client.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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("{}: {} / {} ({}/s)".format(
  102. resource.title(),
  103. int(amount),
  104. player_data['resources_max'][resource],
  105. player_data['resources_production'][resource]
  106. ))
  107. def do_buildings(self, args):
  108. """List the buildings of the city and their levels."""
  109. global player_data
  110. global server_config
  111. any_building = False
  112. for name, level in player_data['buildings'].items():
  113. if level > 0:
  114. any_building = True
  115. print("{}, level {}".format(server_config['building'][name]['name'], level))
  116. if not any_building:
  117. print("There are no buildings in this city.")
  118. def do_units(self, args):
  119. """List available units."""
  120. global player_data
  121. global server_config
  122. if player_data['units']:
  123. for unit in player_data['units']:
  124. print("{}, level {}".format(server_config['unit'][unit['type']]['name'], unit['level']))
  125. else:
  126. print("There are no units in this city.")
  127. def do_exit(self, args):
  128. """Exits the program."""
  129. print("Exiting.")
  130. raise SystemExit
  131. def default(self, line):
  132. print("Unknown command: " + line)
  133. def emptyline(self):
  134. pass
  135. def send_json(ws, message):
  136. ws.send(json.dumps(message))
  137. def on_message(ws, message):
  138. global player_data
  139. global server_config
  140. data = json.loads(message)
  141. if 'username' in data:
  142. player_data = data
  143. elif 'server' in data:
  144. server_config = data
  145. def on_error(ws, error):
  146. print(error)
  147. def on_close(ws):
  148. print("### closed ###")
  149. def on_open(username, password, register=False):
  150. def run(ws):
  151. send_json(ws, {
  152. 'type': "register" if register else "login",
  153. 'username': username,
  154. 'password': password,
  155. })
  156. return run
  157. def main():
  158. ws = websocket.WebSocketApp("ws://localhost:6060",
  159. on_message = on_message,
  160. on_error = on_error,
  161. on_close = on_close)
  162. option = 0
  163. while option not in (1, 2):
  164. print("1. Login")
  165. print("2. Register")
  166. print("> ", end="", flush=True)
  167. option = int(input())
  168. print("Username: ", end="", flush=True)
  169. username = input()
  170. password = getpass()
  171. ws.on_open = on_open(username, password, option == 2)
  172. def run(*args):
  173. ws.run_forever()
  174. _thread.start_new_thread(run, ())
  175. prompt = MyPrompt(ws)
  176. prompt.prompt = '> '
  177. prompt.cmdloop('Starting prompt...')
  178. if __name__ == "__main__":
  179. main()