Example #1
0
def setup_data():
    """Setup data."""
    _sp_logger.log_debug('Setting up data...')

    from core import GameConfigObj
    from memory.manager import manager
    from paths import SP_DATA_PATH

    import players
    players.BaseClient = manager.create_type_from_dict(
        'BaseClient',
        GameConfigObj(SP_DATA_PATH / 'client' / 'CBaseClient.ini'))

    import entities
    entities._BaseEntityOutput = manager.create_type_from_dict(
        'BaseEntityOutput',
        GameConfigObj(SP_DATA_PATH / 'entity_output' /
                      'CBaseEntityOutput.ini'))

    from _entities import BaseEntityOutput
    try:
        _fire_output = entities._BaseEntityOutput.fire_output

        BaseEntityOutput.fire_output = _fire_output
    except ValueError:
        from warnings import warn
        warn('Did not find address for BaseEntityOutput.fire_output. '
             'OnEntityOutput listener will not fire.')
        BaseEntityOutput.fire_output = NotImplemented
    except AttributeError:
        from warnings import warn
        warn('BaseEntityOutput.fire_output not found. '
             'OnEntityOutput listener will not fire.')
        BaseEntityOutput.fire_output = NotImplemented
Example #2
0
def create_patchers_from_file(file):
    """Create patchers from a file."""
    raw_data = GameConfigObj(file)

    binary = raw_data.pop(Key.BINARY, None)
    if binary is not None:
        binary = Key.as_str(manager, binary)

    srv_check = Key.as_bool(manager, raw_data.pop(Key.SRV_CHECK, "True"))

    # Parse patcher data
    patcher_data = parse_data(manager, raw_data, (
        (Key.BINARY, Key.as_str, binary if binary is not None else NO_DEFAULT),
        (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT),
        (Key.OFFSET, Key.as_int, 0),
        (Key.LEVEL, Key.as_int, 0),
        (Key.SRV_CHECK, Key.as_bool, srv_check),
        (Key.SIZE, Key.as_int, NO_DEFAULT),
        ("op_codes", Key.as_identifier, None),
    ))

    # Create the patchers
    return Patchers({
        name: Patcher(get_pointer(*data[:5]), *data[5:])
        for name, data in patcher_data
    })
Example #3
0
def setup_data():
    """Setup data."""
    _sp_logger.log_debug('Setting up data...')

    from core import GameConfigObj
    from memory.manager import manager
    from paths import SP_DATA_PATH

    import players
    players.BaseClient = manager.create_type_from_dict(
        'BaseClient',
        GameConfigObj(SP_DATA_PATH / 'client' / 'CBaseClient.ini'))

    import listeners
    listeners.BaseEntityOutput = manager.create_type_from_dict(
        'BaseEntityOutput',
        GameConfigObj(SP_DATA_PATH / 'entity_output' /
                      'CBaseEntityOutput.ini'))

    try:
        _fire_output = listeners.BaseEntityOutput.fire_output
    except AttributeError:
        from warnings import warn
        warn('BaseEntityOutput.fire_output not found. '
             'OnEntityOutput listener will not fire.')
    else:
        _fire_output.add_pre_hook(listeners._pre_fire_output)
Example #4
0
def setup_data():
    """Setup data."""
    _sp_logger.log_debug('Setting up data...')

    from core import GameConfigObj
    from memory.manager import manager
    from paths import SP_DATA_PATH

    import players
    players.BaseClient = manager.create_type_from_dict(
        'BaseClient',
        GameConfigObj(SP_DATA_PATH / 'client' / 'CBaseClient.ini'))

    from core.cache import CachedProperty
    from memory import get_function_info
    from memory.helpers import MemberFunction
    CachedProperty(
        lambda self, info: MemberFunction(
            manager,
            info.return_type,
            self.make_virtual_function(info),
            self
        ),
        doc="""Fires the given game event to this client.

        :param GameEvent game_event:
            The game event instance to fire.
        """,
        args=(get_function_info('IGameEventListener2', 'FireGameEvent'),)
    ).bind(players.BaseClient, 'fire_game_event')

    import entities
    entities._BaseEntityOutput = manager.create_type_from_dict(
        'BaseEntityOutput',
        GameConfigObj(SP_DATA_PATH / 'entity_output' / 'CBaseEntityOutput.ini'))

    from _entities import BaseEntityOutput
    try:
        _fire_output = entities._BaseEntityOutput.fire_output

        BaseEntityOutput.fire_output = _fire_output
    except ValueError:
        from warnings import warn
        warn(
            'Did not find address for BaseEntityOutput.fire_output. '
            'OnEntityOutput listener will not fire.'
        )
        BaseEntityOutput.fire_output = NotImplemented
    except AttributeError:
        from warnings import warn
        warn(
            'BaseEntityOutput.fire_output not found. '
            'OnEntityOutput listener will not fire.'
        )
        BaseEntityOutput.fire_output = NotImplemented
