client.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. from getpass import getpass
  2. import websocket
  3. import _thread
  4. import json
  5. import time
  6. from cmd import Cmd
  7. class MyPrompt(Cmd):
  8. def __init__(self, ws):
  9. super(MyPrompt, self).__init__()
  10. self.ws = ws
  11. def do_build(self, args):
  12. """Starts the construction of a building."""
  13. send_json(self.ws, {
  14. 'type': "build",
  15. 'name': args,
  16. })
  17. def do_train(self, args):
  18. """Starts the training of a unit."""
  19. args = args.split(" ")
  20. send_json(self.ws, {
  21. 'type': "train",
  22. 'name': args[0],
  23. 'level': args[1] if len(args) > 1 else 1
  24. })
  25. def do_jobs(self, args):
  26. """List the current running jobs."""
  27. global player_data
  28. global server_config
  29. for job in player_data['jobs']:
  30. product = job['product']
  31. if product['type'] == "building":
  32. print("Upgrading {} to level {}.".format(server_config['building'][product['name']]['name'], player_data['buildings'][product['name']] + 1))
  33. elif product['type'] == "unit":
  34. print("Training level {} {}.".format(product['level'], server_config['unit'][product['name']]['name']))
  35. elif product['type'] == "mission":
  36. print("Mission: {}".format(product['mission']['name']))
  37. else:
  38. print("Unknown job: {}".format(job))
  39. bar_width = 20
  40. remaining = job['finish_time'] - time.time()
  41. progress = remaining / job['product']['time']
  42. num_bars = bar_width - int(progress * bar_width)
  43. print("[" + num_bars * "#" + (bar_width - num_bars) * " " + "]" + str(int(remaining)) + "s remaining")
  44. print("-" * (bar_width + 10))
  45. if not player_data['jobs']:
  46. print("No jobs are currently running.")
  47. def do_missions(self, args):
  48. """List available missions."""
  49. global player_data
  50. global server_config
  51. for i, mission in enumerate(player_data['missions']):
  52. print("{}. {}".format(i + 1, mission['name']))
  53. print("Units required:")
  54. for unit, count in mission['units'].items():
  55. print("\t- {} x{}".format(server_config['unit'][unit]['name'], count))
  56. print("Rewards:")
  57. print("\tResources:")
  58. for resource, amount in mission['rewards']['resources'].items():
  59. print("\t- {} x{}".format(resource, amount))
  60. print("-" * 20)
  61. option = 0
  62. opt_len = len(player_data['missions'])
  63. while option not in range(1, opt_len + 1):
  64. print("[1-{}] or 'c' to cancel: ".format(opt_len), end="", flush=True)
  65. try:
  66. option = input()
  67. if option == 'c':
  68. return
  69. else:
  70. option = int(option)
  71. except ValueError:
  72. print("Please enter an integer.")
  73. mission = player_data['missions'][option - 1]
  74. units_required = dict(mission['units'])
  75. units = list()
  76. if mission['type'] == 'gather':
  77. for i, unit in enumerate(player_data['units']):
  78. if unit['type'] in units_required.keys() and units_required[unit['type']] > 0:
  79. units.append(i)
  80. units_required[unit['type']] -= 1
  81. if sum(units_required.values()) == 0:
  82. send_json(self.ws, {
  83. 'type': "mission",
  84. 'index': option - 1,
  85. 'units': units,
  86. })
  87. else:
  88. print("Not enough units.")
  89. def do_resources(self, args):
  90. """List available resources."""
  91. global player_data
  92. for resource, amount in player_data['resources'].items():
  93. print(resource.title() + ": " + str(int(amount)) + " / " + str(player_data['resources_max'][resource]))
  94. def do_buildings(self, args):
  95. """List the buildings of the city and their levels."""
  96. global player_data
  97. global server_config
  98. any_building = False
  99. for name, level in player_data['buildings'].items():
  100. if level > 0:
  101. any_building = True
  102. print("{}, level {}".format(server_config['building'][name]['name'], level))
  103. if not any_building:
  104. print("There are no buildings in this city.")
  105. def do_units(self, args):
  106. """List available units."""
  107. global player_data
  108. global server_config
  109. if player_data['units']:
  110. for unit in player_data['units']:
  111. print("{}, level {}".format(server_config['unit'][unit['type']]['name'], unit['level']))
  112. else:
  113. print("There are no units in this city.")
  114. def do_exit(self, args):
  115. """Exits the program."""
  116. print("Exiting.")
  117. raise SystemExit
  118. def default(self, line):
  119. print("Unknown command: " + line)
  120. def emptyline(self):
  121. pass
  122. def send_json(ws, message):
  123. ws.send(json.dumps(message))
  124. def on_message(ws, message):
  125. global player_data
  126. global server_config
  127. data = json.loads(message)
  128. if 'username' in data:
  129. player_data = data
  130. elif 'server' in data:
  131. server_config = data
  132. def on_error(ws, error):
  133. print(error)
  134. def on_close(ws):
  135. print("### closed ###")
  136. def on_open(username, password, register=False):
  137. def run(ws):
  138. send_json(ws, {
  139. 'type': "register" if register else "login",
  140. 'username': username,
  141. 'password': password,
  142. })
  143. return run
  144. def main():
  145. ws = websocket.WebSocketApp("ws://localhost:6060",
  146. on_message = on_message,
  147. on_error = on_error,
  148. on_close = on_close)
  149. option = 0
  150. while option not in (1, 2):
  151. print("1. Login")
  152. print("2. Register")
  153. print("> ", end="", flush=True)
  154. option = int(input())
  155. print("Username: ", end="", flush=True)
  156. username = input()
  157. password = getpass()
  158. ws.on_open = on_open(username, password, option == 2)
  159. def run(*args):
  160. ws.run_forever()
  161. _thread.start_new_thread(run, ())
  162. prompt = MyPrompt(ws)
  163. prompt.prompt = '> '
  164. prompt.cmdloop('Starting prompt...')
  165. if __name__ == "__main__":
  166. main()