def end_turn(self): end_turn = simplewml.Tag("end_turn") command = simplewml.Tag("command") command.tags.append(end_turn) turn = simplewml.Tag("turn") turn.tags.append(command) self.write_wml(turn)
def process_connecting(self, data): #TODO: make this return a dict or something for tag in data.tags: if tag.name == "version": t = simplewml.Tag("version") t.keys["version"] = self.version self.write_wml(t) elif tag.name == "reject": raise VersionRefused( "Failed to connect: we are version {0} and the server accepts clients of types {1}" .format(self.version, tag.keys["accepted_versions"])) elif tag.name == "redirect": self.con = gzip_connection.GzipClient(tag.keys["host"], tag.keys["port"]) if self.con.getpeername() in self.redirpath: errmsg = "Redirect loop detected on version {0}: ".format( self.version) for step in self.redirpath: errmsg += "{0}:{1} -> ".format(*step) errmsg += "{0}:{1}".format(tag.keys["host"], tag.keys["port"]) raise RedirectLoop(errmsg) self.redirpath.append(self.con.getpeername()) elif tag.name == "mustlogin": t = simplewml.Tag("login") self.name = self.basename t.keys["username"] = self.name self.write_wml(t) elif tag.name == "join_lobby": self.enter_lobby() elif tag.name == "error": if tag.keys.get("error_code") == "101": t = simplewml.Tag("login") self.name = "{0}{1:03}".format(self.basename, random.randint(0, 999)) t.keys["username"] = self.name self.write_wml(t) else: raise Exception( "Received [error] with code {0} and message: {1}". format(tag.keys["error_code"], tag.keys["message"])) else: raise Exception("Unknown tag received:\n{0}\n".format( tag.name)) if "version" in data.keys: # This is the backwards compatibility thing, we should really do it after the [reject] raise VersionRefused( "Failed to connect: we are version {0} and the server only accepts {1}" .format(self.version, data.keys["version"])) return self.mode != Modes.CONNECTING
def poll(self): acted = False if self.sock.poll(): try: self.accept(self.sock.accept()) except Exception as e: print "Failed to accept a connection:" traceback.print_exc() acted = True for client in self.clients: try: if client.poll(): acted = True except StopIteration: self.clients.remove(client) except Exception as e: try: error = simplewml.Tag("error") error.keys["message"] = "Internal error: " + str(e) client.write_wml(error) except: pass print "A client died:" traceback.print_exc() self.clients.remove(client) return acted
def process_game(self, data): response = {} if len(data.keys): self.raws.append(simplewml.Tag("FAKE: loose keys")) self.raws[-1].keys = data.keys for tag in data.tags: self.raws.append(tag) if tag.name == "leave_game": self.enter_lobby() elif tag.name == "host_transfer": get_or_create(response, "host_transfer").append( (tag.keys["name"], tag.keys["value"])) elif tag.name == "change_controller": get_or_create(response, "change_controller").append( (int(tag.keys["side"]), tag.keys["player"], tag.keys["controller"])) elif tag.name == "observer": get_or_create(response, "observer_added").append(tag.keys["name"]) elif tag.name == "observer_quit": get_or_create(response, "observer_deleted").append(tag.keys["name"]) elif tag.name == "turn": if len(tag.tags) == 1 and tag.tags[0].name == "command" and\ len(tag.tags[0].tags) == 1 and tag.tags[0].tags[0].name == "speak": speak = tag.tags[0].tags[0] speaker = speak.keys["id"] message = speak.keys["message"] get_or_create(response, "message").append( (speaker, message)) self.chatlog.append(speak) else: get_or_create(response, "loose_tags").append(tag) return response
def speak(self, message, target=None): if self.mode == Modes.GAME: speak = simplewml.Tag("speak") speak.keys["message"] = message if target: speak.keys["team_name"] = target command = simplewml.Tag("command") command.tags.append(speak) tag = simplewml.Tag("turn") tag.tags.append(command) elif self.mode == Modes.LOBBY: if target: tag = simplewml.Tag("whisper") tag.keys["receiver"] = target else: tag = simplewml.Tag("message") tag.keys["message"] = message self.write_wml(tag)
def direct_version(version): releaseobj = Config().version_by_filter(version) if releaseobj: servers_up = find_valid_servernames(releaseobj["name"]) server_objs = Config().servers server_objs.sort(key=lambda x: x["order"]) candidates = [s["host"] for s in server_objs if s["name"] in servers_up] else: candidates = [] if len(candidates): redir = simplewml.Tag("redirect") redir.keys["host"] = candidates[0] redir.keys["port"] = releaseobj["port"] return redir else: reject = simplewml.Tag("reject") reject.keys["accepted_versions"] = ",".join(versions_up()) if "." not in version or int(version.split(".")[1]) < 11: root = simplewml.RootTag() root.tags.append(reject) root.keys["version"] = reject.keys["accepted_versions"] reject = root return reject
def process_setup(self, data): response = [] if len(data.keys): self.raws.append(simplewml.Tag("FAKE: loose keys")) self.raws[-1].keys = data.keys for key, value in data.keys.items(): pass for tag in data.tags: self.raws.append(tag) response.append(str(tag)) if tag.name == "gamelist_diff": print "[gamelist_diff] encountered during setup" elif tag.name in ["user", "gamelist"]: pass elif tag.name == "start_game": self.enter_game() elif tag.name == "leave_game": self.enter_lobby() else: pass return response
def send_error(self, message): err = simplewml.Tag("error") err.keys["message"] = "#Error: {0}".format(message) self.write_wml(err)
def send_message(self, message): msg = simplewml.Tag("message") msg.keys["message"] = message self.write_wml(msg)
def process(self, data): for tag in data.tags: if tag.name == "request_campaign_list": campaigns = simplewml.Tag("campaigns") # We could do filtering here, but the client never asks for it for campaign in self.config.tags[0].tags: camp = simplewml.Tag("campaign") camp.keys = campaign.keys.copy() camp.tags = campaign.tags del camp.keys["passphrase"] del camp.keys["upload_ip"] camp.keys.pop("email", None) campaigns.tags.append(camp) self.write_wml(campaigns) elif tag.name == "request_terms": self.send_message("All add-ons uploaded to this server must be licensed under the terms of the GNU General Public License (GPL). By uploading content to this server, you certify that you have the right to place the content under the conditions of the GPL, and choose to do so.") elif tag.name == "request_campaign": addons = [addon for addon in self.config.tags[0].tags if addon.keys["name"] == tag.keys["name"]] if not addons: self.send_error("Add-on '{0}' not found.".format(tag.keys["name"])) continue else: filename = addons[0].keys["filename"] self.sock.sendfragment(open(filename).read()) # or self.write_wml(self.wml.parse(open(filename).read())) addons[0].keys["downloads"] = int(addons[0].keys["downloads"]) + 1 # TODO: we should create a better way to do this elif tag.name == "upload": if not tag.tags or tag.tags[0].name != "data": self.send_error("Add-on rejected: No add-on data was supplied.") continue data = tag.tags[0] lcname = tag.keys["name"].lower() # TODO: check whether important keys are present # TODO: check legality of filename addon = [addon for addon in self.config.tags[0].tags if addon.keys["name"].lower() == lcname] if addon: addon = addon[0] if addon.keys["passphrase"] != tag.keys["passphrase"]: self.send_error("Add-on rejected: The add-on already exists, and your passphrase was incorrect.") continue else: addon = simplewml.Tag("campaign") self.config.tags[0].tags.append(addon) downloads = addon.keys["downloads"] if "downloads" in addon.keys else 0 addon.keys = tag.keys.copy() # TODO: be more careful about which keys to copy addon.keys["downloads"] = downloads filename = "data/{0}".format(tag.keys["name"]) addon.keys["filename"] = filename addon.keys["timestamp"] = int(time.time()) addon.keys["upload_ip"] = self.sock.getpeername()[0] # TODO: translation tags roottag = simplewml.RootTag() roottag.tags = data.tags open(filename, "w").write(str(roottag)) self.send_message("Add-on accepted.") elif tag.name == "delete": lcname = tag.keys["name"].lower() addons = [addon for addon in self.config.tags[0].tags if addon.keys["name"].lower() == lcname] if not addons: self.send_error("No add-on with that name exists.") elif tag.keys["passphrase"] != addons[0].keys["passphrase"]: self.send_error("The passphrase is incorrect.") else: os.remove(addons[0].keys["filename"]) self.config.tags[0].tags.remove(addons[0]) self.send_message("Add-on deleted.") elif tag.name == "change_passphrase": lcname = tag.keys["name"].lower() addons = [addon for addon in self.config.tags[0].tags if addon.keys["name"].lower() == lcname] if not addons: self.send_error("No add-on with that name exists.") elif tag.keys["passphrase"] != addons[0].keys["passphrase"]: self.send_error("Your old passphrase was incorrect.") else: addons[0].keys["passphrase"] = tag.keys["new_passphrase"] self.send_message("Passphrase changed.")
def give_control(self, side, player): control = simplewml.Tag("change_controller") control.keys["side"] = side control.keys["player"] = player self.write_wml(control)
def leave_game(self): leave = simplewml.Tag("leave_game") self.write_wml(leave) # We do this ourselves as we do not always get a [leave_game] in return, though sometimes, we do. self.enter_lobby()
def join_game(self, game_id, observe=True): join = simplewml.Tag("join") join.keys["observe"] = "yes" if observe else "no" join.keys["id"] = game_id self.write_wml(join) self.enter_setup()
def __init__(self, sock, verbose): wmlserver.WMLClient.__init__(self, sock) self.write_wml(simplewml.Tag("version")) self.verbose = verbose
options, args = op.parse_args() client_args = {} if len(args) > 0: print "Connecting to {0}".format(args[0]) client_args["server"] = args[0] if options.version: print "Simulating wesnoth version {0}".format(options.version) client_args["version"] = options.version try: client = wesnothd_client.Client(**client_args) if options.speak: msg = simplewml.Tag("message") msg.keys["message"] = "Hello, World!" client.con.sendfragment(str(msg)) result = True while result: result = client.poll() if True and result: print result except Exception as e: print str(e) sys.exit(1) else: conn_to = client.con.sock.getpeername() print "Connected to {0} on port {1} with version {2}".format(conn_to[0], conn_to[1], options.version)