Mercurial > mamba
annotate mamba/habitats/userlevelmenu.py @ 601:915de6c7d342 default tip
Add support for making the editor fullscreen too.
author | Simon Cross <hodgestar@gmail.com> |
---|---|
date | Sat, 14 Jan 2023 19:34:26 +0100 |
parents | 16c690a7dc27 |
children |
rev | line source |
---|---|
334 | 1 """Level menu.""" |
2 | |
590
2d3dee657638
Game runs, although weirdly
Neil Muller <drnlmuller@gmail.com>
parents:
589
diff
changeset
|
3 from urllib import request |
577
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
4 import zipfile |
592
ffb0134be578
Hack network level parsing
Neil Muller <drnlmuller@gmail.com>
parents:
590
diff
changeset
|
5 from io import BytesIO |
399
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
6 |
334 | 7 from mamba.habitats.levelmenu import LevelMenu |
8 from mamba.level import Level | |
577
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
9 from mamba.constants import LEVEL_SERVER, LEVEL_SERVER_VERSION |
402
001c3797a63b
Editor now uses templates and the user level directory.
Jeremy Thurgood <firxen@gmail.com>
parents:
399
diff
changeset
|
10 from mamba.data import get_level_list, load_file |
334 | 11 |
12 | |
362
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
13 class UserLevelApi(object): |
334 | 14 |
528 | 15 def __init__(self, ctype, url=LEVEL_SERVER, timeout=10): |
362
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
16 assert ctype in ("curated", "uncurated") |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
17 assert url.endswith("/") |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
18 self.ctype = ctype |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
19 self.level_namespace = ctype |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
20 self.url = url |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
21 self.timeout = timeout |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
22 self.cache = {} |
335 | 23 |
362
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
24 def _url_data(self, route): |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
25 url = "%s%s/%s" % (self.url, self.ctype, route) |
590
2d3dee657638
Game runs, although weirdly
Neil Muller <drnlmuller@gmail.com>
parents:
589
diff
changeset
|
26 return request.urlopen(url, timeout=self.timeout).read() |
335 | 27 |
362
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
28 def _populate_level(self, name): |
335 | 29 try: |
362
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
30 source = self._url_data("level/%s" % name) |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
31 level = Level(name, self.level_namespace, source) |
597 | 32 except Exception: |
589
fca61cd8fc33
Start working towards py3 port
Neil Muller <drnlmuller@gmail.com>
parents:
577
diff
changeset
|
33 print("Failed to download online level %r" % name) |
362
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
34 return |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
35 self.cache[name] = level |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
36 |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
37 def _populate_cache(self): |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
38 try: |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
39 data = self._url_data("index") |
597 | 40 except Exception: |
589
fca61cd8fc33
Start working towards py3 port
Neil Muller <drnlmuller@gmail.com>
parents:
577
diff
changeset
|
41 print("Failed to download online level index.") |
335 | 42 return |
43 levels = [x.strip() for x in data.splitlines()] | |
44 | |
45 for name in levels: | |
362
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
46 self._populate_level(name) |
334 | 47 |
577
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
48 def _populate_cache_from_zip(self): |
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
49 try: |
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
50 data = self._url_data("levels.zip") |
597 | 51 except Exception: |
589
fca61cd8fc33
Start working towards py3 port
Neil Muller <drnlmuller@gmail.com>
parents:
577
diff
changeset
|
52 print("Failed to download online level zip.") |
577
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
53 return |
592
ffb0134be578
Hack network level parsing
Neil Muller <drnlmuller@gmail.com>
parents:
590
diff
changeset
|
54 level_zip = zipfile.ZipFile(BytesIO(data), "r") |
577
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
55 levels = level_zip.namelist() |
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
56 for level in levels: |
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
57 try: |
592
ffb0134be578
Hack network level parsing
Neil Muller <drnlmuller@gmail.com>
parents:
590
diff
changeset
|
58 source = level_zip.read(level).decode('utf-8') |
577
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
59 self.cache[level] = Level(level, self.level_namespace, source) |
592
ffb0134be578
Hack network level parsing
Neil Muller <drnlmuller@gmail.com>
parents:
590
diff
changeset
|
60 except Exception as e: |
589
fca61cd8fc33
Start working towards py3 port
Neil Muller <drnlmuller@gmail.com>
parents:
577
diff
changeset
|
61 print("Failed to parse online level %r" % level) |
592
ffb0134be578
Hack network level parsing
Neil Muller <drnlmuller@gmail.com>
parents:
590
diff
changeset
|
62 print('Error: ', e) |
577
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
63 |
334 | 64 def list_levels(self): |
362
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
65 if not self.cache: |
577
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
66 if LEVEL_SERVER_VERSION >= 2: |
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
67 self._populate_cache_from_zip() |
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
68 else: |
486c7ae141ea
Add client support for level server API version 2.
Simon Cross <hodgestar@gmail.com>
parents:
528
diff
changeset
|
69 self._populate_cache() |
431
15771cc126fc
Always return network levels in a consistent order.
Simon Cross <hodgestar@gmail.com>
parents:
402
diff
changeset
|
70 return sorted(self.cache.keys()) |
334 | 71 |
366
d759f49c477d
Option for printing list of uncurated levels.
Simon Cross <hodgestar@gmail.com>
parents:
362
diff
changeset
|
72 def print_levels(self): |
d759f49c477d
Option for printing list of uncurated levels.
Simon Cross <hodgestar@gmail.com>
parents:
362
diff
changeset
|
73 title = "%s levels:" % self.ctype.title() |
589
fca61cd8fc33
Start working towards py3 port
Neil Muller <drnlmuller@gmail.com>
parents:
577
diff
changeset
|
74 print(title) |
fca61cd8fc33
Start working towards py3 port
Neil Muller <drnlmuller@gmail.com>
parents:
577
diff
changeset
|
75 print("=" * len(title)) |
366
d759f49c477d
Option for printing list of uncurated levels.
Simon Cross <hodgestar@gmail.com>
parents:
362
diff
changeset
|
76 for name in self.list_levels(): |
589
fca61cd8fc33
Start working towards py3 port
Neil Muller <drnlmuller@gmail.com>
parents:
577
diff
changeset
|
77 print(name) |
fca61cd8fc33
Start working towards py3 port
Neil Muller <drnlmuller@gmail.com>
parents:
577
diff
changeset
|
78 print("=" * len(title)) |
366
d759f49c477d
Option for printing list of uncurated levels.
Simon Cross <hodgestar@gmail.com>
parents:
362
diff
changeset
|
79 |
334 | 80 def get_level(self, name): |
362
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
81 if name not in self.cache: |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
82 self._populate_level(name) |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
83 return self.cache[name] |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
84 |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
85 |
399
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
86 class NetworkLevelMenu(LevelMenu): |
362
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
87 |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
88 API = UserLevelApi("curated") |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
89 |
399
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
90 @property |
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
91 def level_namespace(self): |
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
92 self.API.level_namespace |
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
93 |
362
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
94 def list_levels(self): |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
95 return self.API.list_levels() |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
96 |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
97 def get_level(self, name): |
cc8be536a7fc
Add ability to play uncurated levels via the command line.
Simon Cross <hodgestar@gmail.com>
parents:
361
diff
changeset
|
98 return self.API.get_level(name) |
399
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
99 |
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
100 |
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
101 class UserLevelMenu(LevelMenu): |
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
102 |
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
103 level_namespace = "user" |
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
104 |
507
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
105 def on_enter(self): |
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
106 super(UserLevelMenu, self).on_enter() |
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
107 self._levels = {} |
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
108 self._level_list = [] |
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
109 |
399
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
110 def list_levels(self): |
507
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
111 if not self._level_list: |
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
112 for name in get_level_list('user_levels', is_user_dir=True): |
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
113 try: |
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
114 self.get_level(name) |
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
115 self._level_list.append(name) |
597 | 116 except Exception: |
589
fca61cd8fc33
Start working towards py3 port
Neil Muller <drnlmuller@gmail.com>
parents:
577
diff
changeset
|
117 print("Invalid user level:", name) |
507
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
118 return self._level_list[:] |
399
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
119 |
12d67f69e6b2
Support for user levels.
Jeremy Thurgood <firxen@gmail.com>
parents:
366
diff
changeset
|
120 def get_level(self, name): |
507
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
121 if name not in self._levels: |
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
122 src = load_file('user_levels/%s.txt' % (name,), is_user_dir=True) |
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
123 self._levels[name] = Level(name, self.level_namespace, src.read()) |
f4f883418ac2
Better user level habitat things.
Jeremy Thurgood <firxen@gmail.com>
parents:
431
diff
changeset
|
124 return self._levels[name] |