summaryrefslogtreecommitdiff
path: root/src/unlock.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/unlock.py')
-rw-r--r--src/unlock.py37
1 files changed, 35 insertions, 2 deletions
diff --git a/src/unlock.py b/src/unlock.py
index dfeaa33..446cd0a 100644
--- a/src/unlock.py
+++ b/src/unlock.py
@@ -8,7 +8,9 @@ class UnlockParseError(ValueError):
pass
def parseUnlockText(text):
- return _parseUnlockBit(text.lower())
+ parsed = _parseUnlockBit(text.lower())
+ if parsed == ('always',):
+ return None
def _parseUnlockBit(text):
# blank criterion
@@ -19,7 +21,11 @@ def _parseUnlockBit(text):
m = LEVEL_RE.match(text)
if m:
one, two, secret = m.groups()
- return ('level', int(one), int(two), (secret != None))
+ w = int(one)
+ l = int(two)
+ if w < 1 or w > 10:
+ raise UnlockParseError('world must be between 1 to 10 inclusive; not %s' % w)
+ return ('level', w, l, (secret != None))
# OK, let's parse parentheses
pLevel = 0
@@ -49,6 +55,9 @@ def _parseUnlockBit(text):
raise UnlockParseError('close parenthesis without a matching open')
elif pLevel == 0:
subTerms.append((currentSubTermStart, index, text[currentSubTermStart+1:index]))
+ if len(subTerms) > 64:
+ raise UnlockParseError('no more than 64 subterms in one %s condition' % whatCombiner.upper())
+
# are we expecting to see something else?
if index == endAt: break
@@ -88,6 +97,9 @@ def _parseUnlockBit(text):
def stringifyUnlockData(data):
+ if data == None:
+ return ''
+
kind = data[0]
if kind == 'always':
@@ -98,6 +110,27 @@ def stringifyUnlockData(data):
return (' %s ' % kind).join(map(lambda x: '(%s)' % stringifyUnlockData(x), data[1]))
+def packUnlockSpec(spec):
+ kind = data[0]
+
+ if kind == 'always':
+ return '\x0F'
+
+ elif kind == 'level':
+ k, world, level, secret = data
+
+ one = (1 << 6) | (0x10 if secret else 0) | (worldNumber - 1)
+
+ return chr(one) + chr(level - 1)
+
+ elif kind == 'and' or kind == 'or':
+ terms = data[1]
+ cond = 2 if (kind == 'and') else 3
+ one = (cond << 6) | (len(terms) - 1)
+
+ return chr(one) + ''.join(map(packUnlockSpec, terms))
+
+
if __name__ == '__main__':
p1 = parseUnlockText('((01-01 secret) and (01-02)) or (02-99 secret) or (01-01)')
p2 = parseUnlockText('(1-1 secret) or ((1-2) and (1-3 secret)) or (2-1)')