Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import collections
- from enum import IntEnum
- from commands.say import SayFilter
- from commands import CommandReturn
- from listeners import OnClientDisconnect
- from listeners.tick import Delay
- from core import WeakAutoUnload
- class CancelReason(IntEnum):
- NONE = 0
- FINISHED = 1
- DISCONNECT = 2
- TIMEOUT = 3
- AUTO_UNLOAD = 4
- class UserInputRequest(WeakAutoUnload):
- # One deque per user
- pending_requests = collections.defaultdict(collections.deque)
- def __init__(self, index, timeout=None):
- """Start a new input request.
- :param int index:
- The index of the player who should be asked for input.
- :param float timeout:
- Time after which the request should be cancelled if no input was
- given. The timeout timer will start when the request was started.
- """
- self.index = index
- self.timeout = timeout
- self.timeout_timer = None
- self.queue.append(self)
- if len(self.queue) == 1:
- self._start_request()
- else:
- self.on_request_queued()
- def _unload_instance(self):
- self.cancel(CancelReason.AUTO_UNLOAD)
- def _start_request(self):
- """Start the request."""
- if self.timeout is not None:
- self.timeout_timer = Delay(
- self.timeout, self.cancel, [CancelReason.TIMEOUT])
- self.on_request_started()
- def cancel(self, reason=CancelReason.NONE):
- """Cancel the input request."""
- if self.timeout_timer is not None and self.timeout_timer.running:
- self.timeout_timer.cancel()
- self.on_request_cancelled(reason)
- print(self)
- print(self.queue)
- self.queue.remove(self)
- if self.queue:
- self.queue[0]._start_request()
- def give_input(self, data, team_only):
- """Give input."""
- result = self.on_input_given(data, team_only)
- if result or result is None:
- self.cancel(CancelReason.FINISHED)
- @property
- def queue(self):
- """Return the user's queue.
- :rtype: collections.deque
- """
- return self.pending_requests[self.index]
- @classmethod
- def get_user_queue(cls, index):
- """Return the queue of a user.
- :param int index:
- The index of the player.
- :rtype: collections.deque
- """
- return cls.pending_requests[index]
- @classmethod
- def get_active_request(cls, index):
- """Return the active request of a player.
- :return:
- ``None`` if the user has no active request.
- :rtype: UserInputRequest
- """
- queue = cls.get_user_queue(index)
- return queue[0] if queue else None
- @classmethod
- def has_pending_requests(cls, index):
- """Return ``True`` if a player has pending requests.
- :param int index:
- The index of the player.
- :rtype: bool
- """
- return (index in cls.pending_requests
- and len(cls.get_user_queue(index)) > 0)
- def on_request_queued(self):
- """Called when user input was requested, but another request is
- currently pending.
- """
- pass
- def on_request_started(self):
- """Called when the request is the active request."""
- pass
- def on_input_given(self, data, team_only):
- """Called when the user entered something.
- :param str data:
- The entered data.
- :param bool team_only:
- Whether or not the input was made in team only chat.
- :return:
- Return ``True`` if the given input is valid. Else return
- ``False``. ``None`` will be handled as ``True`` as well.
- :rtype: bool
- """
- pass
- def on_request_cancelled(self, reason):
- """Called when the request has been cancelled.
- :param CancelReason reason:
- Reason why the request has been cancelled.
- """
- pass
- @SayFilter
- def on_say(command, index, team_only):
- if not UserInputRequest.has_pending_requests(index):
- print('CONTINUE')
- return CommandReturn.CONTINUE
- queue = UserInputRequest.get_user_queue(index)
- queue[0].give_input(command.command_string, team_only)
- print('BLOCK')
- return CommandReturn.BLOCK
- @OnClientDisconnect
- def on_client_disconnect(index):
- queue = UserInputRequest.get_user_queue(index)
- for request in list(queue):
- request.cancel(CancelReason.DISCONNECT)
- del UserInputRequest.pending_requests[index]
- # =============================================================================
- # >> TEST
- # =============================================================================
- from events import Event
- from players.entity import Player
- from messages import SayText2
- class MyUserInputRequest(UserInputRequest):
- def on_request_queued(self):
- """Called when user input was requested, but another request is
- currently pending.
- """
- SayText2("on_request_queued").send()
- def on_request_started(self):
- """Called when the request is the active request."""
- SayText2("on_request_started").send()
- def on_input_given(self, data, team_only):
- """Called when the user entered something.
- :param str data:
- The entered data.
- :param bool team_only:
- Whether or not the input was made in team only chat.
- :return:
- Return ``True`` if the given input is valid. Else return
- ``False``. ``None`` will be handled as ``True`` as well.
- :rtype: bool
- """
- SayText2("on_input_given - data: {} - team_only: {}".format(data, team_only)).send()
- def on_request_cancelled(self, reason):
- """Called when the request has been cancelled.
- :param CancelReason reason:
- Reason why the request has been cancelled.
- """
- SayText2("on_request_cancelled - reason: {}".format(reason)).send()
- @Event('player_jump')
- def player_jump(event):
- player = Player.from_userid(event['userid'])
- request = MyUserInputRequest(player.index, 5)
Advertisement
Add Comment
Please, Sign In to add comment