Example #5
0
    def _create_server_file(self):
        """Create a server specific langstrings file."""
        # Get the server specific file's ConfigObj instance
        server_file = GameConfigObj(self._serverfile)

        # Set the initial comments to explain what the file is for
        server_file.initial_comment = _translation_strings[
            'Initial Comment'].get_string(
            language_manager.default,
            filename=self._mainfile.replace(GAME_PATH, '')).splitlines()

        # Write the server specific file
        server_file.write()
Example #6
0
    def _create_server_file(self):
        """Create a server specific langstrings file."""
        # Get the server specific file's ConfigObj instance
        server_file = GameConfigObj(self._serverfile)

        # Set the initial comments to explain what the file is for
        server_file.initial_comment = _translation_strings[
            'Initial Comment'].get_string(language_manager.default,
                                          filename=self._mainfile.replace(
                                              GAME_PATH, '')).splitlines()

        # Write the server specific file
        server_file.write()
Example #7
0
    def __init__(self, temp_entity):
        """Initialize the instance.

        :param BaseTempEntity temp_entity:
            The base entity instance to copy the base from.
        """
        # Store the size of the temp entity...
        self._size = get_size(BaseTempEntity)

        # Get the aliases...
        self._aliases = GameConfigObj(SP_DATA_PATH / 'effects' /
                                      temp_entity.server_class.name + '.ini')

        # Get a dictionary to store the properties...
        self._properties = dict()

        # Add the properties to the dictionary...
        self._add_properties(temp_entity.server_class.table)

        # Loop through all properties...
        for prop in temp_entity.server_class.table:

            # Is the current prop a base class?
            if prop.name != 'baseclass':

                # Pass to the next property...
                continue

            # Add the current table to the properties...
            self._add_properties(prop.data_table)

        # Initialize the base class...
        super()._copy_base(temp_entity, self.size)
Example #8
0
    def create_function_typedefs_from_file(self, f):
        """Create function typedefs from a file."""
        # Read the data
        raw_data = GameConfigObj(f)

        # Prepare typedefs
        typedefs = parse_data(
            self, raw_data,
            ((Key.ARGS, Key.as_args_tuple,
              ()), (Key.RETURN_TYPE, Key.as_return_type, DataType.VOID),
             (Key.CONVENTION, Key.as_convention, Convention.CDECL),
             (Key.DOC, Key.as_str, None)))

        # Create the typedefs
        for name, data in typedefs:
            self.function_typedef(name, *data)
Example #9
0
def setup_global_pointers():
    """Set up global pointers."""
    _sp_logger.log_debug('Setting up global pointers...')

    from core import GameConfigObj
    from memory.manager import manager
    from paths import SP_DATA_PATH

    manager.create_global_pointers_from_file(
        GameConfigObj(SP_DATA_PATH / 'memory' / 'global_pointers.ini'))

    _sp_logger.log_debug('Setting up global "server" variables...')
    from engines import server
    try:
        server.server = server.engine_server.server
    except NotImplementedError:
        server.server = manager.get_global_pointer('Server')
