class SpellbookLoader(object):
    """Loads all client and/or AI modules in order to get the spellbook
    initialized.
    """

    DC_FILES = ['config/toontown.dc']

    def __init__(self, root):
        self.root = root
        sys.path.append(root)
        os.chdir(self.root)

        # We haven't loaded this yet:
        self.spellbook = None

        from panda3d.direct import DCFile
        self.dcf = DCFile()

    def load_modules(self, client=True, ai=True):
        self.start_headless()
        self.load_dc()
        self.load_spellbook()

        if client:
            self.load_suffix('')
        if ai:
            self.load_suffix('AI')

    def start_headless(self):
        # Start a headless Panda3D base.
        from direct.showbase.ShowBase import ShowBase
        base = ShowBase(windowType='none')
        base.wantKarts = False
        base.wantPets = False

        import __builtin__

        class game:
            name = 'uberDog'
            process = 'server'

        __builtin__.game = game
        __builtin__.simbase = base
        __builtin__.__dev__ = False

        from panda3d.core import loadPrcFileData
        loadPrcFileData('',
                        'model-path resources\ndefault-model-extension .bam')

    def load_dc(self):
        # Load and parse toon.dc and otp.dc...
        from panda3d.core import Filename
        for dc in self.DC_FILES:
            full_path = os.path.join(self.root, dc)
            self.dcf.read(Filename.fromOsSpecific(full_path))

    def load_spellbook(self):
        from otp.ai.MagicWordGlobal import spellbook
        self.spellbook = spellbook

    def load_suffix(self, suffix):
        for m in xrange(self.dcf.getNumImportModules()):
            modparts = self.dcf.getImportModule(m).split('/')
            if not suffix or suffix in modparts[1:]:
                mod = modparts[0] + suffix
            else:
                mod = modparts[0]
            __import__(mod)
            for s in xrange(self.dcf.getNumImportSymbols(m)):
                symparts = self.dcf.getImportSymbol(m, s).split('/')
                syms = [symparts[0]]
                if not suffix or suffix in symparts[1:]:
                    sym = symparts[0] + suffix
                else:
                    continue
                try:
                    __import__('%s.%s' % (mod, sym))
                except ImportError:
                    pass
