Skip to content

Commit becd685

Browse files
authored
Merge pull request #11 from aanderse/issue-3
added new option to list only games locally installed
2 parents 51d30a9 + 5a8e6e0 commit becd685

File tree

3 files changed

+132
-11
lines changed

3 files changed

+132
-11
lines changed

addon.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<addon id="plugin.program.steam.library" name="Steam Library" version="0.5.0" provider-name="aanderse">
2+
<addon id="plugin.program.steam.library" name="Steam Library" version="0.6.0" provider-name="aanderse">
33
<requires>
44
<import addon="xbmc.python" version="2.19.0" />
55
<import addon="script.module.requests" version="2.18.4" />
@@ -31,6 +31,8 @@
3131
v0.5.0 (2018-09-18)
3232
- fixed issue with v0.4.0 release
3333
- added new option to pass arguments to the steam executable
34+
v0.6.0 (2018-11-16)
35+
- added list for installed games
3436
</news>
3537
<assets>
3638
<icon>icon.png</icon>

resources/main.py

Lines changed: 126 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,43 @@ def log(msg, level=xbmc.LOGDEBUG):
2121

2222
xbmc.log('[%s] %s' % (__addon__.getAddonInfo('id'), msg), level=level)
2323

24+
# https://github.com/lutris/lutris/blob/master/lutris/util/steam.py
25+
def vdf_parse(steam_config_file, config):
26+
"""Parse a Steam config file and return the contents as a dict."""
27+
line = " "
28+
while line:
29+
try:
30+
line = steam_config_file.readline()
31+
except UnicodeDecodeError:
32+
log("Error while reading Steam VDF file {}. Returning {}".format(steam_config_file, config), xbmc.LOGERROR)
33+
return config
34+
if not line or line.strip() == "}":
35+
return config
36+
while not line.strip().endswith("\""):
37+
nextline = steam_config_file.readline()
38+
if not nextline:
39+
break
40+
line = line[:-1] + nextline
41+
42+
line_elements = line.strip().split("\"")
43+
if len(line_elements) == 3:
44+
key = line_elements[1]
45+
steam_config_file.readline() # skip '{'
46+
config[key] = vdf_parse(steam_config_file, {})
47+
else:
48+
try:
49+
config[line_elements[1]] = line_elements[3]
50+
except IndexError:
51+
log('Malformed config file: {}'.format(line), xbmc.LOGERROR)
52+
return config
53+
2454
@plugin.route('/')
2555
def index():
2656

2757
handle = int(sys.argv[1])
2858

2959
xbmcplugin.addDirectoryItem(handle=handle, url=plugin.url_for(all), listitem=xbmcgui.ListItem('All games'), isFolder=True)
60+
xbmcplugin.addDirectoryItem(handle=handle, url=plugin.url_for(installed), listitem=xbmcgui.ListItem('Installed games'), isFolder=True)
3061
xbmcplugin.addDirectoryItem(handle=handle, url=plugin.url_for(recent), listitem=xbmcgui.ListItem('Recently played games'), isFolder=True)
3162
xbmcplugin.endOfDirectory(handle, succeeded=True)
3263

@@ -74,6 +105,65 @@ def all():
74105
xbmcplugin.addSortMethod(handle, xbmcplugin.SORT_METHOD_LABEL)
75106
xbmcplugin.endOfDirectory(handle, succeeded=True)
76107

