Esempio n. 1
0
        def waiter(p):
            try:
                tle = TimeLimitExceeded(timeout+10)
                tle.start()

                data = p.client.gexpect(tagstr)
                wait_queue.put((p, data))
            except (TimeLimitExceeded, EndpointDied) as e:
                if isinstance(e, TimeLimitExceeded) and e is not tle:
                    raise
                wait_queue.put((p, None))
            finally:
                tle.cancel()
Esempio n. 2
0
    def user_input(self, tag, attachment=None, timeout=15, g=None, st=None):
        g = g if g else Game.getgame()
        st = st if st else g.get_synctag()
        input = DataHolder()
        input.tag = tag
        input.input = None
        input.attachment = attachment
        input.timeout = timeout
        input.player = self

        class Break(Exception): pass

        cur_greenlet = gevent.getcurrent()
        def waiter_func():
            rst = Executive.server.gexpect('input_%s_%d' % (tag, st))
            cur_greenlet.kill(Break(), block=False)
            return rst

        try:
            tle = TimeLimitExceeded(timeout+1)
            tle.start()
            waiter = gevent.spawn(waiter_func)
            g.emit_event('user_input_start', input)
            gevent.sleep(0)
            rst = g.emit_event('user_input', input)
            Executive.server.gwrite('input_%s_%d' % (tag, st), rst.input)
        except (Break, TimeLimitExceeded) as e:
            if isinstance(e, TimeLimitExceeded) and e is not tle:
                raise
            g.emit_event('user_input_timeout', input)
            rst = input
        except:
            waiter.kill()
            raise
        finally:
            tle.cancel()
            g.emit_event('user_input_finish', input)
            try:
                waiter.join()
                gevent.sleep(0)
            except Break:
                pass

        rst.input = waiter.get()
        g.emit_event('user_input_finish', input)
        return rst.input
Esempio n. 3
0
    def user_input(self, tag, attachment=None, timeout=15, g=None, st=None):
        g = g if g else Game.getgame()
        st = st if st else g.get_synctag()

        try:
            # The ultimate timeout
            with TimeLimitExceeded(timeout + 10):
                input = self.client.gexpect('input_%s_%d' % (tag, st))
        except (TimeLimitExceeded, EndpointDied):
            # Player hit the red line, he's DEAD.
            #import gamehall as hall
            #hall.exit_game(self.client)
            input = None
        pl = PlayerList(g.players[:])
        pl.client.gwrite('input_%s_%d' % (tag, st),
                         input)  # tell other players
        return input
Esempio n. 4
0
        def waiter(p):
            try:
                tle = TimeLimitExceeded(timeout + 10)
                tle.start()

                data = p.client.gexpect(tagstr)
                wait_queue.put((p, data))
            except (TimeLimitExceeded, EndpointDied) as e:
                if isinstance(e, TimeLimitExceeded) and e is not tle:
                    raise
                wait_queue.put((p, None))
            finally:
                tle.cancel()
Esempio n. 5
0
    def user_input(self, tag, attachment=None, timeout=15, g=None, st=None):
        g = g if g else Game.getgame()
        st = st if st else g.get_synctag()
        input = DataHolder()
        input.tag = tag
        input.input = None
        input.attachment = attachment
        input.timeout = timeout
        input.player = self

        class Break(Exception):
            pass

        cur_greenlet = gevent.getcurrent()

        def waiter_func():
            rst = Executive.server.gexpect('input_%s_%d' % (tag, st))
            cur_greenlet.kill(Break(), block=False)
            return rst

        try:
            tle = TimeLimitExceeded(timeout + 1)
            tle.start()
            waiter = gevent.spawn(waiter_func)
            g.emit_event('user_input_start', input)
            gevent.sleep(0)
            rst = g.emit_event('user_input', input)
            Executive.server.gwrite('input_%s_%d' % (tag, st), rst.input)
        except (Break, TimeLimitExceeded) as e:
            if isinstance(e, TimeLimitExceeded) and e is not tle:
                raise
            g.emit_event('user_input_timeout', input)
            rst = input
        except:
            waiter.kill()
            raise
        finally:
            tle.cancel()
            g.emit_event('user_input_finish', input)
            try:
                waiter.join()
                gevent.sleep(0)
            except Break:
                pass

        rst.input = waiter.get()
        g.emit_event('user_input_finish', input)
        return rst.input
