client.py 6.6 KB

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