Jump to content

[Python] Avoid closing client on have missing locales


Recommended Posts

Hello,

 

if a key / attribute is missing in the localeinfo in normally crashes and dont let you ingame - I added a "small" workaround for it (it's easy to implement):

Add these class into system.py

 

class LocaleInfoWrapper(object):
    def __init__(self, wrapped):
        self.wrapped = wrapped
    def __getattr__(self, name):
        # Perform custom logic here
        try:
            return getattr(self.wrapped, name)
        except AttributeError:
            dbg.TraceError("Locale attribute not found: {0}".format(name))
            return "Locale not found: {0}".format(name)

Search for that:

# in this if case: 'pack.Exist(filename)'
       return newmodule 

Add this above:

        if filename.lower() == "localeinfo.py":
            sys.modules[name] = LocaleInfoWrapper(newmodule)
            return sys.modules[name]

done, now you can start the game with missing locales and it will print in out to the TraceError

 

NOTE: This is just something I did because one of my clients work with locales and sometimes crashes my client, you need to adjust for e.g. supporting calling etc / formating strings.. blabla

 

For python3 you can define the __getattr__ function inside localeinfo.py which is way easier to implement: 
Check here

best regards

Edited by ZentraX
  • Think 1
  • Good 1
  • Love 3
Link to comment
Share on other sites

  • Honorable Member
Posted (edited)

I don't think there are other alternatives than using a class(object) in python2.

I've edited the code for supporting cython and uiscriptlocale as well:

class LocaleInfoWrapper(object):
	def __init__(self, wrapped):
		self.wrapped = wrapped
	def __getattr__(self, name):
		try:
			return getattr(self.wrapped, name)
		except AttributeError:
			dbg.TraceError("Locale attribute not found: {}".format(name))
			return name

def __hybrid_import(name,globals=None,locals=None,fromlist=None, level=-1):
	if __USE_CYTHON__ and rootlib.isExist(name):
		if name in sys.modules:
			dbg.Tracen('importing from sys.modules %s' % name)
			return sys.modules[name]

		dbg.Tracen('importing from rootlib %s' % name)
		newmodule = rootlib.moduleImport(name)

		module_do(newmodule)
		if name.lower() in ("localeinfo", "uiscriptlocale"):
			newmodule = LocaleInfoWrapper(newmodule)
		sys.modules[name] = newmodule
		return newmodule
	else:
		filename = name + '.py'

		if pack.Exist(filename):
			if name in sys.modules:
				dbg.Tracen('importing from sys.modules %s' % name)
				return sys.modules[name]

			dbg.Tracen('importing from pack %s' % name)

			newmodule = _process_result(compile(pack_file(filename,'r').read(),filename,'exec'),name)

			module_do(newmodule)
			if name.lower() in ("localeinfo", "uiscriptlocale"):
				newmodule = LocaleInfoWrapper(newmodule)
				sys.modules[name] = newmodule
			return newmodule
		else:
			dbg.Tracen('importing from lib %s' % name)
			return old_import(name,globals,locals,fromlist)#, level)

I'm also returning directly 'name' if not found.

Edited by martysama0134
old version up
  • Metin2 Dev 1
  • Love 4
Link to comment
Share on other sites

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.