Example #10
0
    def create_global_pointers_from_file(self, f):
        """Create global pointers from a file."""
        # Parse pointer data
        pointers = parse_data(self, GameConfigObj(f), (
            (Key.BINARY, Key.as_str, NO_DEFAULT),
            (Key.IDENTIFIER, Key.as_identifier, NO_DEFAULT),
            (Key.OFFSET, Key.as_int, 0),
            (Key.LEVEL, Key.as_int, 0),
            (Key.SRV_CHECK, Key.as_bool, True),
        ))

        # Create the global pointer objects
        for name, data in pointers:
            cls = self.get_class(name)
            if cls is None:
                raise NameError('Unknown class "{0}".'.format(name))

            self.global_pointer(cls, *data)
Example #11
0
def update_data():
    for class_name, paths in list(data_paths.items()):
        server_class = server_classes.get(class_name, None)
        if server_class is None:
            continue

        for path in paths:
            raw_data = GameConfigObj(path)
            set_server_class(raw_data, server_class, class_name)
            for name, value in get_type_from_file(raw_data,
                                                  server_classes).items():
                setattr(server_class, name, value)

        del data_paths[class_name]

    if (not data_paths
            and on_entity_created in on_entity_created_listener_manager):
        on_entity_created_listener_manager.unregister_listener(
            on_entity_created)
Example #12
0
def setup_global_pointers():
    """Set up global pointers."""
    _sp_logger.log_debug('Setting up global pointers...')

    import sys
    from warnings import warn
    from core import GameConfigObj
    from memory.manager import manager
    from paths import SP_DATA_PATH

    manager.create_global_pointers_from_file(GameConfigObj(
        SP_DATA_PATH / 'memory' / 'global_pointers.ini'))

    _sp_logger.log_debug('Setting up global "server" variables...')
    from engines import server
    try:
        server.server = server.engine_server.server
    except NotImplementedError:
        try:
            server.server = manager.get_global_pointer('Server')
        except NameError:
            warn(str(sys.exc_info()[1]))

    _sp_logger.log_debug('Setting up global "factory_dictionary" variables...')
    from entities import factories
    try:
        from _entities._factories import factory_dictionary
    except ImportError:
        try:
            factory_dictionary = manager.get_global_pointer(
                'EntityFactoryDictionary'
            )
        except NameError:
            warn(str(sys.exc_info()[1]))
            return

    factories.factory_dictionary = factory_dictionary
Example #13
0
    def __init__(self, infile, encoding='utf_8'):
        """Add all strings and fix double escaped strings."""
        # Initialize the dictionary
        super().__init__()

        # Get the path to the given file
        self._mainfile = TRANSLATION_PATH / infile + '.ini'

        # Does the file exist?
        if not self._mainfile.isfile():

            # Raise an error
            raise FileNotFoundError('No file found at {0}'.format(
                self._mainfile))

        # Get the path to the server specific file
        self._serverfile = self._mainfile.parent / '{0}_server.ini'.format(
            self._mainfile.namebase)

        # Get the strings from the main file
        main_strings = GameConfigObj(self._mainfile, encoding=encoding)

        # Does the server specific file exist?
        if not self._serverfile.isfile() and not infile.startswith('_core/'):

            # Create the server specific file
            self._create_server_file()

        # Otherwise
        else:

            # Get any strings from the server specific file
            server_strings = GameConfigObj(self._serverfile, encoding=encoding)

            # Merge the two ConfigObj instances together
            main_strings.merge(server_strings)

        # Loop through all strings
        for key in main_strings:

            # Is the current string not a Section?
            if not isinstance(main_strings[key], Section):

                # No need to go further
                continue

            # Get a TranslationStrings instance for the current string
            translation_strings = TranslationStrings()

            # Loop through all languages for the current string
            for lang in main_strings[key]:

                # Get the shortname of the current language
                language = language_manager.get_language(lang)

                # Was the language found?
                if language is None:

                    # Do not add this translation
                    # Possibly raise an error silently here
                    continue

                # Get the language's string and fix any escaped strings
                translation_strings[
                    language] = self._replace_escaped_sequences(
                        main_strings[key][lang])

            # Add the TranslationStrings instance for the current string
            self[key] = translation_strings

        # Is there any default language specified into the main file?
        if 'DEFAULT_LANGUAGE' in main_strings:

            # Get the default language
            default_language = main_strings['DEFAULT_LANGUAGE']

            # Make sure it is not a Section
            if not isinstance(default_language, Section):

                # Get the given language code
                language_code = language_manager.get_language(default_language)

                # Is the language valid?
                if language_code is not None:

                    # Set the default language
                    self.default_language = language_code

                # Delete the key from the main file as we are done with it
                del main_strings['DEFAULT_LANGUAGE']
