def __init__(self, resolution, host, port, username, password, split="\n"): global network_log self.log = Log('client') network_log = Log('network') # must have at least one handler self.log.logger.addHandler(logging.NullHandler()) network_log.logger.addHandler(logging.NullHandler()) # opengl must be initialized first self.log.info("Initializing display (windowed at %(resolution)s)", dict(resolution='%dx%d' % resolution)) self._screen = pygame.display.set_mode(resolution, OPENGL | DOUBLEBUF) pygame.display.set_caption('yamosg') self.log.debug( "OpenGL setup (version=\"%(version)s\", vendor=\"%(vendor)s\")", dict(version=glGetString(GL_VERSION), vendor=glGetString(GL_VENDOR))) setup_opengl() Client.cursor_default = pygame.cursors.arrow Client.cursor_capture = pygame.cursors.diamond self._resolution = Vector2i(resolution) self._username = username self._password = password self._split = split self._running = False self._state = StateManager() self._game = GameWidget(self, self._resolution) self._container = Composite(Vector2i(0, 0), self._resolution, children=[self._game]) self._toolbar = Toolbar(self._game) self._window = VBox() self._window.add(self._toolbar, size=LayoutAttachment(Vector2i(1, 0), Vector2i(0, 25))) self._window.add(self._container) self._state.push(GameState(self._resolution, self._window)) self._network = Network(self, host, port) self._command_store = {} self._command_queue = [] self._command_lock = threading.Lock() self._playerid = None self._players = {} self._capture_position = None self._timer = 0 # resizing must be done after state has been created so the event is propagated proper. self._resize(self._resolution)
def __init__(self, resolution, host, port, username, password, split="\n"): global network_log self.log = Log('client') network_log = Log('network') # must have at least one handler self.log.logger.addHandler(logging.NullHandler()) network_log.logger.addHandler(logging.NullHandler()) # opengl must be initialized first self.log.info("Initializing display (windowed at %(resolution)s)", dict(resolution='%dx%d'%resolution)) self._screen = pygame.display.set_mode(resolution, OPENGL|DOUBLEBUF) pygame.display.set_caption('yamosg') self.log.debug("OpenGL setup (version=\"%(version)s\", vendor=\"%(vendor)s\")", dict(version=glGetString(GL_VERSION), vendor=glGetString(GL_VENDOR))) setup_opengl() Client.cursor_default = pygame.cursors.arrow Client.cursor_capture = pygame.cursors.diamond self._resolution = Vector2i(resolution) self._username = username self._password = password self._split = split self._running = False self._state = StateManager() self._game = GameWidget(self, self._resolution) self._container = Composite(Vector2i(0,0), self._resolution, children=[self._game]) self._toolbar = Toolbar(self._game) self._window = VBox() self._window.add(self._toolbar, size=LayoutAttachment(Vector2i(1,0), Vector2i(0,25))) self._window.add(self._container) self._state.push(GameState(self._resolution, self._window)) self._network = Network(self, host, port) self._command_store = {} self._command_queue = [] self._command_lock = threading.Lock() self._playerid = None self._players = {} self._capture_position = None self._timer = 0 # resizing must be done after state has been created so the event is propagated proper. self._resize(self._resolution)
class Client: cursor_default = None cursor_capture = None def __init__(self, resolution, host, port, username, password, split="\n"): global network_log self.log = Log('client') network_log = Log('network') # must have at least one handler self.log.logger.addHandler(logging.NullHandler()) network_log.logger.addHandler(logging.NullHandler()) # opengl must be initialized first self.log.info("Initializing display (windowed at %(resolution)s)", dict(resolution='%dx%d' % resolution)) self._screen = pygame.display.set_mode(resolution, OPENGL | DOUBLEBUF) pygame.display.set_caption('yamosg') self.log.debug( "OpenGL setup (version=\"%(version)s\", vendor=\"%(vendor)s\")", dict(version=glGetString(GL_VERSION), vendor=glGetString(GL_VENDOR))) setup_opengl() Client.cursor_default = pygame.cursors.arrow Client.cursor_capture = pygame.cursors.diamond self._resolution = Vector2i(resolution) self._username = username self._password = password self._split = split self._running = False self._state = StateManager() self._game = GameWidget(self, self._resolution) self._container = Composite(Vector2i(0, 0), self._resolution, children=[self._game]) self._toolbar = Toolbar(self._game) self._window = VBox() self._window.add(self._toolbar, size=LayoutAttachment(Vector2i(1, 0), Vector2i(0, 25))) self._window.add(self._container) self._state.push(GameState(self._resolution, self._window)) self._network = Network(self, host, port) self._command_store = {} self._command_queue = [] self._command_lock = threading.Lock() self._playerid = None self._players = {} self._capture_position = None self._timer = 0 # resizing must be done after state has been created so the event is propagated proper. self._resize(self._resolution) def add_window(self, win): self._container.add(win) @event(pygame.QUIT) def quit(self, event=None): self._running = False def is_running(self): return self._running def resolution(self): return self._resolution def run(self): self._running = True self._network.start() while self._running: try: self._flush_queue() self._logic() self._render() except GLError: traceback.print_exc() self.quit() except: traceback.print_exc() @event(pygame.VIDEORESIZE, lambda event: Vector2i(event.w, event.h)) def _resize(self, resolution): self.log.debug("Resolution changed to %dx%d", resolution.x, resolution.y) #self._screen = pygame.display.set_mode(resolution.xy(), OPENGL|DOUBLEBUF|RESIZABLE) setup_opengl() self._resolution = resolution glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(0, resolution.x, 0, resolution.y, -1.0, 1.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() self._state.resize(resolution) self._game.on_resize(resolution, True) def _flush_queue(self): while True: self._command_lock.acquire() if len(self._command_queue) == 0: self._command_lock.release() break command, args = self._command_queue.pop(0) self._command_lock.release() try: self._dispatch(command, args) except: traceback.print_exc() def _logic(self): global event_table for event in pygame.event.get(): func, adapter = event_table.get(event.type, (None, None)) if func is None: continue func(self, adapter(event)) t = time() if t - self._timer > 1.0: self._toolbar.invalidate() self._timer = t @event(pygame.MOUSEMOTION) def _mousemotion(self, event): pos = Vector2i(event.pos) pos.y = self._resolution.y - pos.y self._state.on_mousemove(pos) @event(pygame.MOUSEBUTTONDOWN) def _mousebuttondown(self, event): pos = Vector2i(event.pos) pos.y = self._resolution.y - pos.y if self._capture_position is not None: if event.button == 1: callback, args, kwargs = self._capture_position try: callback(pos, *args, **kwargs) except: traceback.print_exc() self._capture_position = None pygame.mouse.set_cursor(*Client.cursor_default) return self._state.on_buttondown(pos, event.button) @event(pygame.MOUSEBUTTONUP) def _mousebuttonup(self, event): pos = Vector2i(event.pos) pos.y = self._resolution.y - pos.y self._state.on_buttonup(pos, event.button) def _render(self): glClearColor(1, 0, 0, 0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) self._state.render() pygame.display.flip() def _dispatch(self, cmd, args): """ Run command """ global network_log network_log.debug('got %s(%s)', cmd, ', '.join([str(x) for x in args])) try: # Try to get function func = getattr(self, cmd) # See if it is exposed, so a malicious cannot run any func. if not getattr(func, 'exposed'): raise AttributeError # raised to get same handling as a non-existing func. except AttributeError: print 'Malformed or bad command:', cmd, args return except: print 'Unhandled exception when running command:', cmd, args traceback.print_exc() return func(*args) def push_command(self, line): # Run from network thread try: self._command_lock.acquire() tokens = parse_tokens(line) id = tokens[0] if id == 'UNICAST' or id == 'BROADCAST': id, command, args = parse(line) self._command_queue.append((command, args)) elif id in self._command_store: status = tokens[1] args = tuple(tokens[2:]) data = line[len(id) + len(status) + 2:] self._command_store[id].reply(status, args, data) else: raise RuntimeError, 'Got a reply for ID ' + id + ' but no matching request' except: traceback.print_exc() finally: self._command_lock.release() def call(self, command, *args): """ Synchronously call and get reply """ cmd = Command(command, *args) # send command with self._command_lock: self._command_store[cmd.id] = cmd self._network.send(str(cmd) + self._split) # await reply reply = cmd.wait() # delete command with self._command_lock: del self._command_store[cmd.id] return reply @server_call('LIST_OF_ENTITIES', decode=True) def list_of_entities(self, descriptions): self._game.set_entities([Entity(**x) for x in descriptions]) @expose def NEWENT(self, data): decoded = json.loads(data) self._game.add_entity(Entity(**decoded)) @server_call('ENTINFO', 'id', decode=True) def entity_info(self, info): return info @server_call('ENTACTION', 'id', 'action', decode=True) def entity_action(self, info): return info @server_call('PLAYERINFO', 'id', decode=True) def playerinfo(self, info): self._toolbar.set_cash(info['cash']) @expose def CASH(self, amount): self._toolbar.set_cash(int(amount)) @server_call('LOGIN', 'username', 'password', decode=True) def login(self, info): self.playerid = info['id'] self.log.debug('player id is %s', self.playerid) self.playerinfo(self.playerid) @server_call('PLAYERS', decode=True) def players(self, players): return players def player_by_id(self, id): return self._players.get(unicode(id), None) @expose def Hello(self): self.call('SET', 'ENCODER', 'json') try: self.login(username=self._username, password=self._password) except RuntimeError, e: self.log.error(e) self.quit() return self._players = self.players() self.list_of_entities()
class Client: cursor_default = None cursor_capture = None def __init__(self, resolution, host, port, username, password, split="\n"): global network_log self.log = Log('client') network_log = Log('network') # must have at least one handler self.log.logger.addHandler(logging.NullHandler()) network_log.logger.addHandler(logging.NullHandler()) # opengl must be initialized first self.log.info("Initializing display (windowed at %(resolution)s)", dict(resolution='%dx%d'%resolution)) self._screen = pygame.display.set_mode(resolution, OPENGL|DOUBLEBUF) pygame.display.set_caption('yamosg') self.log.debug("OpenGL setup (version=\"%(version)s\", vendor=\"%(vendor)s\")", dict(version=glGetString(GL_VERSION), vendor=glGetString(GL_VENDOR))) setup_opengl() Client.cursor_default = pygame.cursors.arrow Client.cursor_capture = pygame.cursors.diamond self._resolution = Vector2i(resolution) self._username = username self._password = password self._split = split self._running = False self._state = StateManager() self._game = GameWidget(self, self._resolution) self._container = Composite(Vector2i(0,0), self._resolution, children=[self._game]) self._toolbar = Toolbar(self._game) self._window = VBox() self._window.add(self._toolbar, size=LayoutAttachment(Vector2i(1,0), Vector2i(0,25))) self._window.add(self._container) self._state.push(GameState(self._resolution, self._window)) self._network = Network(self, host, port) self._command_store = {} self._command_queue = [] self._command_lock = threading.Lock() self._playerid = None self._players = {} self._capture_position = None self._timer = 0 # resizing must be done after state has been created so the event is propagated proper. self._resize(self._resolution) def add_window(self, win): self._container.add(win) @event(pygame.QUIT) def quit(self, event=None): self._running = False def is_running(self): return self._running def resolution(self): return self._resolution def run(self): self._running = True self._network.start() while self._running: try: self._flush_queue() self._logic() self._render() except GLError: traceback.print_exc() self.quit() except: traceback.print_exc() @event(pygame.VIDEORESIZE, lambda event: Vector2i(event.w, event.h)) def _resize(self, resolution): self.log.debug("Resolution changed to %dx%d", resolution.x, resolution.y) #self._screen = pygame.display.set_mode(resolution.xy(), OPENGL|DOUBLEBUF|RESIZABLE) setup_opengl() self._resolution = resolution glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(0, resolution.x, 0, resolution.y, -1.0, 1.0); glMatrixMode(GL_MODELVIEW) glLoadIdentity() self._state.resize(resolution) self._game.on_resize(resolution, True) def _flush_queue(self): while True: self._command_lock.acquire() if len(self._command_queue) == 0: self._command_lock.release() break command, args = self._command_queue.pop(0) self._command_lock.release() try: self._dispatch(command, args) except: traceback.print_exc() def _logic(self): global event_table for event in pygame.event.get(): func, adapter = event_table.get(event.type, (None,None)) if func is None: continue func(self, adapter(event)) t = time() if t-self._timer > 1.0: self._toolbar.invalidate() self._timer = t @event(pygame.MOUSEMOTION) def _mousemotion(self, event): pos = Vector2i(event.pos) pos.y = self._resolution.y - pos.y self._state.on_mousemove(pos) @event(pygame.MOUSEBUTTONDOWN) def _mousebuttondown(self, event): pos = Vector2i(event.pos) pos.y = self._resolution.y - pos.y if self._capture_position is not None: if event.button == 1: callback, args, kwargs = self._capture_position try: callback(pos, *args, **kwargs) except: traceback.print_exc() self._capture_position = None pygame.mouse.set_cursor(*Client.cursor_default) return self._state.on_buttondown(pos, event.button) @event(pygame.MOUSEBUTTONUP) def _mousebuttonup(self, event): pos = Vector2i(event.pos) pos.y = self._resolution.y - pos.y self._state.on_buttonup(pos, event.button) def _render(self): glClearColor(1,0,0,0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) self._state.render() pygame.display.flip() def _dispatch(self, cmd, args): """ Run command """ global network_log network_log.debug('got %s(%s)', cmd, ', '.join([str(x) for x in args])) try: # Try to get function func = getattr(self, cmd) # See if it is exposed, so a malicious cannot run any func. if not getattr(func, 'exposed'): raise AttributeError # raised to get same handling as a non-existing func. except AttributeError: print 'Malformed or bad command:', cmd, args return except: print 'Unhandled exception when running command:', cmd, args traceback.print_exc() return func(*args) def push_command(self, line): # Run from network thread try: self._command_lock.acquire() tokens = parse_tokens(line) id = tokens[0] if id == 'UNICAST' or id == 'BROADCAST': id, command, args = parse(line) self._command_queue.append((command, args)) elif id in self._command_store: status = tokens[1] args = tuple(tokens[2:]) data = line[len(id)+len(status)+2:] self._command_store[id].reply(status, args, data) else: raise RuntimeError, 'Got a reply for ID ' + id + ' but no matching request' except: traceback.print_exc() finally: self._command_lock.release() def call(self, command, *args): """ Synchronously call and get reply """ cmd = Command(command, *args) # send command with self._command_lock: self._command_store[cmd.id] = cmd self._network.send(str(cmd) + self._split) # await reply reply = cmd.wait() # delete command with self._command_lock: del self._command_store[cmd.id] return reply @server_call('LIST_OF_ENTITIES', decode=True) def list_of_entities(self, descriptions): self._game.set_entities([Entity(**x) for x in descriptions]) @expose def NEWENT(self, data): decoded = json.loads(data) self._game.add_entity(Entity(**decoded)) @server_call('ENTINFO', 'id', decode=True) def entity_info(self, info): return info @server_call('ENTACTION', 'id', 'action', decode=True) def entity_action(self, info): return info @server_call('PLAYERINFO', 'id', decode=True) def playerinfo(self, info): self._toolbar.set_cash(info['cash']) @expose def CASH(self, amount): self._toolbar.set_cash(int(amount)) @server_call('LOGIN', 'username', 'password', decode=True) def login(self, info): self.playerid = info['id'] self.log.debug('player id is %s', self.playerid) self.playerinfo(self.playerid) @server_call('PLAYERS', decode=True) def players(self, players): return players def player_by_id(self, id): return self._players.get(unicode(id), None) @expose def Hello(self): self.call('SET', 'ENCODER', 'json') try: self.login(username=self._username, password=self._password) except RuntimeError, e: self.log.error(e) self.quit() return self._players = self.players() self.list_of_entities()