class ClientBuilder(object):
    MAINMODULE = 'toontown.toonbase.MiraiStart'

    def __init__(self, directory, version=None, language='english'):
        self.directory = directory
        self.version = version or determineVersion(self.directory)
        self.language = language.lower()

        self.dcfiles = [os.path.join(directory, 'config/otp.dc'),
                        os.path.join(directory, 'config/toon.dc')]
        self.modules = {}
        self.path_overrides = {}

        self.config_file = os.path.join(self.directory, 'config/public_client.prc')

        self.mf = ModuleFinder(sys.path+[self.directory])
        from panda3d.direct import DCFile
        self.dcf = DCFile()

    def should_exclude(self, modname):
        # The NonRepeatableRandomSource modules are imported by the dc file explicitly,
        # so we have to allow them.
        if 'NonRepeatableRandomSource' in modname:
            return False

        if modname.endswith('AI'):
            return True
        if modname.endswith('UD'):
            return True
        if modname.endswith('.ServiceStart'):
            return True

    def find_excludes(self):
        for path, dirs, files in os.walk(self.directory):
            for filename in files:
                filepath = os.path.join(path, filename)
                filepath = os.path.relpath(filepath, self.directory)
                if not filepath.endswith('.py'): continue
                filepath = filepath[:-3]
                modname = filepath.replace(os.path.sep, '.')
                if modname.endswith('.__init__'): modname = modname[:-9]
                if self.should_exclude(modname):
                    self.mf.excludes.append(modname)

    def find_dcfiles(self):
        for path, dirs, files in os.walk(self.directory):
            for filename in files:
                filepath = os.path.join(path, filename)
                if filename.endswith('.dc'):
                    self.dcfiles.append(filepath)

    def create_miraidata(self):
        # Create a temporary _miraidata.py and throw it on the path somewhere...

        # First, we need the minified DC file contents:
        from panda3d.core import StringStream
        dcStream = StringStream()
        self.dcf.write(dcStream, True)
        dcData = dcStream.getData()

        # Next we need config files...
        configData = []
        with open(self.config_file) as f:
            fd = f.read()
            fd = fd.replace('SERVER_VERSION_HERE', self.version)
            fd = fd.replace('LANGUAGE_HERE', self.language)
            configData.append(fd)

        md = 'CONFIG = %r\nDC = %r\n' % (configData, dcData)

        # Now we use tempfile to dump md:
        td = tempfile.mkdtemp()
        with open(os.path.join(td, '_miraidata.py'), 'w') as f:
            f.write(md)

        self.mf.path.append(td)

        atexit.register(shutil.rmtree, td)

    def include_dcimports(self):
        for m in xrange(self.dcf.getNumImportModules()):
            modparts = self.dcf.getImportModule(m).split('/')
            mods = [modparts[0]]
            if 'OV' in modparts[1:]:
                mods.append(modparts[0]+'OV')
            for mod in mods:
                self.mf.import_hook(mod)
                for s in xrange(self.dcf.getNumImportSymbols(m)):
                    symparts = self.dcf.getImportSymbol(m,s).split('/')
                    syms = [symparts[0]]
                    if 'OV' in symparts[1:]:
                        syms.append(symparts[0]+'OV')
                    for sym in syms:
                        try:
                            self.mf.import_hook('%s.%s' % (mod,sym))
                        except ImportError:
                            pass

    def build_modules(self):
        for modname, mod in self.mf.modules.items():
            if modname in self.path_overrides:
                modfile = self.path_overrides[modname]
            else:
                modfile = mod.__file__
            if not (modfile and modfile.endswith('.py')): continue
            is_package = modfile.endswith('__init__.py')
            with open(modfile, 'r') as f:
                code = compile(f.read(), modname, 'exec')
            self.modules[modname] = (is_package, code)

    def load_modules(self):
        #self.find_dcfiles()
        self.find_excludes()

        from panda3d.core import Filename
        for dc in self.dcfiles:
            self.dcf.read(Filename.fromOsSpecific(dc))

        self.create_miraidata()

        self.mf.import_hook(self.MAINMODULE)
        for module in EXTRA_MODULES:
            self.mf.import_hook(module)
        if self.language.lower() != "english":
            self.mf.import_hook('otp.otpbase.OTPLocalizer_%s' % self.language.capitalize())
            self.mf.import_hook('otp.otpbase.OTPLocalizer_%sProperty' % self.language.capitalize())
            self.mf.import_hook('toontown.toonbase.TTLocalizer_%s' % self.language.capitalize())
            self.mf.import_hook('toontown.toonbase.TTLocalizer_%s' % self.language.capitalize())
        self.modules['__main__'] = (False, compile('import %s' % self.MAINMODULE,
                                                   '__main__', 'exec'))

        self.include_dcimports()

        self.build_modules()


    def write_zip(self, outfile):
        zip = zipfile.ZipFile(outfile, 'w')
        for modname, (is_package, code) in self.modules.items():
            mcode = imp.get_magic() + '\x00'*4 + marshal.dumps(code)
            name = modname.replace('.','/')
            if is_package:
                name += '/__init__'
            name += '.pyo'
            zip.writestr(name, mcode)
        zip.close()

    def write_list(self, outfile):
        with open(outfile,'w') as out:
            for modname in sorted(self.modules.keys()):
                is_package, code = self.modules[modname]
                out.write('%s%s\n' % (modname, ' [PKG]' if is_package else ''))