Esempio n. 6
0
    def input_func(st):
        my = ilets[g.me]
        with TimeLimitExceeded(timeout + 1, False):
            _, my = g.emit_event('user_input', (trans, my))

        g.me.server.gwrite(tag + str(st), my.data())
Esempio n. 7
0
    def user_input_any(self, tag, expects, attachment=None, timeout=15):
        g = Game.getgame()
        st = g.get_synctag()

        tagstr = 'inputany_%s_%d' % (tag, st)

        g.emit_event('user_input_any_begin', (self, tag, attachment))

        input = DataHolder()
        input.tag = tag
        input.input = None
        input.attachment = attachment
        input.timeout = timeout
        input.player = g.me

        class Break(Exception): pass # ('Input: you are too late!')

        def waiter_func():
            pid, data = Executive.server.gexpect(tagstr + '_resp')
            g.kill(Break(), block=False)
            return pid, data

        if isinstance(g.me, TheChosenOne) and g.me in self:
            try:
                waiter = gevent.spawn(waiter_func)
                tle = TimeLimitExceeded(timeout)
                tle.start()
                g.emit_event('user_input_start', input)
                rst = g.emit_event('user_input', input)
                Executive.server.gwrite(tagstr, rst.input)
            except (Break, TimeLimitExceeded) as e:
                if isinstance(e, TimeLimitExceeded) and e is not tle:
                    raise
                g.emit_event('user_input_timeout', input)
                rst = input
                rst.input = None
                Executive.server.gwrite(tagstr, rst.input)
            except:
                waiter.kill()
                raise
            finally:
                tle.cancel()
                g.emit_event('user_input_finish', input)
                try:
                    waiter.join()
                    gevent.sleep(0)
                except Break:
                    pass

        else:
            # none of my business, just wait for the result
            try:
                waiter = gevent.spawn(waiter_func)
                waiter.join()
                gevent.sleep(0)
            except Break:
                pass

        pid, data = waiter.get()

        g.emit_event('user_input_any_end', tag)

        if pid is None:
            return None, None

        p = g.player_fromid(pid)

        if not expects(p, data):
            raise GameError('WTF?! Server cheats!')

        return p, data