Example #14
0
from memory.hooks import PreHook
from memory.manager import manager
#   Entity
from entities.entity import BaseEntity
from entities.entity import Entity
from entities.datamaps import Variant
from entities.helpers import find_output_name
#   Listeners
from _listeners import ListenerManager

# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
BaseEntityOutput = manager.create_type_from_dict(
    'BaseEntityOutput',
    GameConfigObj(SP_DATA_PATH / 'entity_output' / 'CBaseEntityOutput.ini'))

on_entity_output_listener_manager = ListenerManager()


# =============================================================================
# >> CALLBACKS
# =============================================================================
@PreHook(BaseEntityOutput.fire_output)
def _pre_fire_output(args):
    """Called when an output is about to be fired."""
    if not on_entity_output_listener_manager:
        return

    # Windows is a bit weird: the function takes 4 additional arguments...
    if PLATFORM == 'windows':
Example #15
0
def get_data_from_file(file):
    return get_data_from_dict(GameConfigObj(file))
Example #16
0
 def create_type_from_file(self, type_name, f, bases=(CustomType, )):
     """Create and registers a new type from a file or URL."""
     return self.create_type_from_dict(type_name, GameConfigObj(f), bases)
Example #17
0
 def create_pipe_from_file(self, f):
     """Create a pipe from a file or URL."""
     return self.create_pipe_from_dict(GameConfigObj(f))
Example #18
0
from memory.manager import manager


# =============================================================================
# >> ALL DECLARATION
# =============================================================================
__all__ = ('WeaponInfo',
           'weapon_scripts',
           )


# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
# Get the WeaponInfo class...
WeaponInfo = manager.create_type_from_dict('WeaponInfo', GameConfigObj(
    SP_DATA_PATH / 'weapons' / 'scripts' / 'WeaponInfo.ini'))

# Get the _WeaponDatabase class...
try:
    from _weapons._scripts import _WeaponDatabase

    # Make sure the manager is able to find us...
    manager['_WeaponDatabase'] = _WeaponDatabase
except ImportError:
    _WeaponDatabase = manager.create_type_from_dict(
        '_WeaponDatabase', GameConfigObj(
            SP_DATA_PATH / 'weapons' / 'scripts' / 'WeaponDatabase.ini'))

# Get the global _WeaponDatabase pointer...
manager.create_global_pointers_from_file(GameConfigObj(
    SP_DATA_PATH / 'weapons' / 'scripts' / 'global_pointers.ini'))
Example #19
0
def get_type_from_file(file, manager=manager):
    return get_type_from_dict(GameConfigObj(file), manager)
