Ayuto

UserInputRequest

Jan 7th, 2018
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.23 KB | None | 0 0
  1. import collections
  2. from enum import IntEnum
  3.  
  4. from commands.say import SayFilter
  5. from commands import CommandReturn
  6.  
  7. from listeners import OnClientDisconnect
  8. from listeners.tick import Delay
  9.  
  10. from core import WeakAutoUnload
  11.  
  12.  
  13. class CancelReason(IntEnum):
  14.     NONE = 0
  15.     FINISHED = 1
  16.     DISCONNECT = 2
  17.     TIMEOUT = 3
  18.     AUTO_UNLOAD = 4
  19.  
  20.  
  21. class UserInputRequest(WeakAutoUnload):
  22.     # One deque per user
  23.     pending_requests = collections.defaultdict(collections.deque)
  24.  
  25.     def __init__(self, index, timeout=None):
  26.         """Start a new input request.
  27.  
  28.        :param int index:
  29.            The index of the player who should be asked for input.
  30.        :param float timeout:
  31.            Time after which the request should be cancelled if no input was
  32.            given. The timeout timer will start when the request was started.
  33.        """
  34.         self.index = index
  35.         self.timeout = timeout
  36.         self.timeout_timer = None
  37.  
  38.         self.queue.append(self)
  39.         if len(self.queue) == 1:
  40.             self._start_request()
  41.         else:
  42.             self.on_request_queued()
  43.  
  44.     def _unload_instance(self):
  45.         self.cancel(CancelReason.AUTO_UNLOAD)
  46.  
  47.     def _start_request(self):
  48.         """Start the request."""
  49.         if self.timeout is not None:
  50.             self.timeout_timer = Delay(
  51.                 self.timeout, self.cancel, [CancelReason.TIMEOUT])
  52.  
  53.         self.on_request_started()
  54.  
  55.     def cancel(self, reason=CancelReason.NONE):
  56.         """Cancel the input request."""
  57.         if self.timeout_timer is not None and self.timeout_timer.running:
  58.             self.timeout_timer.cancel()
  59.  
  60.         self.on_request_cancelled(reason)
  61.            
  62.         print(self)
  63.         print(self.queue)
  64.         self.queue.remove(self)
  65.         if self.queue:
  66.             self.queue[0]._start_request()
  67.  
  68.     def give_input(self, data, team_only):
  69.         """Give input."""
  70.         result = self.on_input_given(data, team_only)
  71.         if result or result is None:
  72.             self.cancel(CancelReason.FINISHED)
  73.  
  74.     @property
  75.     def queue(self):
  76.         """Return the user's queue.
  77.  
  78.        :rtype: collections.deque
  79.        """
  80.         return self.pending_requests[self.index]
  81.  
  82.     @classmethod
  83.     def get_user_queue(cls, index):
  84.         """Return the queue of a user.
  85.  
  86.        :param int index:
  87.            The index of the player.
  88.        :rtype: collections.deque
  89.        """
  90.         return cls.pending_requests[index]
  91.  
  92.     @classmethod
  93.     def get_active_request(cls, index):
  94.         """Return the active request of a player.
  95.  
  96.        :return:
  97.            ``None`` if the user has no active request.
  98.        :rtype: UserInputRequest
  99.        """
  100.         queue = cls.get_user_queue(index)
  101.         return queue[0] if queue else None
  102.  
  103.     @classmethod
  104.     def has_pending_requests(cls, index):
  105.         """Return ``True`` if a player has pending requests.
  106.  
  107.        :param int index:
  108.            The index of the player.
  109.        :rtype: bool
  110.        """
  111.         return (index in cls.pending_requests
  112.             and len(cls.get_user_queue(index)) > 0)
  113.  
  114.     def on_request_queued(self):
  115.         """Called when user input was requested, but another request is
  116.        currently pending.
  117.        """
  118.         pass
  119.  
  120.     def on_request_started(self):
  121.         """Called when the request is the active request."""
  122.         pass
  123.  
  124.     def on_input_given(self, data, team_only):
  125.         """Called when the user entered something.
  126.  
  127.        :param str data:
  128.            The entered data.
  129.        :param bool team_only:
  130.            Whether or not the input was made in team only chat.
  131.        :return:
  132.            Return ``True`` if the given input is valid. Else return
  133.            ``False``. ``None`` will be handled as ``True`` as well.
  134.        :rtype: bool
  135.        """
  136.         pass
  137.  
  138.     def on_request_cancelled(self, reason):
  139.         """Called when the request has been cancelled.
  140.  
  141.        :param CancelReason reason:
  142.            Reason why the request has been cancelled.
  143.        """
  144.         pass
  145.  
  146.  
  147. @SayFilter
  148. def on_say(command, index, team_only):
  149.     if not UserInputRequest.has_pending_requests(index):
  150.         print('CONTINUE')
  151.         return CommandReturn.CONTINUE
  152.  
  153.     queue = UserInputRequest.get_user_queue(index)
  154.     queue[0].give_input(command.command_string, team_only)
  155.     print('BLOCK')
  156.     return CommandReturn.BLOCK
  157.  
  158.  
  159. @OnClientDisconnect
  160. def on_client_disconnect(index):
  161.     queue = UserInputRequest.get_user_queue(index)
  162.     for request in list(queue):
  163.         request.cancel(CancelReason.DISCONNECT)
  164.  
  165.     del UserInputRequest.pending_requests[index]
  166.  
  167.  
  168.  
  169. # =============================================================================
  170. # >> TEST
  171. # =============================================================================
  172. from events import Event
  173. from players.entity import Player
  174. from messages import SayText2
  175.  
  176. class MyUserInputRequest(UserInputRequest):
  177.     def on_request_queued(self):
  178.         """Called when user input was requested, but another request is
  179.        currently pending.
  180.        """
  181.         SayText2("on_request_queued").send()
  182.  
  183.     def on_request_started(self):
  184.         """Called when the request is the active request."""
  185.         SayText2("on_request_started").send()
  186.  
  187.     def on_input_given(self, data, team_only):
  188.         """Called when the user entered something.
  189.  
  190.        :param str data:
  191.            The entered data.
  192.        :param bool team_only:
  193.            Whether or not the input was made in team only chat.
  194.        :return:
  195.            Return ``True`` if the given input is valid. Else return
  196.            ``False``. ``None`` will be handled as ``True`` as well.
  197.        :rtype: bool
  198.        """
  199.         SayText2("on_input_given - data: {} - team_only: {}".format(data, team_only)).send()
  200.  
  201.     def on_request_cancelled(self, reason):
  202.         """Called when the request has been cancelled.
  203.  
  204.        :param CancelReason reason:
  205.            Reason why the request has been cancelled.
  206.        """
  207.         SayText2("on_request_cancelled - reason: {}".format(reason)).send()
  208.  
  209. @Event('player_jump')
  210. def player_jump(event):
  211.     player = Player.from_userid(event['userid'])
  212.     request = MyUserInputRequest(player.index, 5)
Advertisement
Add Comment
Please, Sign In to add comment