Esempio n. 3
0
class ClientBuilder(object):
    MAINMODULE = 'toontown.toonbase.MiraiStart'

    def __init__(self, directory, version=None, language='english'):
        self.directory = directory
        self.version = version or determineVersion(self.directory)
        self.language = language.lower()

        self.dcfiles = [
            os.path.join(directory, 'config/otp.dc'),
            os.path.join(directory, 'config/toon.dc')
        ]
        self.modules = {}
        self.path_overrides = {}

        self.config_file = os.path.join(self.directory,
                                        'config/public_client.prc')

        self.mf = ModuleFinder(sys.path + [self.directory])
        from panda3d.direct import DCFile
        self.dcf = DCFile()

    def should_exclude(self, modname):
        # The NonRepeatableRandomSource modules are imported by the dc file explicitly,
        # so we have to allow them.
        if 'NonRepeatableRandomSource' in modname:
            return False

        if modname.endswith('AI'):
            return True
        if modname.endswith('UD'):
            return True
        if modname.endswith('.ServiceStart'):
            return True

    def find_excludes(self):
        for path, dirs, files in os.walk(self.directory):
            for filename in files:
                filepath = os.path.join(path, filename)
                filepath = os.path.relpath(filepath, self.directory)
                if not filepath.endswith('.py'): continue
                filepath = filepath[:-3]
                modname = filepath.replace(os.path.sep, '.')
                if modname.endswith('.__init__'): modname = modname[:-9]
                if self.should_exclude(modname):
                    self.mf.excludes.append(modname)

    def find_dcfiles(self):
        for path, dirs, files in os.walk(self.directory):
            for filename in files:
                filepath = os.path.join(path, filename)
                if filename.endswith('.dc'):
                    self.dcfiles.append(filepath)

    def create_miraidata(self):
        # Create a temporary _miraidata.py and throw it on the path somewhere...

        # First, we need the minified DC file contents:
        from panda3d.core import StringStream
        dcStream = StringStream()
        self.dcf.write(dcStream, True)
        dcData = dcStream.getData()

        # Next we need config files...
        configData = []
        with open(self.config_file) as f:
            fd = f.read()
            fd = fd.replace('SERVER_VERSION_HERE', self.version)
            fd = fd.replace('LANGUAGE_HERE', self.language)
            configData.append(fd)

        md = 'CONFIG = %r\nDC = %r\n' % (configData, dcData)

        # Now we use tempfile to dump md:
        td = tempfile.mkdtemp()
        with open(os.path.join(td, '_miraidata.py'), 'w') as f:
            f.write(md)

        self.mf.path.append(td)

        atexit.register(shutil.rmtree, td)

    def include_dcimports(self):
        for m in xrange(self.dcf.getNumImportModules()):
            modparts = self.dcf.getImportModule(m).split('/')
            mods = [modparts[0]]
            if 'OV' in modparts[1:]:
                mods.append(modparts[0] + 'OV')
            for mod in mods:
                self.mf.import_hook(mod)
                for s in xrange(self.dcf.getNumImportSymbols(m)):
                    symparts = self.dcf.getImportSymbol(m, s).split('/')
                    syms = [symparts[0]]
                    if 'OV' in symparts[1:]:
                        syms.append(symparts[0] + 'OV')
                    for sym in syms:
                        try:
                            self.mf.import_hook('%s.%s' % (mod, sym))
                        except ImportError:
                            pass

    def build_modules(self):
        for modname, mod in self.mf.modules.items():
            if modname in self.path_overrides:
                modfile = self.path_overrides[modname]
            else:
                modfile = mod.__file__
            if not (modfile and modfile.endswith('.py')): continue
            is_package = modfile.endswith('__init__.py')
            with open(modfile, 'r') as f:
                code = compile(f.read(), modname, 'exec')
            self.modules[modname] = (is_package, code)

    def load_modules(self):
        #self.find_dcfiles()
        self.find_excludes()

        from panda3d.core import Filename
        for dc in self.dcfiles:
            self.dcf.read(Filename.fromOsSpecific(dc))

        self.create_miraidata()

        self.mf.import_hook(self.MAINMODULE)
        for module in EXTRA_MODULES:
            self.mf.import_hook(module)
        if self.language.lower() != "english":
            self.mf.import_hook('otp.otpbase.OTPLocalizer_%s' %
                                self.language.capitalize())
            self.mf.import_hook('otp.otpbase.OTPLocalizer_%sProperty' %
                                self.language.capitalize())
            self.mf.import_hook('toontown.toonbase.TTLocalizer_%s' %
                                self.language.capitalize())
            self.mf.import_hook('toontown.toonbase.TTLocalizer_%s' %
                                self.language.capitalize())
        self.modules['__main__'] = (False,
                                    compile('import %s' % self.MAINMODULE,
                                            '__main__', 'exec'))

        self.include_dcimports()

        self.build_modules()

    def write_zip(self, outfile):
        zip = zipfile.ZipFile(outfile, 'w')
        for modname, (is_package, code) in self.modules.items():
            mcode = imp.get_magic() + '\x00' * 4 + marshal.dumps(code)
            name = modname.replace('.', '/')
            if is_package:
                name += '/__init__'
            name += '.pyo'
            zip.writestr(name, mcode)
        zip.close()

    def write_list(self, outfile):
        with open(outfile, 'w') as out:
            for modname in sorted(self.modules.keys()):
                is_package, code = self.modules[modname]
                out.write('%s%s\n' % (modname, ' [PKG]' if is_package else ''))