Example #20
0
    def _get_server_class(self, class_name, datamap):
        """Retrieve values for the server class."""
        # Get the engine specific data for the current class
        manager_contents = GameConfigObj(
            _managers_path.joinpath(class_name + '.ini'))

        # Are there any values for the manager?
        if manager_contents:

            # Add the binary path to the manager dictionary
            manager_contents['binary'] = 'server'

        # Get a TypeManager instance for the current datamap
        instance = self.create_type_from_file(class_name, manager_contents)

        # Store the class name to more easily look it up
        instance.__name__ = class_name

        # Get the specific types of values to use
        input_contents = dict(map(
            reversed, manager_contents.get('input', {}).items()))
        keyvalue_contents = dict(map(
            reversed, manager_contents.get('keyvalue', {}).items()))
        property_contents = dict(map(
            reversed, manager_contents.get('property', {}).items()))

        # Create dictionaries to store all values for the instance
        instance.inputs = dict()
        instance.functiontables = dict()
        instance.keyvalues = dict()
        instance.outputs = dict()
        instance.properties = dict()

        # Loop through all possible properties for the server class
        for name, prop, offset in self._find_properties(
                _server_classes.get(class_name, {})):

            # Add the property to the instance
            self._add_property(
                instance, name, prop, offset, property_contents,
                _supported_property_types, True)

        # Loop through all possible descriptors for the server class
        for name, desc, offset in self._find_descriptors(datamap):

            # Is the current descriptor an Output?
            if desc.flags & TypeDescriptionFlags.OUTPUT:

                # Store the descriptor in the outputs dictionary
                instance.outputs[name] = desc

            # Is the current descriptor a FunctionTable?
            elif desc.flags & TypeDescriptionFlags.FUNCTIONTABLE:

                # Store the descriptor in the functiontables dictionary
                instance.functiontables[name] = desc

            # Is the current descriptor a KeyValue?
            elif desc.flags & TypeDescriptionFlags.KEY:

                # Add the key value to the instance
                self._add_keyvalue(instance, name, desc, keyvalue_contents)

            # Is the current descriptor an Input?
            elif desc.flags & TypeDescriptionFlags.INPUT:

                # Add the input to the instance
                self._add_input(instance, name, desc, input_contents)

            # Is the current descriptor of a supported type?
            elif desc.type in _supported_descriptor_types:

                # Add the descriptor to the instance
                self._add_property(
                    instance, name, desc, offset,
                    property_contents, _supported_descriptor_types)

        # Get a list of all properties for the current server class
        properties = list(instance.properties)

        # Store all of the properties as
        # attributes of an instance of the class
        instance._properties = self(class_name + 'Properties', (
            CustomType, ), dict(zip(properties, [
                instance.properties[x].instance for x in properties])))

        # Store all of the inputs as attributes
        # of an instance of the class
        instance._inputs = self(
            class_name + 'Inputs', (CustomType, ), dict(instance.inputs))

        # Return the ServerClass
        return instance
Example #21
0
def get_ctype_from_file(file, auto_dealloc=True):
    return get_ctype_from_dict(get_function_from_dict(GameConfigObj(file)),
                               auto_dealloc=True)