108+
@plugin.route('/installed')
109+
def installed():
110+
111+
if __addon__.getSetting('steam-id') == '' or __addon__.getSetting('steam-key') == '':
112+
113+
# ensure required data is available
114+
return
115+
116+
if os.path.isdir(__addon__.getSetting('steam-path')) == False:
117+
118+
# ensure required data is available
119+
notify = xbmcgui.Dialog()
120+
notify.notification('Error', 'Unable to find your Steam path, please check your settings.', xbmcgui.NOTIFICATION_ERROR)
121+
122+
return
123+
124+
handle = int(sys.argv[1])
125+
126+
try:
127+
128+
# query the steam web api for a full list of steam applications/games that belong to the user
129+
response = requests.get('https://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=' + __addon__.getSetting('steam-key') + '&steamid=' + __addon__.getSetting('steam-id') + '&include_appinfo=1&format=json', timeout=10)
130+
response.raise_for_status()
131+
132+
except requests.exceptions.RequestException as e:
133+
134+
# something went wrong, can't scan the steam library
135+
notify = xbmcgui.Dialog()
136+
notify.notification('Error', 'An unexpected error has occurred while contacting Steam. Please ensure your Steam credentials are correct and then try again. If this problem persists please contact support.', xbmcgui.NOTIFICATION_ERROR)
137+
138+
log(str(e), xbmc.LOGERROR)
139+
140+
return
141+
142+
with open(os.path.join(__addon__.getSetting('steam-path'), 'registry.vdf'), 'r') as file:
143+
vdf = vdf_parse(file, {})
144+
apps = vdf['Registry']['HKCU']['Software']['Valve']['Steam']['Apps']
145+
apps = dict((k, v) for (k, v) in apps.iteritems() if v.get('installed', '0') == '1')
146+
147+
data = response.json()
148+
149+
for entry in data['response']['games']:
150+
151+
appid = entry['appid']
152+
name = entry['name']
153+
154+
# filter out any applications not listed as installed
155+
if str(appid) not in apps: continue
156+
157+
item = xbmcgui.ListItem(name)
158+
159+
item.addContextMenuItems([('Play', 'RunPlugin(plugin://plugin.program.steam.library/run/' + str(appid) + ')'), ('Install', 'RunPlugin(plugin://plugin.program.steam.library/install/' + str(appid) + ')')])
160+
item.setArt({ 'thumb': 'http://cdn.akamai.steamstatic.com/steam/apps/' + str(appid) + '/header.jpg', 'fanart': 'http://cdn.akamai.steamstatic.com/steam/apps/' + str(appid) + '/page_bg_generated_v6b.jpg' })
161+
162+
if not xbmcplugin.addDirectoryItem(handle=handle, url=plugin.url_for(run, id=str(appid)), listitem=item): break
163+
164+
xbmcplugin.addSortMethod(handle, xbmcplugin.SORT_METHOD_LABEL)
165+
xbmcplugin.endOfDirectory(handle, succeeded=True)
166+
77167
@plugin.route('/recent')
78168
def recent():
79169

@@ -119,23 +209,23 @@ def recent():
119209
@plugin.route('/install/<id>')
120210
def install(id):
121211

122-
if os.path.isfile(__addon__.getSetting('steam-path')) == False:
212+
if os.path.isfile(__addon__.getSetting('steam-exe')) == False:
123213

124214
# ensure required data is available
125215
notify = xbmcgui.Dialog()
126216
notify.notification('Error', 'Unable to find your Steam executable, please check your settings.', xbmcgui.NOTIFICATION_ERROR)
127217

128218
return
129219

130-
log('executing ' + __addon__.getSetting('steam-path') + ' steam://install/' + id)
220+
log('executing ' + __addon__.getSetting('steam-exe') + ' steam://install/' + id)
131221

132222
# https://developer.valvesoftware.com/wiki/Steam_browser_protocol
133-
subprocess.call([__addon__.getSetting('steam-path'), 'steam://install/' + id])
223+
subprocess.call([__addon__.getSetting('steam-exe'), 'steam://install/' + id])
134224

135225
@plugin.route('/run/<id>')
136226
def run(id):
137227

138-
if os.path.isfile(__addon__.getSetting('steam-path')) == False:
228+
if os.path.isfile(__addon__.getSetting('steam-exe')) == False:
139229

140230
# ensure required data is available
141231
notify = xbmcgui.Dialog()
@@ -145,37 +235,64 @@ def run(id):
145235

146236
userArgs = shlex.split(__addon__.getSetting('steam-args'))
147237

148-
log('executing ' + __addon__.getSetting('steam-path') + ' ' + __addon__.getSetting('steam-args') + ' steam://rungameid/' + id)
238+
log('executing ' + __addon__.getSetting('steam-exe') + ' ' + __addon__.getSetting('steam-args') + ' steam://rungameid/' + id)
149239

150240
# https://developer.valvesoftware.com/wiki/Steam_browser_protocol
151-
subprocess.call([__addon__.getSetting('steam-path')] + userArgs + ['steam://rungameid/' + id])
241+
subprocess.call([__addon__.getSetting('steam-exe')] + userArgs + ['steam://rungameid/' + id])
152242

