/ tools / wld2json.py
wld2json.py
  1  import json
  2  import sys
  3  
  4  DIRS = {
  5      "0": "North",
  6      "1": "East",
  7      "2": "South",
  8      "3": "West",
  9      "4": "Up",
 10      "5": "Down", 
 11  }
 12  
 13  index = 0
 14  
 15  def getline(lines):
 16      global index
 17      index += 1
 18      # print(f'{index=}: raw: {lines[index-1].strip()}//')
 19      return lines[index-1].strip('\n\r')
 20  
 21  def _delimited(lines, inline=True, strip=False):
 22      payload = []
 23      done = False
 24  
 25      while not done:
 26          next = getline(lines)
 27          if not next:
 28              payload.append(next)
 29              continue
 30  
 31          if inline and next[-1] == '~':
 32              next = next[:-1]
 33              done = True
 34  
 35          if next == '~':
 36              done = true
 37          else:
 38              if next:
 39                  payload.append(next)
 40      #print(f'delimited: {payload=}')
 41      return payload
 42  
 43  def _direction(lines):
 44      payload = {}
 45  
 46      try:
 47          payload['description'] = _delimited(lines)
 48          keywords = ' '.join(_delimited(lines, inline=True))
 49          payload['keywords'] = keywords.split(' ') if keywords else []
 50          payload['flag'], payload['key'], payload['link'] = getline(lines).strip().split(' ')
 51      except Exception as e:
 52          print(f'bad direction: {e}')
 53          print(f' direction: {lines[index]=}')
 54          print(f' direction: {payload=}')
 55  
 56      return payload
 57  
 58  def churn(wld):
 59      rooms = []
 60  
 61      with open(wld) as file:
 62          lines = file.readlines()
 63  
 64          while True:
 65              line = getline(lines)
 66              if line[0] == '$':
 67                  break
 68  
 69              jwld = {}
 70              jwld['vnum'] = int(line[1:])
 71              jwld['name'] = getline(lines)[:-1]
 72              jwld['description'] = _delimited(lines)
 73  
 74              zonestr, roombstr, secstr = getline(lines).split(' ')
 75  
 76              jwld['zone'] = int(zonestr)
 77              jwld['bitvector'] = roombstr
 78              jwld['sector'] = int(secstr)
 79  
 80              jwld['directions'] = {}
 81              jwld['extra'] = {}
 82  
 83              while True:
 84                  try:
 85                      entry = getline(lines)
 86                      match entry[0]:
 87                          case 'D':
 88                              jwld['directions'][DIRS[entry[1:].strip()]] = _direction(lines)
 89                          case 'E':
 90                              keywords = ' '.join(_delimited(lines, inline=True))
 91                              jwld['extra']['keywords'] = keywords.split(' ') if keywords else []
 92                              jwld['extra']['description'] = _delimited(lines)
 93                          case 'S':
 94                              print(f'adding room {jwld["vnum"]}')
 95                              rooms.append(jwld)
 96                              break  # new room
 97                          case '$':
 98                              return rooms
 99                          case _:
100                              print(f'what is {entry}?')
101                  except Exception as e:
102                      print(f'other: {e}')
103                      print(f'{lines[index]=}')
104                      print(json.dumps(jwld, indent=2))
105      return rooms
106  
107  if __name__ == '__main__':
108      wld = sys.argv[1]
109      rooms = churn(wld)
110  
111      jsonfile = f'{wld[:-4]}.json'
112      json.dump(rooms, open(jsonfile, 'w'), indent=4)
113      print(f'wrote {jsonfile}')