Example #22
0
    def _get_server_class(self, class_name, datamap):
        """Retrieve values for the server class."""
        # Get the engine specific data for the current class
        manager_contents = GameConfigObj(_managers_path / class_name + '.ini')

        # Are there any values for the manager?
        if manager_contents:

            # Add the binary path to the manager dictionary
            manager_contents['binary'] = 'server'

        # Get a TypeManager instance for the current datamap
        instance = self.create_type_from_file(class_name, manager_contents)

        # Get the specific types of values to use
        input_contents = dict(map(
            reversed, manager_contents.get('input', {}).items()))
        property_contents = {}
        for item, value in manager_contents.get('property', {}).items():
            if isinstance(value, Section):
                property_contents[value['name']] = (item, value['type'])
            else:
                property_contents[value] = item
        keyvalue_contents = {}
        hardcoded_keyvalues = {}
        for item, value in manager_contents.get('keyvalue', {}).items():
            if isinstance(value, Section):
                hardcoded_keyvalues[item] = value
                hardcoded_keyvalues[item].update({'alias': item})
            else:
                keyvalue_contents[value] = item

        # Create dictionaries to store all values for the instance
        instance.inputs = dict()
        instance.functiontables = dict()
        instance.keyvalues = dict()
        instance.outputs = dict()
        instance.properties = dict()

        # Loop through all possible properties for the server class
        for name, prop, offset in self._find_properties(
                _server_classes.get(class_name, {})):

            if prop.type not in _supported_property_types:
                continue

            prop_type = _supported_property_types[prop.type]

            if prop.type == SendPropType.INT:
                bit_count = prop.bits
                if bit_count < 1:
                    # Note: I have yet to encounter this, so I'm not
                    #   sure under what circumstances this can occur.
                    # That is why this simply continues.
                    continue
                if bit_count >= 17:
                    prop_type = 'int'
                elif bit_count >= 9:
                    prop_type = '{0}short'.format(
                        '' if prop.is_signed() else 'u')
                elif bit_count >= 2:
                    prop_type = '{0}char'.format(
                        '' if prop.is_signed() else 'u')
                else:
                    prop_type = 'bool'

            # Add the property to the instance
            self._add_property(
                instance, name, offset, property_contents, prop_type, True)

        # Loop through all possible descriptors for the server class
        for name, desc, offset in self._find_descriptors(datamap):

            # Is the current descriptor an Output?
            if desc.flags & TypeDescriptionFlags.OUTPUT:

                # Store the descriptor in the outputs dictionary
                instance.outputs[name] = desc

            # Is the current descriptor a FunctionTable?
            elif desc.flags & TypeDescriptionFlags.FUNCTIONTABLE:

                # Store the descriptor in the functiontables dictionary
                instance.functiontables[name] = desc

            # Is the current descriptor a KeyValue?
            elif desc.flags & TypeDescriptionFlags.KEY:

                # Add the key value to the instance
                self._add_keyvalue(instance, name, desc, keyvalue_contents)

                # Is the key value also a valid property?
                if desc.name and desc.type in _supported_descriptor_types:

                    # Add the descriptor to the instance
                    self._add_property(
                        instance, desc.name, offset, property_contents,
                        _supported_descriptor_types[desc.type])

            # Is the current descriptor an Input?
            elif desc.flags & TypeDescriptionFlags.INPUT:

                # Add the input to the instance
                self._add_input(instance, name, desc, input_contents)

            # Is the current descriptor of a supported type?
            elif desc.type in _supported_descriptor_types:

                # Add the descriptor to the instance
                self._add_property(
                    instance, name, offset, property_contents,
                    _supported_descriptor_types[desc.type])

        # Get a list of all properties for the current server class
        properties = list(instance.properties)

        # Store all of the properties as
        # attributes of an instance of the class
        instance._properties = self(class_name + 'Properties', (
            CustomType, ), dict(zip(properties, [
                instance.properties[x].instance for x in properties])))

        # Store all of the inputs as attributes
        # of an instance of the class
        instance._inputs = self(
            class_name + 'Inputs', (CustomType, ), dict(instance.inputs))

        # Loop through all hard coded keyvalues
        for item, value in hardcoded_keyvalues.items():

            # Get the keyvalue's name and type
            name = value['name']
            keyvalue_type = getattr(FieldType, value['type'])

            # Is the keyvalue already added to the instance?
            if name in instance.keyvalues:
                warn('KeyValue "{0}" already implemented.'.format(name))
                continue

            # Is the type unsupported?
            if keyvalue_type not in _supported_keyvalue_types:
                warn('Unsupported KeyValue type "{0}".'.format(keyvalue_type))
                continue

            # Add the keyvalue to the instance
            instance.keyvalues[name] = value
            setattr(instance, value['alias'], self.keyvalue(
                name, _supported_keyvalue_types[keyvalue_type]))

        # Return the ServerClass
        return instance
Example #23
0
from core import GameConfigObj
#   Memory
from memory.manager import manager
#   Paths
from paths import SP_DATA_PATH
#   Players
from _players import Client
from _players import PlayerGenerator
from _players import PlayerInfo
from _players import UserCmd

# =============================================================================
# >> ALL DECLARATION
# =============================================================================
__all__ = (
    'BaseClient',
    'Client',
    'PlayerGenerator',
    'PlayerInfo',
    'UserCmd',
)

# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
# Get the sp.players logger
players_logger = _sp_logger.players

BaseClient = manager.create_type_from_dict(
    'BaseClient', GameConfigObj(SP_DATA_PATH / 'client' / 'CBaseClient.ini'))
