def __init__(self, networkname, server_config, bot_config, joinlist, modules_config): self.alive = True self.connected = False self.hostname = server_config['hostname'] self.port = int(server_config.get('port', "6667")) self.nick = bot_config['nick'] self.altnick = bot_config.get('altnick', self.nick + "_") self.username = bot_config['username'] self.realname = bot_config['realname'] self.owner = bot_config['owner'] self.networkname = networkname self.joinlist = joinlist self._reader_thread = None self._parser = MessageParser() self._init_callback_table() self._socket = None self._channel_list = [] self._modules_config = modules_config self.dynamic_modules = [ DynamicModule(self, m, c) for m, c in modules_config.items() ] self._last_ping = time.time()
def __init__(self, networkname, server_config, bot_config, joinlist, modules_config): self.alive = True self.connected = False self.hostname = server_config['hostname'] self.port = int(server_config.get('port', "6667")) self.nick = bot_config['nick'] self.altnick = bot_config.get('altnick', self.nick + "_") self.username = bot_config['username'] self.realname = bot_config['realname'] self.owner = bot_config['owner'] self.networkname = networkname self.joinlist = joinlist self._reader_thread = None self._parser = MessageParser() self._init_callback_table() self._socket = None self._channel_list = [] self._modules_config = modules_config self.dynamic_modules = [DynamicModule(self, m, c) for m, c in modules_config.items()] self._last_ping = time.time()
def __init__(self, sock): self.__socket = sock self.__message_parser = MessageParser() self.__lobby_model = LobbyModel() # name of the game self.__game = None # player number (1 or 2) self.__player = None # player id lol self.__id = self.__get_own_player_id() # add client as player self.__lobby_model.add_player(self.__id) # register callbacks self.__lobby_model.register_callback(LobbyEvent.on_update, self.on_update_lobby) self.__lobby_model.register_callback(LobbyEvent.on_chat, self.on_chat)
def __init__(self, message): self.message_parser = MessageParser(message) # hole, [['2c', '2d'],...] for 6 players self.hole = self.message_parser.hole # board ['2c', '2d', '2h', ...] for at most 5 board cards self.board = self.message_parser.board self.viewing_player = self.message_parser.get_position() self.betting_string = self.message_parser.get_betting_string(rd=None) self.board_string = self.message_parser.get_board_string(rd=None) # a two-dimension list, dim-1 is round, dim-2 is i-th action of a round self.betting_action = self.get_betting_action() # a one-dimension list, store each {action string} as an element self.action_list = [] # store each {action object} of all round actions in a one-dimension list for each_round_action in self.betting_action: for action in each_round_action: self.action_list.append(Action(action)) # set up basic data structure self.spent = [50, 100, 0, 0, 0, 0] self.active = [True] * 6 self.fold = [False] * 6 self.allin = [False] * 6 self.pot = 150 self.max_bet = 100 self.current_player = 2 # player at seat 2 is first player to act in PREFLOP round self.finished = False self.round = Round.PREFLOP self.boards = None # first round have no board cards self.holes = None # hole array for 6 players self.min_no_limit_raise_to = 2 * 100 self.max_no_limit_raise_to = 20000 self.next_round_flag = False self.call_number = 0 # update [hole] and [board] self.holes = self.message_parser.get_hole_card(position=None) self.boards = self.message_parser.get_board_card(rd=None) # after setting up basic data structure, start to do each action and update data structure cnt = 0 for action in self.action_list: cnt += 1 self.do_action(action)
def __init__(self, roverID, blockInfo): self.roverID = roverID self.blockInfo = blockInfo self.posY = 0 self.nextY = 0 if roverID == 0: self.posX = 0 self.nextX = 0 else: self.posX = -1 self.nextX = -1 # Declare test client and parser self.clientConnection = TestClient() self.parser = MessageParser(roverID) # Connect signals and slots self.clientConnection.messageFromServer.connect(self.parser.parse) self.parser.parsedMessageSignal.connect(self.messageFromServer) self.parser.constructedMessageSignal.connect( self.clientConnection.sendMessageToServer)
def __init__(self, sock): self.__socket = sock self.__message_parser = MessageParser() self.__lobby_model = LobbyModel() # name of the game self.__game = None # player number (1 or 2) self.__player = None # player id lol self.__id = self.__get_own_player_id() # add client as player self.__lobby_model.add_player(self.__id) # register callbacks self.__lobby_model.register_callback(LobbyEvent.on_update, self.on_update_lobby) self.__lobby_model.register_callback(LobbyEvent.on_chat, self.on_chat)
def cleanup(): print('cleanup') server.closeServer() # Make Qt happy app = QApplication(sys.argv) # Declare server server = team13Server('192.168.42.1', 2000) # Declare server GUI serverGui = MainWindow() # Declare parser for rover 0 rover0Parser = MessageParser(0) # Declare parser for rover 1 rover1Parser = MessageParser(1) # Central class holding positions of both rovers roverPositions = RoverPositions() # Declare controller for rover 0 rover0Controller = Rover0Control(roverPositions) # Declare controller for rover 1 rover1Controller = Rover1Control(roverPositions) # Connect server signals server.client0Message.connect(rover0Parser.parse) server.client1Message.connect(rover1Parser.parse) server.serverClosed.connect(rover0Parser.closeLog) server.startSelf.connect(server.runServer) # Connect GUI signals
# Please install the slackclient module either globally or into ./lib before running this bot # Additionally, you should fill in the config.json with all of the appropriate keys, tokens, and IDs import json, sys, socket, time sys.path.insert(0, 'lib') sys.dont_write_bytecode = True from rtmctl import SlackBotController from messageparser import MessageParser with open('config.json', 'r') as cfg: config = json.load(cfg) slackbot = SlackBotController(config=config, parser=MessageParser(config)) # Runs the bot and handles/retries on connection errors, # implements an exponential backoff up to 256 seconds. def retryLoop(func, sec): try: func() except Exception, e: sec = sec + 1 if sec < 8 else 1 print 'Connection error, retrying in ' + str(2**sec) + ' seconds...' time.sleep(2**sec) retryLoop(func, sec) retryLoop(slackbot.run, 0)
from messageparser import MessageParser mp = MessageParser() try: prefix, command, params = mp.parseMessage('USER oskar oskar 127.0.0.1 :realname\r\n') except ValueError as e: print(e) print("prefix: ", prefix) print("command:", command) print("parameters:", params) # try: # mp.parseMessage(':prefix 001 middle :this is a trailing parameter \r\n') # except ValueError as e: # print(e) # print("prefix: ", mp.prefix) # print("command:", mp.command) # print("parameters:", mp.parameters)
class ServerConnection(object): """ Class handling irc servers. """ PING_INTERVAL_THRESHOLD = 300 # 300 seconds def __init__(self, networkname, server_config, bot_config, joinlist, modules_config): self.alive = True self.connected = False self.hostname = server_config['hostname'] self.port = int(server_config.get('port', "6667")) self.nick = bot_config['nick'] self.altnick = bot_config.get('altnick', self.nick + "_") self.username = bot_config['username'] self.realname = bot_config['realname'] self.owner = bot_config['owner'] self.networkname = networkname self.joinlist = joinlist self._reader_thread = None self._parser = MessageParser() self._init_callback_table() self._socket = None self._channel_list = [] self._modules_config = modules_config self.dynamic_modules = [ DynamicModule(self, m, c) for m, c in modules_config.items() ] self._last_ping = time.time() def _init_callback_table(self): self._receive_callbacks = { MessageType.PRIVATE_MESSAGE: self._private_message_received, MessageType.JOIN: self._join_received, MessageType.PART: self._part_received, MessageType.PING: self._ping_received, MessageType.QUIT: self._quit_received, MessageType.TOPIC: self._topic_received, MessageType.END_OF_MOTD: self._motd_received, #MessageType.NICK_IN_USE: self.ni, MessageType.TOPIC_REPLY: self._topic_reply_received, MessageType.USERS: self._users_received, MessageType.END_OF_USERS: self._users_end_received, MessageType.CHANNEL_MESSAGE: self._channel_message_received, MessageType.UNKNOWN: self._unknown_message_received, MessageType.CTCP_TIME: self._ctcp_message_received, MessageType.CTCP_VERSION: self._ctcp_version_received, MessageType.CTCP_PING: self._ctcp_message_received, MessageType.CTCP_DCC: self._ctcp_message_received, } def connect(self): """ Tries to connect to irc server. """ self._reader_thread = Thread(target=self._connection_loop) self._reader_thread.start() def _connect(self): while self.alive: try: if self._socket: self._socket.close() self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._socket.connect((self.hostname, self.port)) self.NICK(self.nick) self.USER(self.username, self.realname) self._last_ping = time.time() break except Exception as e: self._print_line(str(e) + " " + self.hostname) self._print_line("Trying again in 30 seconds.") self._sleep(30) def _connection_loop(self): while self.alive: self._connect() self._read() if not self.alive: break self._print_line("Trying again in 60 seconds.") self._sleep(60) def _write(self, message): """ Prints and writes message to server. """ self._print_line(message[:-1]) self._socket.send(bytearray(message, 'utf-8')) def _check_ping_time(self): return time.time( ) - self._last_ping < ServerConnection.PING_INTERVAL_THRESHOLD def _read(self): """ Reads and handles messages. """ self._socket.settimeout(1.0) buff = "" while self.alive and self._check_ping_time(): try: tmp = self._socket.recv(4096) except socket.timeout as e: continue except socket.error as e: self._print_line(str(e)) break except KeyboardInterrupt: self.kill() return if not self.alive: break if not tmp: break tmp = tmp.decode('utf-8') buff += tmp parsed_messages, remainder = self._parser.parse_buffer(buff) buff = remainder self._handle_messages(parsed_messages) self._socket.close() self._print_line("Connection closed.") self.connected = False def _handle_messages(self, messages): """ Handles a list of messages """ for message in messages: self._receive_callbacks[message.type](**message.params) def _print_line(self, message): """ Prints message with timestamp. """ print( time.strftime("%H:%M:%S") + " |" + self.networkname + "| " + message) def NICK(self, nick): """ Sets user's nick on server. """ self._write("NICK " + nick + "\r\n") def USER(self, username, realname): """ Sets username and realname to server on connect. """ self._write("USER " + username + " 0 * :" + realname + "\r\n") def PONG(self, message): """ Reply to PING. """ self._write("PONG :" + message + "\r\n") def JOIN(self, channel): """ Joins a irc channel. """ self._write("JOIN :" + channel + "\r\n") def PART(self, channel, reason=""): """ PARTs from a channel. """ msg = "PART " + channel if reason: msg += " :" + reason self._write(msg + "\r\n") def PRIVMSG(self, target, message): """ Sends PRIVMSG to target. """ self._write("PRIVMSG " + target + " :" + message + "\r\n") def PING(self, message): """ Sends PING to server. """ self._write("PING " + message + "\r\n") def CTCP(self, target, message): self.PRIVMSG(target, str("\x01" + message + "\x01")) def NOTICE(self, target, message): self._write("NOTICE " + target + " :" + message + "\r\n") def _on_connect(self): """ Called when connected to the network. """ self.PING(self.hostname) self._join_channels() for dm in self.dynamic_modules: try: dm.instance.on_connect() except Exception as e: print(e) def _join_channels(self): """ Joins channels specified in self.joinlist """ for channel in self.joinlist: self.JOIN(channel) def kill(self): """ Called when the thread is wanted dead. """ self.alive = False for m in self.dynamic_modules: m.instance.kill() def _private_message_received(self, **kw): """ Called when a private message has been received. Prints it and calls on_private_message() on DynamicModule instances. """ source = kw['source'] message = kw['message'] full_mask = kw['full_mask'] self._print_line("PRIVATE" + " <" + source + "> " + message) for dm in self.dynamic_modules: try: dm.instance.on_private_message(source, message, full_mask) except Exception as e: print(e) def _channel_message_received(self, **kw): """ Called when a PRIVMSG to a channel has been received. Prints it and calls on_channel_message() on DynamicModule instances. """ source = kw['source'] message = kw['message'] full_mask = kw['full_mask'] channel = kw['channel_name'] self._print_line(channel + " <" + source + "> " + message) for dm in self.dynamic_modules: try: dm.instance.on_channel_message(source, channel, message, full_mask) except Exception as e: print(e) def _ping_received(self, **kw): """ Called when PING message has been received. """ self._last_ping = time.time() message = kw['message'] self.PONG(message) def _motd_received(self, **kw): """ Called when the end of MOTD message has been received. """ message = kw['message'] self._print_line(message) if not self.connected: self.connected = True self._on_connect() def _find_channel_by_name(self, channel_name): """ Returns a channel instance from channel_list matching channel_name parameter or None. """ for channel in self._channel_list: if channel.name == channel_name: return channel def _add_channel(self, name, user_list): """ Adds a channel to networks channel list. """ if self._find_channel_by_name(name): return channel = IrcChannel(name, user_list) self._channel_list.append(channel) def _users_received(self, **kw): """ Called when USERS message is received. Notifies channel instance of the users. """ channel_name = kw['channel_name'] user_list = kw['user_list'] channel = self._find_channel_by_name(channel_name) if not channel: self._add_channel(channel_name, user_list) return channel.users_message(user_list) def _users_end_received(self, **kw): """ Called when USERS message's end has been received. Notifies the channel instance. """ channel_name = kw['channel_name'] channel = self._find_channel_by_name(channel_name) if not channel: # TODO FIX self._print_line( "REPORT THIS: usersEndReceived, channel not found") return channel.users_message_end() self._print_line("USERS OF " + channel_name) self._print_line(" ".join(channel.userlist)) def _quit_received(self, **kw): """ Called when a QUIT message has been received. Calls on_quit() on DynamicModules """ nick = kw['nick'] full_mask = kw['full_mask'] for channel in self._channel_list: channel.remove_user(nick) self._print_line(nick + " has quit.") for dm in self.dynamic_modules: try: dm.instance.on_quit(nick, full_mask) except Exception as e: print(e) def _part_received(self, **kw): """ Called when a PART message has been received. Calls on_part() on DynamicModules """ nick = kw['nick'] channel_name = kw['channel_name'] full_mask = kw['full_mask'] channel = self._find_channel_by_name(channel_name) if not channel: return channel.remove_user(nick) self._print_line(nick + " has parted " + channel_name) for dm in self.dynamic_modules: try: dm.instance.on_part(nick, channel_name, full_mask) except Exception as e: print(e) def _join_received(self, **kw): """ Called when a JOIN message has been received. Calls on_join() on DynamicModules """ nick = kw['nick'] channel_name = kw['channel_name'] full_mask = kw['full_mask'] channel = self._find_channel_by_name(channel_name) if channel: channel.add_user(nick) self._print_line(nick + " has joined " + channel_name) for dm in self.dynamic_modules: try: dm.instance.on_join(nick, channel_name, full_mask) except Exception as e: print(e) def _topic_received(self, **kw): """ Called when topic is changed on a channel. Calls on_topic() on DynamicModules """ nick = kw['nick'] channel_name = kw['channel_name'] full_mask = kw['full_mask'] topic = kw['topic'] channel = self._find_channel_by_name(channel_name) if channel: channel.topic = topic self._print_line(nick + " changed the topic of " + channel_name + " to: " + topic) for dm in self.dynamic_modules: try: dm.instance.on_topic(nick, channel_name, topic, full_mask) except Exception as e: print(e) def _topic_reply_received(self, **kw): """ Called when server responds to client's /topic or server informs of the topic on joined channel. """ channel_name = kw['channel_name'] topic = kw['topic'] channel = self._find_channel_by_name(channel_name) if channel: channel.topic = topic self._print_line("Topic in " + channel_name + ": " + topic) def _ctcp_message_received(self, **kw): self._print_line("CTCP: " + str(kw)) def _ctcp_version_received(self, **kw): ":[email protected] NOTICE irckaaja :VERSION ?l? hakkeroi!" self.NOTICE(kw['source'], "\x01VERSION irckaaja 0.1.0\x01") def _unknown_message_received(self, **kw): self._print_line(kw['message']) def _sleep(self, seconds): """ Sleeps for seconds unless not self.alive. """ start = time.time() while time.time() < start + seconds and self.alive: time.sleep(1)
class ClientHandler: def __init__(self, sock): self.__socket = sock self.__message_parser = MessageParser() self.__lobby_model = LobbyModel() # name of the game self.__game = None # player number (1 or 2) self.__player = None # player id lol self.__id = self.__get_own_player_id() # add client as player self.__lobby_model.add_player(self.__id) # register callbacks self.__lobby_model.register_callback(LobbyEvent.on_update, self.on_update_lobby) self.__lobby_model.register_callback(LobbyEvent.on_chat, self.on_chat) def handle(self): logging.info("Client {} connected.".format(self.__socket.getpeername())) while True: logging.debug("handle({}) loop.".format(self.__socket.getpeername())) # receive 2 bytes size header size = self.__recv(2) if not size: logging.debug("Did not receive 2 bytes header.") break size = struct.unpack('>H', size)[0] logging.debug("Size: " + str(size)) # receive message body msg = self.__recv(size) if not msg: logging.debug("Did not receive {} bytes body.".format(str(size))) break # explode received data into message type and parameters msgtype, msgparams = self.__message_parser.decode(msg.decode()) logging.debug("Msg type: " + msgtype) logging.debug("Msg parameters: " + repr(msgparams)) # dispatch message type if msgtype == messages.CREATE_GAME: self.__create_game(msgparams) elif msgtype == messages.JOIN_GAME: self.__join_game(msgparams) elif msgtype == messages.SET_NICK: self.__set_nickname(msgparams) elif msgtype == messages.LEAVE_GAME: self.__leave_game() elif msgtype == messages.INIT_BOARD: self.__init_board(msgparams) elif msgtype == messages.FIRE: self.__fire(msgparams) elif msgtype == messages.NUKE: self.__nuke(msgparams) elif msgtype == messages.MOVE: self.__move(msgparams) elif msgtype == messages.SURRENDER: self.__surrender() elif msgtype == messages.CHAT_SEND: self.__chat(msgparams) else: self.__unknown_msg() # # Callbacks # def on_update_lobby(self): logging.debug("on_update_lobby()") # Get required data for update lobby msg number_of_clients = self.__lobby_model.get_number_of_players() number_of_games = self.__lobby_model.get_number_of_games() games_info = self.__lobby_model.get_games_info() players_info = self.__lobby_model.get_players_info() # Update_Lobby data = { 'status': 16, 'number_of_clients': number_of_clients, 'number_of_games': number_of_games[0] } i = 0 weirdkey = 'game_name_{}' moreweirdkeys = 'game_players_count_{}' whatevenisthis = 'game_player_{}_{}' waitwhat = 'player_name_{}' yetanotherkey = 'player_identifier_{}' for game in games_info: # game stuff data[weirdkey.format(i)] = game['game_name'] data[moreweirdkeys.format(i)] = game['number_of_players'] # player 1 stuff data[whatevenisthis.format(i, 0)] = game['ids'][0] # player 2 stuff if game['number_of_players'] == 2: data[whatevenisthis.format(i, 1)] = game['ids'][1] i += 1 i = 0 for player in players_info: # player stuff data[yetanotherkey.format(i)] = player['id'] data[waitwhat.format(i)] = player['nickname'] i += 1 msg = self.__message_parser.encode('report', data) self.__send(msg) def on_game_abort(self): # delete game self.__lobby_model.delete_game(self.__game) self.__game = None self.__send(self.__message_parser.encode('report', {'status': '19'})) def on_game_ended(self, winner, id0, id1, timestamp): msg = { 'status': '17', 'winner': winner - 1, 'name_of_game': self.__game, 'timestamp': timestamp, 'identifier_0': id0, 'identifier_1': id1, 'reason_for_game_end': 'Because of reasons.' } # delete game self.__lobby_model.delete_game(self.__game) self.__game = None self.__send(self.__message_parser.encode('report', msg)) def on_ship_edit(self): logging.debug('on_ship_edit()') self.__send(self.__message_parser.encode('report', {'status': '18'})) def on_game_start(self): logging.debug('on_game_start()') self.__send(self.__message_parser.encode('report', {'status': '48'})) def on_host_begins(self): logging.debug('on_host_begins()') self.__begin_turn() def on_guest_begins(self): logging.debug('on_guest_begins()') self.__begin_turn() def on_attack(self, x, y, condition): logging.debug('on_attack()') msg = None # if player is enemy if self.__lobby_model.get_game(self.__game).get_turn() == self.__player: # update own field msg = { 'status': 13, 'was_special_attack': 'false', 'coordinate_x': x, 'coordinate_y': y } self.__send(self.__message_parser.encode('report', msg)) # trigger next turn wtf self.__begin_turn() else: # update enemy field msg = { 'status': 14, 'number_of_updated_fields': '1', 'field_0_x': x, 'field_0_y': y, 'field_0_condition': condition } self.__send(self.__message_parser.encode('report', msg)) def on_special_attack(self, x, y, updates): logging.debug('on_special_attack()') msg = None if self.__lobby_model.get_game(self.__game).get_turn() == self.__player: # update own field msg = { 'status': 13, 'was_special_attack': 'true', 'coordinate_x': x, 'coordinate_y': y } self.__send(self.__message_parser.encode('report', msg)) # trigger next turn wtf self.__begin_turn() else: # update enemy field msg = { 'status': 14, 'number_of_updated_fields': len(updates) } i = 0 for j in updates: msg['field_{}_x'.format(i)] = j['field'].x msg['field_{}_y'.format(i)] =j['field'].y msg['field_{}_condition'.format(i)] = j['status'] i += 1 self.__send(self.__message_parser.encode('report', msg)) def on_move(self, updates): logging.debug('on_move()') msg = None if self.__lobby_model.get_game(self.__game).get_turn() == self.__player: # update enemy field if len(updates) > 0: msg = { 'status': 14, 'number_of_updated_fields': len(updates) } i = 0 for j in updates: msg['field_{}_x'.format(i)] = j['field'].x msg['field_{}_y'.format(i)] =j['field'].y msg['field_{}_condition'.format(i)] = j['status'] i += 1 self.__send(self.__message_parser.encode('report', msg)) # trigger next turn wtf self.__begin_turn() def on_chat(self, timestamp, player, msg): logging.debug('on_chat()') msg = { 'status': '15', 'author_id': player, 'timestamp': timestamp, 'message_content': msg } self.__send(self.__message_parser.encode('report', msg)) def get_socket(self): return self.__socket def finish(self): logging.info("Client disconnected.") # remove any left callbacks self.__lobby_model.remove_callback(LobbyEvent.on_update, self.on_update_lobby) self.__lobby_model.remove_callback(LobbyEvent.on_chat, self.on_chat) # end running game if any if self.__game and self.__lobby_model.get_game(self.__game) is not None: # remove callbacks of disconnected player self.__lobby_model.get_game(self.__game).remove_callback(GameEvent.on_ship_edit, self.on_ship_edit) self.__lobby_model.get_game(self.__game).remove_callback(GameEvent.on_game_start, self.on_game_start) self.__lobby_model.get_game(self.__game).remove_callback(GameEvent.on_attack, self.on_attack) self.__lobby_model.get_game(self.__game).remove_callback(GameEvent.on_special_attack, self.on_special_attack) self.__lobby_model.get_game(self.__game).remove_callback(GameEvent.on_move, self.on_move) #self.__lobby_model.get_game(self.__game).remove_callback(GameEvent.on_host_begins, self.on_host_begins) #self.__lobby_model.get_game(self.__game).remove_callback(GameEvent.on_guest_begins, self.on_guest_begins) self.__lobby_model.get_game(self.__game).remove_callback(GameEvent.on_game_ended, self.on_game_ended) self.__lobby_model.get_game(self.__game).remove_callback(GameEvent.on_game_abort, self.on_game_abort) # surrender if self.__lobby_model.get_game(self.__game).is_ongoing(): logging.debug("Surrender by disconnect.") self.__lobby_model.get_game(self.__game).surrender(self.__player) # abort elif self.__lobby_model.get_game(self.__game).is_ready(): logging.debug("Abort by disconnect.") self.__lobby_model.get_game(self.__game).abort() # remove player from lobby self.__lobby_model.delete_player(self.__id) def __create_game(self, params): # make sure parameter list is complete if not self.__expect_parameter(['name'], params): return # check if client is already in a game if self.__game: logging.debug("Client already in some game.") # 31 is the new 42 self.__send(self.__message_parser.encode('report', {'status': '31'})) return # check game name length if 1 > len(params['name']) or len(params['name']) > 64: logging.debug("Game name too long.") self.__send(self.__message_parser.encode('report', {'status': '37'})) return # create the game game = self.__lobby_model.add_lobby(params['name'], self.__id) if not game: self.__send(self.__message_parser.encode('report', {'status': '37'})) return self.__game = params['name'] self.__player = 1 self.__send(self.__message_parser.encode('report', {'status': '28'})) # register game callbacks self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_ship_edit, self.on_ship_edit) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_game_start, self.on_game_start) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_attack, self.on_attack) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_special_attack, self.on_special_attack) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_move, self.on_move) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_host_begins, self.on_host_begins) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_game_ended, self.on_game_ended) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_game_abort, self.on_game_abort) def __join_game(self, params): # make sure parameter list is complete if not self.__expect_parameter(['name'], params): return # check if client is already in a game if self.__game: logging.debug("Client already in some game.") self.__send(self.__message_parser.encode('report', {'status': '31'})) return # join the game game, e = self.__lobby_model.join_lobby(params['name'], self.__id) # handle game join errors if e: if e == LobbyError.game_is_full: self.__send(self.__message_parser.encode('report', {'status': '47'})) return elif e == LobbyError.game_does_not_exist: self.__send(self.__message_parser.encode('report', {'status': '37'})) return # ack game join self.__send(self.__message_parser.encode('report', {'status': '27'})) self.__game = params['name'] self.__player = 2 # register game callbacks self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_ship_edit, self.on_ship_edit) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_game_start, self.on_game_start) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_attack, self.on_attack) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_special_attack, self.on_special_attack) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_move, self.on_move) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_guest_begins, self.on_guest_begins) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_game_ended, self.on_game_ended) self.__lobby_model.get_game(self.__game).register_callback(GameEvent.on_game_abort, self.on_game_abort) self.__lobby_model.get_game(self.__game).just_begin_ship_placement_already() def __set_nickname(self, params): if not self.__expect_parameter(['name'], params): return if len(params['name']) > 64: logging.debug("Nickname too long.") self.__send(self.__message_parser.encode('report', {'status': '36'})) return # tell lobby to set nickname and hope for the best self.__lobby_model.set_nickname(self.__id, params['name']) def __get_own_player_id(self): addr, port = self.__socket.getpeername() playerid = hashlib.sha1(b(addr + str(port))).hexdigest() return playerid def __init_board(self, params): logging.debug('__init_board()') # not in any game if self.__game is None: self.__send(self.__message_parser.encode('report', {'status': '43'})) return shipx = 'ship_{}_x' shipy = 'ship_{}_y' shipdir = 'ship_{}_direction' # make sure that all parameters exist if not self.__expect_parameter( [shipx.format(i) for i in range(0, 10)] + [shipy.format(i) for i in range(0, 10)] + [shipdir.format(i) for i in range(0, 10)], params): return # init board left = True for id in range(0, 10): x = int(params[shipx.format(id)]) y = int(params[shipy.format(id)]) dir = params[shipdir.format(id)] logging.debug('self.__lobby_model :: {}'.format(repr(self.__lobby_model))) logging.debug('self.__lobby_model.get_game(self.__game) :: {}'.format(repr(self.__lobby_model.get_game(self.__game)))) logging.debug('self.__game :: {}'.format(repr(self.__game))) suc, left = self.__lobby_model.get_game(self.__game).place_ship(self.__player, x, y, dir, id) # catch illegal placement if suc == -1: logging.debug("Nonsense ship placement.") self.__send(self.__message_parser.encode('report', {'status': '38'})) return if left: logging.debug("Something is still wrong with ship placement.") self.__send(self.__message_parser.encode('report', {'status': '38'})) return # ack init board self.__send(self.__message_parser.encode('report', {'status': '29'})) # trigger random begin return message self.__lobby_model.get_game(self.__game).start() def __leave_game(self): # not in any game if self.__game is None: self.__send(self.__message_parser.encode('report', {'status': '43'})) return # make sure the game has not started yet if self.__lobby_model.get_game(self.__game).is_ongoing(): self.__send(self.__message_parser.encode('report', {'status': '43'})) logging.debug("Too late to leave the game.") return # abort self.__lobby_model.get_game(self.__game).abort() def __fire(self, params): if not self.__expect_parameter(['coordinate_x', 'coordinate_y'], params): return # not in any game if self.__game is None: self.__send(self.__message_parser.encode('report', {'status': '43'})) return # check if it's actually your turn if self.__lobby_model.get_game(self.__game).get_turn() != self.__player: self.__send(self.__message_parser.encode('report', {'status': '41'})) return # check if coordinates are valid if not ((0 <= int(params['coordinate_x']) <= 15) and (0 <= int(params['coordinate_y']) <= 15)): self.__send(self.__message_parser.encode('report', {'status': '39'})) return # save move _, updated = self.__lobby_model.get_game(self.__game).fire(self.__player, params['coordinate_x'], params['coordinate_y']) logging.debug("Fire: updated is {}.".format(updated)) #if not updated: # self.__send(self.__message_parser.encode('report', {'status': '39'})) # return # successful attack self.__send(self.__message_parser.encode('report', {'status': '22'})) # check if game over self.__lobby_model.get_game(self.__game).check_if_game_over(self.__player) def __nuke(self, params): if not self.__expect_parameter(['coordinate_x', 'coordinate_y'], params): return # check if coordinates are valid if not ((0 <= int(params['coordinate_x']) <= 13) and (0 <= int(params['coordinate_y']) <= 13)): self.__send(self.__message_parser.encode('report', {'status': '32'})) return # not in any game if self.__game is None: self.__send(self.__message_parser.encode('report', {'status': '43'})) return # check if it's actually your turn if self.__lobby_model.get_game(self.__game).get_turn() != self.__player: self.__send(self.__message_parser.encode('report', {'status': '41'})) return # save move updated = self.__lobby_model.get_game(self.__game).nuke(self.__player, params['coordinate_x'], params['coordinate_y']) # special attack failed if updated is False: self.__send(self.__message_parser.encode('report', {'status': '32'})) return logging.debug("Nuke: updated {} fields.".format(len(updated))) #if len(updated) == 0: # self.__send(self.__message_parser.encode('report', {'status': '32'})) # return # successful special attack self.__send(self.__message_parser.encode('report', {'status': '24'})) # check if game over self.__lobby_model.get_game(self.__game).check_if_game_over(self.__player) def __move(self, params): if not self.__expect_parameter(['ship_id', 'direction'], params): return # not in any game if self.__game is None: self.__send(self.__message_parser.encode('report', {'status': '43'})) return # check if it's actually your turn if self.__lobby_model.get_game(self.__game).get_turn() != self.__player: self.__send(self.__message_parser.encode('report', {'status': '41'})) return # save move result = self.__lobby_model.get_game(self.__game).move_ship(self.__player, int(params['ship_id']), params['direction']) if result is False: self.__send(self.__message_parser.encode('report', {'status': '31'})) return # successful move self.__send(self.__message_parser.encode('report', {'status': '21'})) def __surrender(self): # not in any game if self.__game is None: self.__send(self.__message_parser.encode('report', {'status': '43'})) return # make sure the game is ongoing if not self.__lobby_model.get_game(self.__game).is_ongoing(): self.__send(self.__message_parser.encode('report', {'status': '43'})) return # surrender self.__lobby_model.get_game(self.__game).surrender(self.__player) # surrender accepted lol self.__send(self.__message_parser.encode('report', {'status': '23'})) def __begin_turn(self): self.__send(self.__message_parser.encode('report', {'status': '11'})) def __chat(self, params): if not self.__expect_parameter(['text'], params): return self.__lobby_model.chat(self.__id, params['text']) def __unknown_msg(self): self.__send(self.__message_parser.encode('report', {'status': '40'})) def __expect_parameter(self, expected, actual): keys = list(actual.keys()) for p in expected: if p not in keys: self.__unknown_msg() return False return True def __recv(self, count): try: msg = self.__socket.recv(count) except socket.error as e: logging.debug("Client already dead: ".format(repr(e))) return logging.debug(b"Raw in: " + msg) return msg def __send(self, msg): try: self.__socket.sendall(msg) except socket.error as e: logging.debug("Client already dead: ".format(repr(e))) return logging.debug(b"Raw out: " + msg)
class RoverSim(): def __init__(self, roverID, blockInfo): self.roverID = roverID self.blockInfo = blockInfo self.posY = 0 self.nextY = 0 if roverID == 0: self.posX = 0 self.nextX = 0 else: self.posX = -1 self.nextX = -1 # Declare test client and parser self.clientConnection = TestClient() self.parser = MessageParser(roverID) # Connect signals and slots self.clientConnection.messageFromServer.connect(self.parser.parse) self.parser.parsedMessageSignal.connect(self.messageFromServer) self.parser.constructedMessageSignal.connect( self.clientConnection.sendMessageToServer) def ack(self, command): self.parser.constructMessage(commandDefs.flags["COMMAND_RECEIVED"] + ' ' + command) def finish(self, command): time.sleep(0.5) # Pause for command to complete self.parser.constructMessage(commandDefs.flags["COMMAND_FINISHED"] + ' ' + command) def eventAlert(self): self.parser.constructMessage(commandDefs.flags["EVENT_ALERT"]) # Handler for server commands def messageFromServer(self, message): # Acknowledge message self.ack(message) messageFields = message.split(' ') # Compute new position if necessary if messageFields[0] == commandDefs.commands[ "MOVE_COMMAND"] or messageFields[0] == commandDefs.commands[ "PICKUP_COMMAND"]: if messageFields[1] == commandDefs.specifiers["NORTH_MOVE"]: self.nextX = self.posX self.nextY = self.posY + 1 self.executeMove(message) elif messageFields[1] == commandDefs.specifiers["EAST_MOVE"]: self.nextX = self.posX + 1 self.nextY = self.posY self.executeMove(message) elif messageFields[1] == commandDefs.specifiers["SOUTH_MOVE"]: self.nextX = self.posX self.nextY = self.posY - 1 self.executeMove(message) elif messageFields[1] == commandDefs.specifiers["WEST_MOVE"]: self.nextX = self.posX - 1 self.nextY = self.posY self.executeMove(message) # Send reading for a read command elif messageFields[0] == commandDefs.commands["READ_COMMAND"]: self.parser.constructMessage( commandDefs.flags["EVENT_ALERT"] + ' ' + self.blockInfo[8 - self.nextY][self.nextX]) self.finish(message) # Finish any other command else: self.finish(message) def blockAtPos(self, x, y): if self.blockInfo[8 - y][x] != 'N': return self.blockInfo[8 - y][x] else: return None def updatePos(self): self.posX = self.nextX self.posY = self.nextY print("New positiion: ", self.posX, ', ', self.posY) def executeMove(self, message): if self.roverID == 0: if not self.blockAtPos(self.nextX, self.nextY): # if no block is in the way self.updatePos() # update position and finish command self.finish(message) else: # if a block is in the way self.eventAlert() # send an event alert else: self.updatePos() # Moves always succeed for rover1 self.finish(message) def run(self): app = QApplication(sys.argv) self.clientConnection.begin.emit() sys.exit(app.exec())
import socket from channel import Channel from messageparser import MessageParser mp = MessageParser() def serv_log(text): print("[Server] {}".format(text)) def irc_log(t, text): print("[{0}] {1}".format(t, text)) ################### # Server responses# ################### def confirm_reg(conn, data, host): msg = ":{0} 001 {1} :Hi welcome to this IRC server \r\n".format( host, data.nick) conn.send(msg.encode()) irc_log("OUT", msg.strip()) msg = ":{0} 002 {1} :Your host is {0} IRC server made as an assignment \r\n".format( host, data.nick) conn.send(msg.encode()) irc_log("OUT", msg.strip())
class ClientHandler: def __init__(self, sock): self.__socket = sock self.__message_parser = MessageParser() self.__lobby_model = LobbyModel() # name of the game self.__game = None # player number (1 or 2) self.__player = None # player id lol self.__id = self.__get_own_player_id() # add client as player self.__lobby_model.add_player(self.__id) # register callbacks self.__lobby_model.register_callback(LobbyEvent.on_update, self.on_update_lobby) self.__lobby_model.register_callback(LobbyEvent.on_chat, self.on_chat) def handle(self): logging.info("Client {} connected.".format( self.__socket.getpeername())) while True: logging.debug("handle({}) loop.".format( self.__socket.getpeername())) # receive 2 bytes size header size = self.__recv(2) if not size: logging.debug("Did not receive 2 bytes header.") break size = struct.unpack('>H', size)[0] logging.debug("Size: " + str(size)) # receive message body msg = self.__recv(size) if not msg: logging.debug("Did not receive {} bytes body.".format( str(size))) break # explode received data into message type and parameters msgtype, msgparams = self.__message_parser.decode(msg.decode()) logging.debug("Msg type: " + msgtype) logging.debug("Msg parameters: " + repr(msgparams)) # dispatch message type if msgtype == messages.CREATE_GAME: self.__create_game(msgparams) elif msgtype == messages.JOIN_GAME: self.__join_game(msgparams) elif msgtype == messages.SET_NICK: self.__set_nickname(msgparams) elif msgtype == messages.LEAVE_GAME: self.__leave_game() elif msgtype == messages.INIT_BOARD: self.__init_board(msgparams) elif msgtype == messages.FIRE: self.__fire(msgparams) elif msgtype == messages.NUKE: self.__nuke(msgparams) elif msgtype == messages.MOVE: self.__move(msgparams) elif msgtype == messages.SURRENDER: self.__surrender() elif msgtype == messages.CHAT_SEND: self.__chat(msgparams) else: self.__unknown_msg() # # Callbacks # def on_update_lobby(self): logging.debug("on_update_lobby()") # Get required data for update lobby msg number_of_clients = self.__lobby_model.get_number_of_players() number_of_games = self.__lobby_model.get_number_of_games() games_info = self.__lobby_model.get_games_info() players_info = self.__lobby_model.get_players_info() # Update_Lobby data = { 'status': 16, 'number_of_clients': number_of_clients, 'number_of_games': number_of_games[0] } i = 0 weirdkey = 'game_name_{}' moreweirdkeys = 'game_players_count_{}' whatevenisthis = 'game_player_{}_{}' waitwhat = 'player_name_{}' yetanotherkey = 'player_identifier_{}' for game in games_info: # game stuff data[weirdkey.format(i)] = game['game_name'] data[moreweirdkeys.format(i)] = game['number_of_players'] # player 1 stuff data[whatevenisthis.format(i, 0)] = game['ids'][0] # player 2 stuff if game['number_of_players'] == 2: data[whatevenisthis.format(i, 1)] = game['ids'][1] i += 1 i = 0 for player in players_info: # player stuff data[yetanotherkey.format(i)] = player['id'] data[waitwhat.format(i)] = player['nickname'] i += 1 msg = self.__message_parser.encode('report', data) self.__send(msg) def on_game_abort(self): # delete game self.__lobby_model.delete_game(self.__game) self.__game = None self.__send(self.__message_parser.encode('report', {'status': '19'})) def on_game_ended(self, winner, id0, id1, timestamp): msg = { 'status': '17', 'winner': winner - 1, 'name_of_game': self.__game, 'timestamp': timestamp, 'identifier_0': id0, 'identifier_1': id1, 'reason_for_game_end': 'Because of reasons.' } # delete game self.__lobby_model.delete_game(self.__game) self.__game = None self.__send(self.__message_parser.encode('report', msg)) def on_ship_edit(self): logging.debug('on_ship_edit()') self.__send(self.__message_parser.encode('report', {'status': '18'})) def on_game_start(self): logging.debug('on_game_start()') self.__send(self.__message_parser.encode('report', {'status': '48'})) def on_host_begins(self): logging.debug('on_host_begins()') self.__begin_turn() def on_guest_begins(self): logging.debug('on_guest_begins()') self.__begin_turn() def on_attack(self, x, y, condition): logging.debug('on_attack()') msg = None # if player is enemy if self.__lobby_model.get_game( self.__game).get_turn() == self.__player: # update own field msg = { 'status': 13, 'was_special_attack': 'false', 'coordinate_x': x, 'coordinate_y': y } self.__send(self.__message_parser.encode('report', msg)) # trigger next turn wtf self.__begin_turn() else: # update enemy field msg = { 'status': 14, 'number_of_updated_fields': '1', 'field_0_x': x, 'field_0_y': y, 'field_0_condition': condition } self.__send(self.__message_parser.encode('report', msg)) def on_special_attack(self, x, y, updates): logging.debug('on_special_attack()') msg = None if self.__lobby_model.get_game( self.__game).get_turn() == self.__player: # update own field msg = { 'status': 13, 'was_special_attack': 'true', 'coordinate_x': x, 'coordinate_y': y } self.__send(self.__message_parser.encode('report', msg)) # trigger next turn wtf self.__begin_turn() else: # update enemy field msg = {'status': 14, 'number_of_updated_fields': len(updates)} i = 0 for j in updates: msg['field_{}_x'.format(i)] = j['field'].x msg['field_{}_y'.format(i)] = j['field'].y msg['field_{}_condition'.format(i)] = j['status'] i += 1 self.__send(self.__message_parser.encode('report', msg)) def on_move(self, updates): logging.debug('on_move()') msg = None if self.__lobby_model.get_game( self.__game).get_turn() == self.__player: # update enemy field if len(updates) > 0: msg = {'status': 14, 'number_of_updated_fields': len(updates)} i = 0 for j in updates: msg['field_{}_x'.format(i)] = j['field'].x msg['field_{}_y'.format(i)] = j['field'].y msg['field_{}_condition'.format(i)] = j['status'] i += 1 self.__send(self.__message_parser.encode('report', msg)) # trigger next turn wtf self.__begin_turn() def on_chat(self, timestamp, player, msg): logging.debug('on_chat()') msg = { 'status': '15', 'author_id': player, 'timestamp': timestamp, 'message_content': msg } self.__send(self.__message_parser.encode('report', msg)) def get_socket(self): return self.__socket def finish(self): logging.info("Client disconnected.") # remove any left callbacks self.__lobby_model.remove_callback(LobbyEvent.on_update, self.on_update_lobby) self.__lobby_model.remove_callback(LobbyEvent.on_chat, self.on_chat) # end running game if any if self.__game and self.__lobby_model.get_game( self.__game) is not None: # remove callbacks of disconnected player self.__lobby_model.get_game(self.__game).remove_callback( GameEvent.on_ship_edit, self.on_ship_edit) self.__lobby_model.get_game(self.__game).remove_callback( GameEvent.on_game_start, self.on_game_start) self.__lobby_model.get_game(self.__game).remove_callback( GameEvent.on_attack, self.on_attack) self.__lobby_model.get_game(self.__game).remove_callback( GameEvent.on_special_attack, self.on_special_attack) self.__lobby_model.get_game(self.__game).remove_callback( GameEvent.on_move, self.on_move) #self.__lobby_model.get_game(self.__game).remove_callback(GameEvent.on_host_begins, self.on_host_begins) #self.__lobby_model.get_game(self.__game).remove_callback(GameEvent.on_guest_begins, self.on_guest_begins) self.__lobby_model.get_game(self.__game).remove_callback( GameEvent.on_game_ended, self.on_game_ended) self.__lobby_model.get_game(self.__game).remove_callback( GameEvent.on_game_abort, self.on_game_abort) # surrender if self.__lobby_model.get_game(self.__game).is_ongoing(): logging.debug("Surrender by disconnect.") self.__lobby_model.get_game(self.__game).surrender( self.__player) # abort elif self.__lobby_model.get_game(self.__game).is_ready(): logging.debug("Abort by disconnect.") self.__lobby_model.get_game(self.__game).abort() # remove player from lobby self.__lobby_model.delete_player(self.__id) def __create_game(self, params): # make sure parameter list is complete if not self.__expect_parameter(['name'], params): return # check if client is already in a game if self.__game: logging.debug("Client already in some game.") # 31 is the new 42 self.__send( self.__message_parser.encode('report', {'status': '31'})) return # check game name length if 1 > len(params['name']) or len(params['name']) > 64: logging.debug("Game name too long.") self.__send( self.__message_parser.encode('report', {'status': '37'})) return # create the game game = self.__lobby_model.add_lobby(params['name'], self.__id) if not game: self.__send( self.__message_parser.encode('report', {'status': '37'})) return self.__game = params['name'] self.__player = 1 self.__send(self.__message_parser.encode('report', {'status': '28'})) # register game callbacks self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_ship_edit, self.on_ship_edit) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_game_start, self.on_game_start) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_attack, self.on_attack) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_special_attack, self.on_special_attack) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_move, self.on_move) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_host_begins, self.on_host_begins) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_game_ended, self.on_game_ended) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_game_abort, self.on_game_abort) def __join_game(self, params): # make sure parameter list is complete if not self.__expect_parameter(['name'], params): return # check if client is already in a game if self.__game: logging.debug("Client already in some game.") self.__send( self.__message_parser.encode('report', {'status': '31'})) return # join the game game, e = self.__lobby_model.join_lobby(params['name'], self.__id) # handle game join errors if e: if e == LobbyError.game_is_full: self.__send( self.__message_parser.encode('report', {'status': '47'})) return elif e == LobbyError.game_does_not_exist: self.__send( self.__message_parser.encode('report', {'status': '37'})) return # ack game join self.__send(self.__message_parser.encode('report', {'status': '27'})) self.__game = params['name'] self.__player = 2 # register game callbacks self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_ship_edit, self.on_ship_edit) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_game_start, self.on_game_start) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_attack, self.on_attack) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_special_attack, self.on_special_attack) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_move, self.on_move) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_guest_begins, self.on_guest_begins) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_game_ended, self.on_game_ended) self.__lobby_model.get_game(self.__game).register_callback( GameEvent.on_game_abort, self.on_game_abort) self.__lobby_model.get_game( self.__game).just_begin_ship_placement_already() def __set_nickname(self, params): if not self.__expect_parameter(['name'], params): return if len(params['name']) > 64: logging.debug("Nickname too long.") self.__send( self.__message_parser.encode('report', {'status': '36'})) return # tell lobby to set nickname and hope for the best self.__lobby_model.set_nickname(self.__id, params['name']) def __get_own_player_id(self): addr, port = self.__socket.getpeername() playerid = hashlib.sha1(b(addr + str(port))).hexdigest() return playerid def __init_board(self, params): logging.debug('__init_board()') # not in any game if self.__game is None: self.__send( self.__message_parser.encode('report', {'status': '43'})) return shipx = 'ship_{}_x' shipy = 'ship_{}_y' shipdir = 'ship_{}_direction' # make sure that all parameters exist if not self.__expect_parameter( [shipx.format(i) for i in range(0, 10)] + [shipy.format(i) for i in range(0, 10)] + [shipdir.format(i) for i in range(0, 10)], params): return # init board left = True for id in range(0, 10): x = int(params[shipx.format(id)]) y = int(params[shipy.format(id)]) dir = params[shipdir.format(id)] logging.debug('self.__lobby_model :: {}'.format( repr(self.__lobby_model))) logging.debug( 'self.__lobby_model.get_game(self.__game) :: {}'.format( repr(self.__lobby_model.get_game(self.__game)))) logging.debug('self.__game :: {}'.format(repr(self.__game))) suc, left = self.__lobby_model.get_game(self.__game).place_ship( self.__player, x, y, dir, id) # catch illegal placement if suc == -1: logging.debug("Nonsense ship placement.") self.__send( self.__message_parser.encode('report', {'status': '38'})) return if left: logging.debug("Something is still wrong with ship placement.") self.__send( self.__message_parser.encode('report', {'status': '38'})) return # ack init board self.__send(self.__message_parser.encode('report', {'status': '29'})) # trigger random begin return message self.__lobby_model.get_game(self.__game).start() def __leave_game(self): # not in any game if self.__game is None: self.__send( self.__message_parser.encode('report', {'status': '43'})) return # make sure the game has not started yet if self.__lobby_model.get_game(self.__game).is_ongoing(): self.__send( self.__message_parser.encode('report', {'status': '43'})) logging.debug("Too late to leave the game.") return # abort self.__lobby_model.get_game(self.__game).abort() def __fire(self, params): if not self.__expect_parameter(['coordinate_x', 'coordinate_y'], params): return # not in any game if self.__game is None: self.__send( self.__message_parser.encode('report', {'status': '43'})) return # check if it's actually your turn if self.__lobby_model.get_game( self.__game).get_turn() != self.__player: self.__send( self.__message_parser.encode('report', {'status': '41'})) return # check if coordinates are valid if not ((0 <= int(params['coordinate_x']) <= 15) and (0 <= int(params['coordinate_y']) <= 15)): self.__send( self.__message_parser.encode('report', {'status': '39'})) return # save move _, updated = self.__lobby_model.get_game(self.__game).fire( self.__player, params['coordinate_x'], params['coordinate_y']) logging.debug("Fire: updated is {}.".format(updated)) #if not updated: # self.__send(self.__message_parser.encode('report', {'status': '39'})) # return # successful attack self.__send(self.__message_parser.encode('report', {'status': '22'})) # check if game over self.__lobby_model.get_game(self.__game).check_if_game_over( self.__player) def __nuke(self, params): if not self.__expect_parameter(['coordinate_x', 'coordinate_y'], params): return # check if coordinates are valid if not ((0 <= int(params['coordinate_x']) <= 13) and (0 <= int(params['coordinate_y']) <= 13)): self.__send( self.__message_parser.encode('report', {'status': '32'})) return # not in any game if self.__game is None: self.__send( self.__message_parser.encode('report', {'status': '43'})) return # check if it's actually your turn if self.__lobby_model.get_game( self.__game).get_turn() != self.__player: self.__send( self.__message_parser.encode('report', {'status': '41'})) return # save move updated = self.__lobby_model.get_game(self.__game).nuke( self.__player, params['coordinate_x'], params['coordinate_y']) # special attack failed if updated is False: self.__send( self.__message_parser.encode('report', {'status': '32'})) return logging.debug("Nuke: updated {} fields.".format(len(updated))) #if len(updated) == 0: # self.__send(self.__message_parser.encode('report', {'status': '32'})) # return # successful special attack self.__send(self.__message_parser.encode('report', {'status': '24'})) # check if game over self.__lobby_model.get_game(self.__game).check_if_game_over( self.__player) def __move(self, params): if not self.__expect_parameter(['ship_id', 'direction'], params): return # not in any game if self.__game is None: self.__send( self.__message_parser.encode('report', {'status': '43'})) return # check if it's actually your turn if self.__lobby_model.get_game( self.__game).get_turn() != self.__player: self.__send( self.__message_parser.encode('report', {'status': '41'})) return # save move result = self.__lobby_model.get_game(self.__game).move_ship( self.__player, int(params['ship_id']), params['direction']) if result is False: self.__send( self.__message_parser.encode('report', {'status': '31'})) return # successful move self.__send(self.__message_parser.encode('report', {'status': '21'})) def __surrender(self): # not in any game if self.__game is None: self.__send( self.__message_parser.encode('report', {'status': '43'})) return # make sure the game is ongoing if not self.__lobby_model.get_game(self.__game).is_ongoing(): self.__send( self.__message_parser.encode('report', {'status': '43'})) return # surrender self.__lobby_model.get_game(self.__game).surrender(self.__player) # surrender accepted lol self.__send(self.__message_parser.encode('report', {'status': '23'})) def __begin_turn(self): self.__send(self.__message_parser.encode('report', {'status': '11'})) def __chat(self, params): if not self.__expect_parameter(['text'], params): return self.__lobby_model.chat(self.__id, params['text']) def __unknown_msg(self): self.__send(self.__message_parser.encode('report', {'status': '40'})) def __expect_parameter(self, expected, actual): keys = list(actual.keys()) for p in expected: if p not in keys: self.__unknown_msg() return False return True def __recv(self, count): try: msg = self.__socket.recv(count) except socket.error as e: logging.debug("Client already dead: ".format(repr(e))) return logging.debug(b"Raw in: " + msg) return msg def __send(self, msg): try: self.__socket.sendall(msg) except socket.error as e: logging.debug("Client already dead: ".format(repr(e))) return logging.debug(b"Raw out: " + msg)
class GameState(object): def __init__(self, message): self.message_parser = MessageParser(message) # hole, [['2c', '2d'],...] for 6 players self.hole = self.message_parser.hole # board ['2c', '2d', '2h', ...] for at most 5 board cards self.board = self.message_parser.board self.viewing_player = self.message_parser.get_position() self.betting_string = self.message_parser.get_betting_string(rd=None) self.board_string = self.message_parser.get_board_string(rd=None) # a two-dimension list, dim-1 is round, dim-2 is i-th action of a round self.betting_action = self.get_betting_action() # a one-dimension list, store each {action string} as an element self.action_list = [] # store each {action object} of all round actions in a one-dimension list for each_round_action in self.betting_action: for action in each_round_action: self.action_list.append(Action(action)) # set up basic data structure self.spent = [50, 100, 0, 0, 0, 0] self.active = [True] * 6 self.fold = [False] * 6 self.allin = [False] * 6 self.pot = 150 self.max_bet = 100 self.current_player = 2 # player at seat 2 is first player to act in PREFLOP round self.finished = False self.round = Round.PREFLOP self.boards = None # first round have no board cards self.holes = None # hole array for 6 players self.min_no_limit_raise_to = 2 * 100 self.max_no_limit_raise_to = 20000 self.next_round_flag = False self.call_number = 0 # update [hole] and [board] self.holes = self.message_parser.get_hole_card(position=None) self.boards = self.message_parser.get_board_card(rd=None) # after setting up basic data structure, start to do each action and update data structure cnt = 0 for action in self.action_list: cnt += 1 self.do_action(action) def do_action(self, action): # [1.0] do action, update player [spent] and [active] if action.type == ActionType.CALL: self.spent[self.current_player] = self.max_bet self.call_number += 1 # if current player called ALLIN action -> not active if self.max_bet == 20000: self.active[self.current_player] = False self.allin[self.current_player] = True #if current player folded -> not active elif action.type == ActionType.FOLD: self.active[self.current_player] = False self.fold[self.current_player] = True else: # must be a raise action self.call_number = 1 # a raise action happened, min_no_limit_raise_to need to be updated if action.amount + action.amount - max( self.spent) > self.min_no_limit_raise_to: self.min_no_limit_raise_to = action.amount + action.amount - max( self.spent) # make sure it <= 20000 self.min_no_limit_raise_to = min( [self.min_no_limit_raise_to, 20000]) # update {max_bet} self.max_bet = action.amount self.spent[self.current_player] = action.amount # if current player raised to stack size -> not active if action.amount == 20000: self.active[self.current_player] = False self.allin[self.current_player] = True # if all players choose all in, then game ends, which no active players if self.active.count(True) == 0: self.finished = True return # [3.0] if all active player spent same amount, which means they are reaching next round amount_set = set() for p, amount in zip(self.active, self.spent): if p: amount_set.add(amount) next_round_reaching_flag = len( amount_set) == 1 and self.call_number == self.fold.count(False) self.next_round_flag = next_round_reaching_flag if next_round_reaching_flag: # reset call number self.call_number = 0 # we are going to reach next round # if current round == 4, then there is no more next round and the game ends here if self.round == Round.RIVER: self.finished = True # there are next round else: # update round self.round += 1 # update min_no_limit_raise_to self.min_no_limit_raise_to += self.max_bet self.min_no_limit_raise_to = min( [self.min_no_limit_raise_to, 20000]) # find next active player from seat 0 next_player = 0 while not self.active[next_player]: next_player = (next_player + 1) % 6 self.current_player = next_player else: # we are still at current round # update {current player}, find next active player # if more than one active player left, find next active player if self.active.count(True) > 1: # game is not finished yet # find next active player next_player = (self.current_player + 1) % 6 while not self.active[next_player]: next_player = (next_player + 1) % 6 self.current_player = next_player elif self.active.count(True) == 1: # game may finish now # if there is no all-in player, which means other players all folded, only one player left if self.allin.count(True) == 0: # game ends self.finished = True # else, there are all-in player, the only one player who is active is the next current player else: self.current_player = self.active.index(True) else: # active player number is 0, which means they are at least one player all-in, the rest are folded # game is finished self.finished = True # split betting string into single betting actions # if rd=None, by default, handle betting string of all rounds def get_betting_action(self, rd=None): pattern = re.compile(r'r\d+|f|c') if rd is not None: string = self.betting_string[rd] current_round_action = [] # parse string into sigle action string for m in pattern.finditer(string): current_round_action.append(m.group()) return current_round_action else: betting_action = [] for string in self.betting_string: # parse string into single action string current_round_action = [] for m in pattern.finditer(string): current_round_action.append(m.group()) betting_action.append(current_round_action) return betting_action # who just did an action def get_current_player(self): return self.current_player # return active player # a list containing True/False def get_active_player(self): return self.active def get_active_player_number(self): return self.active.count(True) def get_max_bet(self): return self.max_bet def get_min_bet(self): return self.min_bet def get_pot(self): return sum(self.pot) def get_next_valid_raise_size(self): return [self.min_no_limit_raise_to, self.max_no_limit_raise_to] def is_my_turn(self): return self.viewing_player == self.current_player
class ServerConnection(object): """ Class handling irc servers. """ PING_INTERVAL_THRESHOLD = 300 # 300 seconds def __init__(self, networkname, server_config, bot_config, joinlist, modules_config): self.alive = True self.connected = False self.hostname = server_config['hostname'] self.port = int(server_config.get('port', "6667")) self.nick = bot_config['nick'] self.altnick = bot_config.get('altnick', self.nick + "_") self.username = bot_config['username'] self.realname = bot_config['realname'] self.owner = bot_config['owner'] self.networkname = networkname self.joinlist = joinlist self._reader_thread = None self._parser = MessageParser() self._init_callback_table() self._socket = None self._channel_list = [] self._modules_config = modules_config self.dynamic_modules = [DynamicModule(self, m, c) for m, c in modules_config.items()] self._last_ping = time.time() def _init_callback_table(self): self._receive_callbacks = { MessageType.PRIVATE_MESSAGE: self._private_message_received, MessageType.JOIN: self._join_received, MessageType.PART: self._part_received, MessageType.PING: self._ping_received, MessageType.QUIT: self._quit_received, MessageType.TOPIC: self._topic_received, MessageType.END_OF_MOTD: self._motd_received, #MessageType.NICK_IN_USE: self.ni, MessageType.TOPIC_REPLY: self._topic_reply_received, MessageType.USERS: self._users_received, MessageType.END_OF_USERS: self._users_end_received, MessageType.CHANNEL_MESSAGE: self._channel_message_received, MessageType.UNKNOWN: self._unknown_message_received, MessageType.CTCP_TIME: self._ctcp_message_received, MessageType.CTCP_VERSION: self._ctcp_version_received, MessageType.CTCP_PING: self._ctcp_message_received, MessageType.CTCP_DCC: self._ctcp_message_received, } def connect(self): """ Tries to connect to irc server. """ self._reader_thread = Thread(target=self._connection_loop) self._reader_thread.start() def _connect(self): while self.alive: try: if self._socket: self._socket.close() self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._socket.connect((self.hostname, self.port)) self.NICK(self.nick) self.USER(self.username, self.realname) self._last_ping = time.time() break except Exception as e: self._print_line(str(e) + " " + self.hostname) self._print_line("Trying again in 30 seconds.") self._sleep(30) def _connection_loop(self): while self.alive: self._connect() self._read() if not self.alive: break self._print_line("Trying again in 60 seconds.") self._sleep(60) def _write(self, message): """ Prints and writes message to server. """ self._print_line(message[:-1]) self._socket.send(bytearray(message, 'utf-8')) def _check_ping_time(self): return time.time() - self._last_ping < ServerConnection.PING_INTERVAL_THRESHOLD def _read(self): """ Reads and handles messages. """ self._socket.settimeout(1.0) buff = "" while self.alive and self._check_ping_time(): try: tmp = self._socket.recv(4096) except socket.timeout as e: continue except socket.error as e: self._print_line(str(e)) break except KeyboardInterrupt: self.kill() return if not self.alive: break if not tmp: break tmp = tmp.decode('utf-8') buff += tmp parsed_messages, remainder = self._parser.parse_buffer(buff) buff = remainder self._handle_messages(parsed_messages) self._socket.close() self._print_line("Connection closed.") self.connected = False def _handle_messages(self, messages): """ Handles a list of messages """ for message in messages: self._receive_callbacks[message.type](**message.params) def _print_line(self, message): """ Prints message with timestamp. """ print(time.strftime("%H:%M:%S") + " |" + self.networkname + "| " + message) def NICK(self, nick): """ Sets user's nick on server. """ self._write("NICK " + nick + "\r\n") def USER(self, username, realname): """ Sets username and realname to server on connect. """ self._write("USER " + username + " 0 * :" + realname + "\r\n") def PONG(self, message): """ Reply to PING. """ self._write("PONG :" + message + "\r\n") def JOIN(self, channel): """ Joins a irc channel. """ self._write("JOIN :" + channel + "\r\n") def PART(self, channel, reason=""): """ PARTs from a channel. """ msg = "PART " + channel if reason: msg += " :" + reason self._write(msg + "\r\n") def PRIVMSG(self, target, message): """ Sends PRIVMSG to target. """ self._write("PRIVMSG " + target + " :" + message + "\r\n") def PING(self, message): """ Sends PING to server. """ self._write("PING " + message + "\r\n") def CTCP(self, target, message): self.PRIVMSG(target, str("\x01" + message + "\x01")) def NOTICE(self, target, message): self._write("NOTICE " + target + " :" + message + "\r\n") def _on_connect(self): """ Called when connected to the network. """ self.PING(self.hostname) self._join_channels() for dm in self.dynamic_modules: try: dm.instance.on_connect() except Exception as e: print(e) def _join_channels(self): """ Joins channels specified in self.joinlist """ for channel in self.joinlist: self.JOIN(channel) def kill(self): """ Called when the thread is wanted dead. """ self.alive = False for m in self.dynamic_modules: m.instance.kill() def _private_message_received(self, **kw): """ Called when a private message has been received. Prints it and calls on_private_message() on DynamicModule instances. """ source = kw['source'] message = kw['message'] full_mask = kw['full_mask'] self._print_line("PRIVATE" + " <" + source + "> " + message) for dm in self.dynamic_modules: try: dm.instance.on_private_message(source, message, full_mask) except Exception as e: print(e) def _channel_message_received(self, **kw): """ Called when a PRIVMSG to a channel has been received. Prints it and calls on_channel_message() on DynamicModule instances. """ source = kw['source'] message = kw['message'] full_mask = kw['full_mask'] channel = kw['channel_name'] self._print_line(channel + " <" + source + "> " + message) for dm in self.dynamic_modules: try: dm.instance.on_channel_message(source, channel, message, full_mask) except Exception as e: print(e) def _ping_received(self, **kw): """ Called when PING message has been received. """ self._last_ping = time.time() message = kw['message'] self.PONG(message) def _motd_received(self, **kw): """ Called when the end of MOTD message has been received. """ message = kw['message'] self._print_line(message) if not self.connected: self.connected = True self._on_connect() def _find_channel_by_name(self, channel_name): """ Returns a channel instance from channel_list matching channel_name parameter or None. """ for channel in self._channel_list: if channel.name == channel_name: return channel def _add_channel(self, name, user_list): """ Adds a channel to networks channel list. """ if self._find_channel_by_name(name): return channel = IrcChannel(name, user_list) self._channel_list.append(channel) def _users_received(self, **kw): """ Called when USERS message is received. Notifies channel instance of the users. """ channel_name = kw['channel_name'] user_list = kw['user_list'] channel = self._find_channel_by_name(channel_name) if not channel: self._add_channel(channel_name, user_list) return channel.users_message(user_list) def _users_end_received(self, **kw): """ Called when USERS message's end has been received. Notifies the channel instance. """ channel_name = kw['channel_name'] channel = self._find_channel_by_name(channel_name) if not channel: # TODO FIX self._print_line("REPORT THIS: usersEndReceived, channel not found") return channel.users_message_end() self._print_line("USERS OF " + channel_name) self._print_line(" ".join(channel.userlist)) def _quit_received(self, **kw): """ Called when a QUIT message has been received. Calls on_quit() on DynamicModules """ nick = kw['nick'] full_mask = kw['full_mask'] for channel in self._channel_list: channel.remove_user(nick) self._print_line(nick + " has quit.") for dm in self.dynamic_modules: try: dm.instance.on_quit(nick, full_mask) except Exception as e: print(e) def _part_received(self, **kw): """ Called when a PART message has been received. Calls on_part() on DynamicModules """ nick = kw['nick'] channel_name = kw['channel_name'] full_mask = kw['full_mask'] channel = self._find_channel_by_name(channel_name) if not channel: return channel.remove_user(nick) self._print_line(nick + " has parted " + channel_name) for dm in self.dynamic_modules: try: dm.instance.on_part(nick, channel_name, full_mask) except Exception as e: print(e) def _join_received(self, **kw): """ Called when a JOIN message has been received. Calls on_join() on DynamicModules """ nick = kw['nick'] channel_name = kw['channel_name'] full_mask = kw['full_mask'] channel = self._find_channel_by_name(channel_name) if channel: channel.add_user(nick) self._print_line(nick + " has joined " + channel_name) for dm in self.dynamic_modules: try: dm.instance.on_join(nick, channel_name, full_mask) except Exception as e: print(e) def _topic_received(self, **kw): """ Called when topic is changed on a channel. Calls on_topic() on DynamicModules """ nick = kw['nick'] channel_name = kw['channel_name'] full_mask = kw['full_mask'] topic = kw['topic'] channel = self._find_channel_by_name(channel_name) if channel: channel.topic = topic self._print_line(nick + " changed the topic of " + channel_name + " to: " + topic) for dm in self.dynamic_modules: try: dm.instance.on_topic(nick, channel_name, topic, full_mask) except Exception as e: print(e) def _topic_reply_received(self, **kw): """ Called when server responds to client's /topic or server informs of the topic on joined channel. """ channel_name = kw['channel_name'] topic = kw['topic'] channel = self._find_channel_by_name(channel_name) if channel: channel.topic = topic self._print_line("Topic in " + channel_name + ": " + topic) def _ctcp_message_received(self, **kw): self._print_line("CTCP: " + str(kw)) def _ctcp_version_received(self, **kw): ":[email protected] NOTICE irckaaja :VERSION ?l? hakkeroi!" self.NOTICE(kw['source'], "\x01VERSION irckaaja 0.1.0\x01") def _unknown_message_received(self, **kw): self._print_line(kw['message']) def _sleep(self, seconds): """ Sleeps for seconds unless not self.alive. """ start = time.time() while time.time() < start + seconds and self.alive: time.sleep(1)
import json, sys, socket, time sys.path.insert(0, './lib') from irccontroller import SlackIRCController from messageparser import MessageParser with open('config.json', 'r') as cfg: config = json.load(cfg) slackbot = SlackIRCController(server=config['irc']['host'], port=config['irc']['port'], channel=config['irc']['channel'], master=config['master'], parser=MessageParser(config=config), username=config['irc']['username'], password=config['irc']['password']) # Runs the bot and handles/retries on connection errors, # implementing an exponential backoff up to 256 seconds. def retryLoop(func, sec): try: func() except socket.error: sec = sec + 1 if sec < 8 else 1 print 'Connection error, retrying in ' + str(2**sec) + ' seconds...' time.sleep(2**sec) retryLoop(func, sec) retryLoop(slackbot.run, 0)