153243
def main():
154244

155245
log('steam-id = ' + __addon__.getSetting('steam-id'))
156246
log('steam-key = ' + __addon__.getSetting('steam-key'))
247+
log('steam-exe = ' + __addon__.getSetting('steam-exe'))
157248
log('steam-path = ' + __addon__.getSetting('steam-path'))
158249

250+
# backwards compatibility for versions prior to 0.6.0
251+
if __addon__.getSetting('steam-id') != '' and __addon__.getSetting('steam-key') != '' and __addon__.getSetting('steam-path') != '' and __addon__.getSetting('steam-exe') == '':
252+
253+
__addon__.setSetting('steam-exe', __addon__.getSetting('steam-path'));
254+
255+
if sys.platform == "linux" or sys.platform == "linux2":
256+
257+
__addon__.setSetting('steam-path', os.path.expanduser('~/.steam'));
258+
259+
elif sys.platform == "win32":
260+
261+
__addon__.setSetting('steam-path', os.path.expandvars('%ProgramFiles%\\Steam\\Steam.exe'))
262+
263+
elif sys.platform == "win64":
264+
265+
__addon__.setSetting('steam-path', os.path.expandvars('%ProgramFiles(x86)%\\Steam\\Steam.exe'))
266+
159267
# all settings are empty, assume this is the first run
160268
# best guess at steam executable path
161-
if __addon__.getSetting('steam-id') == '' and __addon__.getSetting('steam-key') == '' and __addon__.getSetting('steam-path') == '':
269+
if __addon__.getSetting('steam-id') == '' and __addon__.getSetting('steam-key') == '' and __addon__.getSetting('steam-exe') == '':
162270

163271
if sys.platform == "linux" or sys.platform == "linux2":
164272

165-
__addon__.setSetting('steam-path', '/usr/bin/steam')
273+
__addon__.setSetting('steam-exe', '/usr/bin/steam')
274+
__addon__.setSetting('steam-path', os.path.expanduser('~/.steam'));
166275

167276
elif sys.platform == "darwin":
168277

169-
__addon__.setSetting('steam-path', os.path.expanduser('~/Library/Application Support/Steam/Steam.app/Contents/MacOS/steam_osx'))
278+
__addon__.setSetting('steam-exe', os.path.expanduser('~/Library/Application Support/Steam/Steam.app/Contents/MacOS/steam_osx'))
279+
# TODO: not a clue
170280

171281
elif sys.platform == "win32":
172282

283+
__addon__.setSetting('steam-exe', os.path.expandvars('%ProgramFiles%\\Steam\\Steam.exe'))
173284
__addon__.setSetting('steam-path', os.path.expandvars('%ProgramFiles%\\Steam\\Steam.exe'))
174285

175286
elif sys.platform == "win64":
176287

288+
__addon__.setSetting('steam-exe', os.path.expandvars('%ProgramFiles(x86)%\\Steam\\Steam.exe'))
177289
__addon__.setSetting('steam-path', os.path.expandvars('%ProgramFiles(x86)%\\Steam\\Steam.exe'))
178290

291+
if __addon__.getSetting('version') == '':
292+
293+
# first time run, store version
294+
__addon__.setSetting('version', '0.6.0');
295+
179296
# prompt the user to configure the plugin with their steam details
180297
if __addon__.getSetting('steam-id') == '' or __addon__.getSetting('steam-key') == '':
181298

resources/settings.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
<setting id="debug" type="bool" label="Enable debugging mode" default="false"/>
44
<setting id="steam-id" type="text" label="Your Steam user id"/>
55
<setting id="steam-key" type="text" label="Your Steam web API key"/>
6-
<setting id="steam-path" type="executable" label="Path to your Steam executable"/>
6+
<setting id="steam-exe" type="executable" label="Your Steam executable file (Steam.exe)"/>
7+
<setting id="steam-path" type="folder" label="Your Steam folder (contains registry.vdf)"/>
78
<setting id="steam-args" type="text" label="Arguments to pass to your Steam executable"/>
9+
<setting id="version" type="text" label="Internal version number, do not modify" visible="false"/>
810
</settings>

0 commit comments

Comments
 (0)