Example #24
0
    def _get_server_class(self, class_name, datamap):
        """Retrieve values for the server class."""
        # Get the engine specific data for the current class
        manager_contents = GameConfigObj(_managers_path / class_name + '.ini')

        # Are there any values for the manager?
        if manager_contents:

            # Add the binary path to the manager dictionary
            manager_contents['binary'] = 'server'

        # Get a TypeManager instance for the current datamap
        instance = self.create_type_from_dict(class_name, manager_contents)

        # Get the specific types of values to use
        input_contents = dict(
            map(reversed,
                manager_contents.get('input', {}).items()))
        property_contents = {}
        for item, value in manager_contents.get('property', {}).items():
            if isinstance(value, Section):
                property_contents[value['name']] = (item, value['type'])
            else:
                property_contents[value] = item
        keyvalue_contents = {}
        hardcoded_keyvalues = {}
        for item, value in manager_contents.get('keyvalue', {}).items():
            if isinstance(value, Section):
                hardcoded_keyvalues[item] = value
                hardcoded_keyvalues[item].update({'alias': item})
            else:
                keyvalue_contents[value] = item

        # Create dictionaries to store all values for the instance
        instance.inputs = dict()
        instance.functiontables = dict()
        instance.keyvalues = dict()
        instance.outputs = dict()
        instance.properties = dict()

        # Loop through all possible properties for the server class
        for name, prop, offset in self._find_properties(
                _server_classes.get(class_name, {})):

            if prop.type not in _supported_property_types:
                continue

            prop_type = _supported_property_types[prop.type]

            if prop.type == SendPropType.INT:
                bit_count = prop.bits
                if bit_count < 1:
                    # Note: I have yet to encounter this, so I'm not
                    #   sure under what circumstances this can occur.
                    # That is why this simply continues.
                    continue
                if bit_count >= 17:
                    prop_type = 'int'
                elif bit_count >= 9:
                    prop_type = '{0}short'.format(
                        '' if prop.is_signed() else 'u')
                elif bit_count >= 2:
                    prop_type = '{0}char'.format(
                        '' if prop.is_signed() else 'u')
                else:
                    prop_type = 'bool'

            # Add the property to the instance
            self._add_property(instance, name, offset, property_contents,
                               prop_type, True)

        # Loop through all possible descriptors for the server class
        for name, desc, offset in self._find_descriptors(datamap):

            # Is the current descriptor an Output?
            if desc.flags & TypeDescriptionFlags.OUTPUT:

                # Store the descriptor in the outputs dictionary
                instance.outputs[name] = desc

            # Is the current descriptor a FunctionTable?
            elif desc.flags & TypeDescriptionFlags.FUNCTIONTABLE:

                # Store the descriptor in the functiontables dictionary
                instance.functiontables[name] = desc

            # Is the current descriptor a KeyValue?
            elif desc.flags & TypeDescriptionFlags.KEY:

                # Add the key value to the instance
                self._add_keyvalue(instance, name, desc, keyvalue_contents)

                # Is the key value also a valid property?
                if desc.name and desc.type in _supported_descriptor_types:

                    # Add the descriptor to the instance
                    self._add_property(instance, desc.name, offset,
                                       property_contents,
                                       _supported_descriptor_types[desc.type])

            # Is the current descriptor an Input?
            elif desc.flags & TypeDescriptionFlags.INPUT:

                # Add the input to the instance
                self._add_input(instance, name, desc, input_contents)

            # Is the current descriptor of a supported type?
            elif desc.type in _supported_descriptor_types:

                # Add the descriptor to the instance
                self._add_property(instance, name, offset, property_contents,
                                   _supported_descriptor_types[desc.type])

        # Loop through all based attributes
        for name, data in manager_contents.get('based_attribute', {}).items():

            # Resolve the method to register this attribute
            method = getattr(self, data.get('method', 'instance_attribute'))

            # Resolve the offset of this attribute
            offset = Key.as_int(
                self, data.get('offset_' + PLATFORM, data.get('offset', 0)))

            # Resolve the base offset of this attribute
            base = data.get('base_' + PLATFORM, data.get('base'))
            try:
                offset += instance.properties[base].offset
            except KeyError:
                raise NameError(f'"{base}" is not a valid property ' +
                                f'for attribute "{class_name}.{name}".')

            # Generate the attribute
            attribute = method(Key.as_attribute_type(self, data['type']),
                               offset, data.get('doc'))

            # Assign the attribute to the instance
            setattr(instance, name, attribute)

        # Get a list of all properties for the current server class
        properties = list(instance.properties)

        # Store all of the properties as
        # attributes of an instance of the class
        instance._properties = self(
            class_name + 'Properties', (CustomType, ),
            dict(
                zip(properties,
                    [instance.properties[x].instance for x in properties])))

        # Store all of the inputs as attributes
        # of an instance of the class
        instance._inputs = self(class_name + 'Inputs', (CustomType, ),
                                dict(instance.inputs))

        # Loop through all hard coded keyvalues
        for item, value in hardcoded_keyvalues.items():

            # Get the keyvalue's name and type
            name = value['name']
            keyvalue_type = getattr(FieldType, value['type'])

            # Is the keyvalue already added to the instance?
            if name in instance.keyvalues:
                warn('KeyValue "{0}" already implemented.'.format(name))
                continue

            # Is the type unsupported?
            if keyvalue_type not in _supported_keyvalue_types:
                warn('Unsupported KeyValue type "{0}".'.format(keyvalue_type))
                continue

            # Add the keyvalue to the instance
            instance.keyvalues[name] = value
            setattr(
                instance, value['alias'],
                self.keyvalue(name, _supported_keyvalue_types[keyvalue_type]))

        # Return the ServerClass
        return instance