Esempio n. 8
0
def user_input(players, inputlet, timeout=25, type='single', trans=None):
    '''
    Type can be 'single', 'all' or 'any'
    '''
    assert type in ('single', 'all', 'any')
    assert not type == 'single' or len(players) == 1

    timeout = max(0, timeout)

    g = Game.getgame()
    inputlet.timeout = timeout
    players = players[:]

    if not trans:
        with InputTransaction(inputlet.tag(), players) as trans:
            return user_input(players, inputlet, timeout, type, trans)

    t = {'single': '', 'all': '&', 'any': '|'}[type]
    tag = 'I{0}:{1}:'.format(t, inputlet.tag())

    ilets = {p: copy(inputlet) for p in players}
    for p in players:
        ilets[p].actor = p

    results = {p: None for p in players}
    synctags = {p: g.get_synctag() for p in players}

    orig_players = players[:]
    input_group = GreenletGroup()
    g.gr_groups.add(input_group)
    _input_group = set()

    till = time.time() + timeout + 5
    try:
        inputany_player = None

        def get_input_waiter(p, t):
            try:
                # should be [tag, <Data for Inputlet.parse>]
                # tag likes 'I?:ChooseOption:2345'
                tag, rst = p.client.gexpect(t)
                return rst
            except EndpointDied:
                return None

        for p in players:
            t = tag + str(synctags[p])
            w = input_group.spawn(get_input_waiter, p, t)
            _input_group.add(w)
            w.player = p
            w.gr_name = 'get_input_waiter: p=%r, tag=%s' % (p, t)

        for p in players:
            g.emit_event('user_input_start', (trans, ilets[p]))

        while players:
            # NOTICE: This is a must.
            # TLE would be raised at other part (notably my.post_process) in the original solution
            # (wrapping large parts of code in 'with TimeLimitExceeded(): ...')
            with TimeLimitExceeded(max(till - time.time(), 0)):
                w = waitany(_input_group)
                _input_group.discard(w)
                try:
                    rst = w.get()
                    p, data = w.player, rst
                except:
                    p, data = w.player, None

            g.players.client.gwrite('R{}{}'.format(tag, synctags[p]), data)

            my = ilets[p]

            try:
                rst = my.parse(data)
            except:
                log.error('user_input: exception in .process()', exc_info=1)
                # ----- FOR DEBUG -----
                if g.IS_DEBUG:
                    raise
                # ----- END FOR DEBUG -----
                rst = None

            rst = my.post_process(p, rst)

            g.emit_event('user_input_finish', (trans, my, rst))

            players.remove(p)
            results[p] = rst

            if type == 'any' and rst is not None:
                inputany_player = p
                break

    except TimeLimitExceeded:
        pass

    finally:
        input_group.kill()

    # timed-out players
    for p in players:
        my = ilets[p]
        rst = my.parse(None)
        rst = my.post_process(p, rst)
        results[p] = rst
        g.emit_event('user_input_finish', (trans, my, rst))
        g.players.client.gwrite('R{}{}'.format(tag, synctags[p]), None)

    if type == 'single':
        return results[orig_players[0]]

    elif type == 'any':
        if not inputany_player:
            return None, None

        return inputany_player, results[inputany_player]

    elif type == 'all':
        return OrderedDict([(p, results[p]) for p in orig_players])

    assert False, 'WTF?!'
Esempio n. 9
0
    def user_input_any(self, tag, expects, attachment=None, timeout=15):
        g = Game.getgame()
        st = g.get_synctag()

        tagstr = 'inputany_%s_%d' % (tag, st)

        g.emit_event('user_input_any_begin', (self, tag, attachment))

        input = DataHolder()
        input.tag = tag
        input.input = None
        input.attachment = attachment
        input.timeout = timeout
        input.player = g.me

        class Break(Exception):
            pass  # ('Input: you are too late!')

        def waiter_func():
            pid, data = Executive.server.gexpect(tagstr + '_resp')
            g.kill(Break(), block=False)
            return pid, data

        if isinstance(g.me, TheChosenOne) and g.me in self:
            try:
                waiter = gevent.spawn(waiter_func)
                tle = TimeLimitExceeded(timeout)
                tle.start()
                g.emit_event('user_input_start', input)
                rst = g.emit_event('user_input', input)
                Executive.server.gwrite(tagstr, rst.input)
            except (Break, TimeLimitExceeded) as e:
                if isinstance(e, TimeLimitExceeded) and e is not tle:
                    raise
                g.emit_event('user_input_timeout', input)
                rst = input
                rst.input = None
                Executive.server.gwrite(tagstr, rst.input)
            except:
                waiter.kill()
                raise
            finally:
                tle.cancel()
                g.emit_event('user_input_finish', input)
                try:
                    waiter.join()
                    gevent.sleep(0)
                except Break:
                    pass

        else:
            # none of my business, just wait for the result
            try:
                waiter = gevent.spawn(waiter_func)
                waiter.join()
                gevent.sleep(0)
            except Break:
                pass

        pid, data = waiter.get()

        g.emit_event('user_input_any_end', tag)

        if pid is None:
            return None, None

        p = g.player_fromid(pid)

        if not expects(p, data):
            raise GameError('WTF?! Server cheats!')

        return p, data