/bravo/infini/factory.py

https://github.com/JDShu/bravo
Python | 110 lines | 77 code | 25 blank | 8 comment | 6 complexity | df3b5c27bddd31de27acaa4a087eabea MD5 | raw file
  1. from urllib import urlencode
  2. from urlparse import urlunparse
  3. from twisted.internet import reactor
  4. from twisted.internet.protocol import Factory
  5. from twisted.internet.task import LoopingCall
  6. from twisted.python import log
  7. from twisted.web.client import getPage
  8. from bravo import version as bravo_version
  9. from bravo.entity import Pickup, Player
  10. from bravo.infini.protocol import InfiniClientProtocol, InfiniNodeProtocol
  11. (STATE_UNAUTHENTICATED, STATE_CHALLENGED, STATE_AUTHENTICATED,
  12. STATE_LOCATED) = range(4)
  13. entities_by_name = {
  14. "Player": Player,
  15. "Pickup": Pickup,
  16. }
  17. class InfiniClientFactory(Factory):
  18. """
  19. A ``Factory`` that serves as an InfiniCraft client.
  20. """
  21. protocol = InfiniClientProtocol
  22. def __init__(self, config, name):
  23. self.protocols = set()
  24. self.config = config
  25. log.msg("InfiniClient started")
  26. def buildProtocol(self, addr):
  27. log.msg("Starting connection to %s" % addr)
  28. return Factory.buildProtocol(self, addr)
  29. class InfiniNodeFactory(Factory):
  30. """
  31. A ``Factory`` that serves as an InfiniCraft node.
  32. """
  33. protocol = InfiniNodeProtocol
  34. ready = False
  35. broadcast_loop = None
  36. def __init__(self, config, name):
  37. self.name = name
  38. self.port = self.config.getint("infininode %s" % name, "port")
  39. self.gateway = self.config.get("infininode %s" % name, "gateway")
  40. self.private_key = self.config.getdefault("infininode %s" % name,
  41. "private_key", None)
  42. self.broadcast_loop = LoopingCall(self.broadcast)
  43. self.broadcast_loop.start(220)
  44. def broadcast(self):
  45. args = urlencode({
  46. "max_clients": 10,
  47. "max_chunks": 256,
  48. "client_count": 0,
  49. "chunk_count": 0,
  50. "node_agent": "Bravo %s" % bravo_version,
  51. "port": self.port,
  52. "name": self.name,
  53. })
  54. if self.private_key:
  55. url = urlunparse(("http", self.gateway,
  56. "/broadcast/%s/" % self.private_key, None, args, None))
  57. else:
  58. url = urlunparse(("http", self.gateway, "/broadcast/", None, args,
  59. None))
  60. d = getPage(url)
  61. d.addCallback(self.online)
  62. d.addErrback(self.error)
  63. def broadcasted(self):
  64. self.ready = True
  65. def online(self, response):
  66. log.msg("Successfully said hi")
  67. log.msg("Response: %s" % response)
  68. if response == "Ok":
  69. # We're in business!
  70. reactor.callLater(0, self.broadcasted)
  71. elif response.startswith("Ok"):
  72. # New keypair?
  73. try:
  74. okay, public, private = response.split(":")
  75. self.public_key = public
  76. self.private_key = private
  77. self.save_keys()
  78. except ValueError:
  79. pass
  80. reactor.callLater(0, self.broadcasted)
  81. def save_keys(self):
  82. pass
  83. def error(self, reason):
  84. log.err("Couldn't talk to gateway %s" % self.gateway)
  85. log.err(reason)