Example #25
0
def get_function_from_file(file, manager=manager):
    return get_function_from_dict(GameConfigObj(file), manager)
Example #26
0
    def __init__(self, infile, encoding='utf_8'):
        """Add all strings and fix double escaped strings."""
        # Initialize the dictionary
        super().__init__()

        # Get the path to the given file
        self._mainfile = TRANSLATION_PATH / infile + '.ini'

        # Does the file exist?
        if not self._mainfile.isfile():

            # Raise an error
            raise FileNotFoundError(
                'No file found at {0}'.format(self._mainfile))

        # Get the path to the server specific file
        self._serverfile = self._mainfile.parent / '{0}_server.ini'.format(
            self._mainfile.namebase)

        # Get the strings from the main file
        main_strings = GameConfigObj(self._mainfile, encoding=encoding)

        # Does the server specific file exist?
        if not self._serverfile.isfile() and not infile.startswith('_core/'):

            # Create the server specific file
            self._create_server_file()

        # Otherwise
        else:

            # Get any strings from the server specific file
            server_strings = GameConfigObj(self._serverfile, encoding=encoding)

            # Merge the two ConfigObj instances together
            main_strings.merge(server_strings)

        # Loop through all strings
        for key in main_strings:

            # Is the current string not a Section?
            if not isinstance(main_strings[key], Section):

                # No need to go further
                continue

            # Get a TranslationStrings instance for the current string
            translation_strings = TranslationStrings()

            # Loop through all languages for the current string
            for lang in main_strings[key]:

                # Get the shortname of the current language
                language = language_manager.get_language(lang)

                # Was the language found?
                if language is None:

                    # Do not add this translation
                    # Possibly raise an error silently here
                    continue

                # Get the language's string and fix any escaped strings
                translation_strings[
                    language] = self._replace_escaped_sequences(
                    main_strings[key][lang])

            # Add the TranslationStrings instance for the current string
            self[key] = translation_strings

        # Is there any default language specified into the main file?
        if 'DEFAULT_LANGUAGE' in main_strings:

            # Get the default language
            default_language = main_strings['DEFAULT_LANGUAGE']

            # Make sure it is not a Section
            if not isinstance(default_language, Section):

                # Get the given language code
                language_code = language_manager.get_language(default_language)

                # Is the language valid?
                if language_code is not None:

                    # Set the default language
                    self.default_language = language_code

                # Delete the key from the main file as we are done with it
                del main_strings['DEFAULT_LANGUAGE']
Example #27
0
    'WeaponProficiency',
    'WeaponSlot',
    'WeaponSound',
    'WeaponState',
    'WeaponType',
)

# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
# Get the base path...
_path = SP_DATA_PATH / 'weapons' / 'constants'

# Get the MuzzleFlashStyle enumerator...
MuzzleFlashStyle = IntEnum('MuzzleFlashStyle',
                           GameConfigObj(_path / 'MuzzleFlashStyle.ini'))

# Get the WeaponID enumerator...
WeaponID = IntEnum('WeaponID', GameConfigObj(_path / 'WeaponID.ini'))

# Get the WeaponType enumerator...
WeaponType = IntEnum('WeaponType', GameConfigObj(_path / 'WeaponType.ini'))

# Get the WeaponSlot enumerator...
WeaponSlot = IntEnum('WeaponSlot', GameConfigObj(_path / 'WeaponSlot.ini'))


# =============================================================================
# >> ENUMERATORS
# =============================================================================
class ItemFlags(IntFlag):