forked from Pidgeot/python-lnp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hacks.py
122 lines (111 loc) · 3.99 KB
/
hacks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""DFHack management."""
from __future__ import print_function, unicode_literals, absolute_import
import sys, os, shutil, filecmp, collections
# pylint:disable=redefined-builtin
from io import open
from . import paths, log
from .lnp import lnp
def open_dfhack_readme():
"""Open the DFHack Readme in the default browser."""
from . import launcher
index = paths.get('df', 'hack', 'docs', 'index.html')
if os.path.isfile(index):
launcher.open_file(index)
else:
launcher.open_url('https://dfhack.readthedocs.org')
def read_hacks():
"""Reads which hacks are enabled."""
hacklines = []
for init_file in ('dfhack', 'onLoad', 'onMapLoad'):
try:
with open(paths.get('df', init_file + '_PyLNP.init'),
encoding='latin1') as f:
hacklines.extend(l.strip() for l in f.readlines())
except IOError:
log.debug(init_file + '_PyLNP.init not found.')
return {name: hack for name, hack in get_hacks().items()
if hack['command'] in hacklines}
def is_dfhack_enabled():
"""Returns YES if DFHack should be used."""
if sys.platform == 'win32':
if 'dfhack' not in lnp.df_info.variations:
return False
sdl = paths.get('df', 'SDL.dll')
sdlreal = paths.get('df', 'SDLreal.dll')
if not os.path.isfile(sdlreal):
return False
return not filecmp.cmp(sdl, sdlreal, 0)
else:
return lnp.userconfig.get_value('use_dfhack', True)
def toggle_dfhack():
"""Toggles the use of DFHack."""
if sys.platform == 'win32':
if 'dfhack' not in lnp.df_info.variations:
return
sdl = paths.get('df', 'SDL.dll')
sdlhack = paths.get('df', 'SDLhack.dll')
sdlreal = paths.get('df', 'SDLreal.dll')
if is_dfhack_enabled():
shutil.copyfile(sdl, sdlhack)
shutil.copyfile(sdlreal, sdl)
else:
shutil.copyfile(sdl, sdlreal)
shutil.copyfile(sdlhack, sdl)
else:
lnp.userconfig['use_dfhack'] = not lnp.userconfig.get_value(
'use_dfhack', True)
lnp.save_config()
def get_hacks():
"""Returns dict of available hacks."""
return collections.OrderedDict(sorted(
lnp.config.get_dict('dfhack').items(), key=lambda t: t[0]))
def get_hack(title):
"""
Returns the hack titled <title>, or None if this does not exist.
Args:
title: the title of the hack.
"""
try:
return get_hacks()[title]
except KeyError:
log.d('No hack configured with name ' + title)
return None
def toggle_hack(name):
"""
Toggles the hack <name>.
Args:
name: the name of the hack to toggle.
Returns:
True if the hack is now enabled,
False if the hack is now disabled,
None on error (no change in status)
"""
# Setup - get the hack, which file, and validate
hack = get_hack(name)
init_file = hack.get('file', 'dfhack')
if init_file not in ('dfhack', 'onLoad', 'onMapLoad'):
log.e('Illegal file configured for hack %s; must be one of '
'"dfhack", "onLoad", "onMapLoad"', name)
return None
# Get the enabled hacks for this file, and toggle our state
hacks = {name: h for name, h in read_hacks().items()
if h.get('file', 'dfhack') == init_file}
is_enabled = False
if not hacks.pop(name, False):
is_enabled = True
hacks[name] = hack
# Write back to the file
fname = paths.get('df', init_file + '_PyLNP.init')
log.i('Rebuilding {} with the enabled hacks'.format(fname))
lines = ['# {}\n# {}\n{}\n\n'.format(
k, h['tooltip'].replace('\n', '\n#'), h['command'])
for k, h in hacks.items()]
if lines:
with open(fname, 'w', encoding='latin1') as f:
f.write('# Generated by PyLNP\n\n')
f.writelines(lines)
elif os.path.isfile(fname):
os.remove(fname)
return is_enabled