Esempio n. 1
0
 def __init__(self, *args, **kwargs):
   Plugin.__init__(self, *args, **kwargs)
   
   command_handler.event.connect(get_dispatcher(self))
   
   self.pre_lo3 = Signal()
   self.post_lo3 = Signal()
   self.performing_lo3 = False
Esempio n. 2
0
class CommandHandler(object):  
  #==============================
  def __init__(self):
    self._init_signals()
    
  #==============================
  def _init_signals(self):
    self.event = Signal()

  #==============================
  def process(self, command, extra=None, silent=False, **kwargs):
    command = command.split(' ')
    params = ' '.join(command[1:])
    command = command[0]
    stop = False
        
    try:
      stop = self.event.send(
        sender=self.__class__,
        command=command,
        params=params,
        extra=extra,
        silent=silent,
        **kwargs
      )
    except CommandInterrupt:
      pass
    except:
      raise
Esempio n. 3
0
 def _init_signals(self):
   self.pre_connect = Signal()
   self.post_connect = Signal()
   
   self.pre_receive = Signal()
   self.post_receive = Signal()
   
   self.pre_send = Signal()
   self.post_send = Signal()
   
   self.post_accept = Signal()
   
   self.ready = Signal()
Esempio n. 4
0
 def _init_signals(self):
   self.event = Signal()
Esempio n. 5
0
class SignalSocket(Thread):
  """A threaded socket class based on signals. It can become a client or a server.
  Hook into the signals in order to do useful things with the class."""
  
  #==============================
  def __init__(self, host, port, protocol="tcp"):
    self.daemon = True
    Thread.__init__(self)
    
    self._init_signals()
    
    self.host = socket.gethostbyname(host)
    self.port = port
    self.protocol = protocol
    self._close = False
    self.max_packet_size = 8192
    
    self.sock = False
    self.clientsock = False
    # The socket we are communicating with. It will either
    # be self.sock or self.clientsock depending on our socket
    # configuration (protocol+mode)
    self.commsock = False
    
  #============================== 
  def _init_signals(self):
    self.pre_connect = Signal()
    self.post_connect = Signal()
    
    self.pre_receive = Signal()
    self.post_receive = Signal()
    
    self.pre_send = Signal()
    self.post_send = Signal()
    
    self.post_accept = Signal()
    
    self.ready = Signal()
  
  #============================== 
  def send(self, data):
    self.pre_send.send(sender=self.__class__)
    self.commsock.send(data)
    self.post_send.send(sender=self.__class__, data=data)
    
  #============================== 
  def recv(self):    
    self.pre_receive.send(sender=self.__class__)
    data = self.commsock.recv(self.max_packet_size)
    self.post_receive.send(sender=self.__class__, data=data)
    return data
    
  #============================== 
  def close(self):
    self._close = True
    if self.sock:
      self.sock.close()
      self.sock = False
    if self.clientsock:
      self.clientsock.close()
      self.clientsock = False
    self.commsock = False
  
  #============================== 
  def set_protocol(self, protocol=None):
    self.close()
    if not protocol:
      protocol = self.protocol
    self.protocol = protocol
    
    if protocol == "tcp":
      self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    elif protocol == "udp":
      self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      
    self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      
  #============================== 
  def client(self):
    while self.isAlive():
      self.close()
      time.sleep(0.05)
      
    self.set_protocol()
      
    self.mode = "client"
    self.pre_connect.send(sender=self.__class__)
    self.sock.connect((self.host, self.port))
    self.post_connect.send(sender=self.__class__)
    self.start()
  
  #============================== 
  def server(self):
    while self.isAlive():
      self.close()
      time.sleep(0.05)
      
    self.set_protocol()
      
    self.mode = "server"
    self.sock.bind((self.host, self.port))
    if self.protocol == "tcp":
      self.sock.listen(5)
    self.start()
      
  #============================== 
  def run(self):
    self._close = False
    data = False    
    self.commsock = self.sock
    if self.mode == "server" and self.protocol == "tcp":
      # this mode and protocol is ready at this point
      self.ready.send(sender=self.__class__)
      
      self.clientsock, addr = self.sock.accept()      
      self.commsock = self.clientsock      
      self.post_accept.send(sender=self.__class__)
    else: # all other modes and protocols are ready at this point
      self.ready.send(sender=self.__class__)
    
    while not self._close:      
      data = self.recv()
      if not data:
        self.close()
        
Esempio n. 6
0
class ExePlugin(Plugin):
  """Supported commands: exec, execr, lo3"""
  
  #==============================
  def __init__(self, *args, **kwargs):
    Plugin.__init__(self, *args, **kwargs)
    
    command_handler.event.connect(get_dispatcher(self))
    
    self.pre_lo3 = Signal()
    self.post_lo3 = Signal()
    self.performing_lo3 = False

  #==============================
  @command('exec', 'execr')
  def on_command(self, command, params, silent, **kwargs):
    extra = kwargs.get('extra', {})
    uniqueid = extra.get('uniqueid', '')
    
    # We don't have access. Return.
    if not has_access(uniqueid, 'admin'):
      # Keep processing other plugins.
      return True

    if (command == 'exec' or command == 'execr') and params:
      self.exec_(params)
      
      if command == 'execr':
        rcon_client.cvar('sv_restart', '1')

    # Keep processing other plugins.
    return True
  
  #==============================
  def exec_(self, name):
    if not name:
      return
    
    # Grab the location of our scripts
    path = cget('plugins', 'exec', 'scripts_path', default=os.path.join(os.path.dirname(__file__), 'scripts'))
    
    # Iterate through the scripts dir and try to find any file matching name.
    list = os.listdir(path)
    for file in list:
      file_name = os.path.splitext(file)[0]
      if name == file_name:
        fp = open(os.path.join(path, file), 'r')
        for line in fp:
          rcon_client.command(line, deferred=False)
        fp.close()
        break
  
  #==============================
  @command('lo3')
  def on_lo3(self, command, params, silent, **kwargs):
    extra = kwargs.get('extra', {})
    uniqueid = extra.get('uniqueid', '')
    
    if not has_access(uniqueid, 'admin'):
      return True
      
    if command == 'lo3':
      # Don't do lo3 if we're already doing lo3.
      if self.performing_lo3:
        return True
      self.performing_lo3 = True
    
      self.pre_lo3.send(sender=self.__class__)
      
      self.exec_(cget('plugins', 'exec', 'exec_on_lo3'))
      
      # Get the configuration options for going lo3.
      default_lo3_messages = ['[ Going live on 3 restarts ]', '[ Two more restarts ]', '[ Last restart ]']
      default_lo3_delays = ['2', '2', '5']
      lo3_messages = cget('plugins', 'exec', 'lo3_messages', default=default_lo3_messages)
      lo3_delays = cget('plugins', 'exec', 'lo3_delays', default=default_lo3_delays)
      lo3_live_message = cget('plugins', 'exec', 'lo3_live_message', default='[* LIVE LIVE LIVE *]')
       
      #==============================
      def do_restarts(index):
        if index < len(lo3_messages):
          message = lo3_messages[index]
          delay = lo3_delays[index]
          rcon_client.hsay('', message)
          rcon_client.command('sv_restart', delay)
          index += 1
          reactor.callLater(int(delay)+0.9, do_restarts, index)
        else:
          self.performing_lo3 = False
          rcon_client.hsay('', lo3_live_message)
          self.post_lo3.send(sender=self.__class__)
        
      do_restarts(0)
Esempio n. 7
0
 def _init_signals(self):
   self.data = Signal()
   self.ready = Signal()
   self.event = Signal()
   self.unhandled_event = Signal()
Esempio n. 8
0
class RconProcessor(object):
  #==============================
  def __init__(self):
    self._init_signals()
    
    self.events = {
      'user_connected': {
        'regex': re.compile(r'^"(?P<name>.*?)<(?P<userid>\d+)><(?P<uniqueid>.*?)><(?P<team>.*?)>" connected, address "(?P<ip>.*?):(?P<port>.*?)"')
      },
      'user_validated': {
        'regex': re.compile(r'^"(?P<name>.*?)<(?P<userid>\d+)><(?P<uniqueid>.*?)><(?P<team>.*?)>" STEAM USERID validated')
      },
      'user_entered': {
        'regex': re.compile(r'^"(?P<name>.*?)<(?P<userid>\d+)><(?P<uniqueid>.*?)><(?P<team>.*?)>" entered the game')
      },
      'user_joined_team': {
        'regex': re.compile(r'^"(?P<name>.*?)<(?P<userid>\d+)><(?P<uniqueid>.*?)><.*?>" joined team "(?P<team>.*?)"')
      },
      'user_say': {
        'regex': re.compile(r'^"(?P<name>.*?)<(?P<userid>\d+)><(?P<uniqueid>.*?)><(?P<team>.*?)>" say(_(?P<to>.*?))? "(?P<message>.*)"( \((?P<status>.*?)\))?')
      },
      'user_changed_name': {
        'regex': re.compile(r'^"(?P<name>.*?)<(?P<userid>\d+)><(?P<uniqueid>.*?)><.*?>" changed name to "(?P<new_name>.*?)"')
      },
      'user_triggered': {
        'regex': re.compile(r'^"(?P<name>.*?)<(?P<userid>\d+)><(?P<uniqueid>.*?)><(?P<team>.*?)>" triggered "(?P<event>.*?)"')
      },
      'world_triggered': {
        'regex': re.compile(r'^World triggered "(?P<event>.*?)"( \(CT "(?P<ct_score>\d+)"\) \(T "(?P<t_score>\d+)"\))?')
      },
      'server_say': {
        'regex': re.compile(r'^Server say "(?P<message>.*?)"')
      },
      'server_cvar': {
        'regex': re.compile(r'^Server cvar "(?P<cvar>.*?)" = "(?P<value>.*?)"')
      },
      'team_scored': {
        'regex': re.compile(r'^Team "(?P<team>.*?)" scored "(?P<score>.*?)" with "(?P<players>.*?)" players')
      },
      'team_triggered': {
        'regex': re.compile(r'^Team "(?P<team>.*?)" triggered "(?P<event>.*?)"( \(CT "(?P<ct_score>\d+)"\) \(T "(?P<t_score>\d+)"\))?')
      }
    }
    
  #==============================
  def _init_signals(self):
    self.data = Signal()
    self.ready = Signal()
    self.event = Signal()
    self.unhandled_event = Signal()
  
  #==============================
  def run(self):    
    self.sock = SignalSocket(config['rcon']['local']['host'], int(config['rcon']['local']['port']), 'udp')
    self.sock.post_receive.connect(self._on_sock_receive)
    self.sock.ready.connect(self._on_sock_ready)
    self.sock.server()
  
  #==============================
  def add_event(self, name, regex):
    if name in self.events:
      raise EventError('Event already exists')
      
    if isinstance(regex, str):
      regex = re.compile(str)
    
    self.events[name] = {
      'regex': regex
    }
  
  #==============================
  def _on_sock_ready(self, **kwargs):
    self.ready.send(sender=self.__class__)
  
  #==============================
  def _on_sock_receive(self, data, **kwargs):
    self.data.send(sender=self.__class__, data=data)
    
    #log L date - time: response
    null, null, date, null, time, response = data[4:-2].split(' ', 5)
    
    #log.debug(response)
    found_event = False
    for event in self.events:
      m = self.events[event]['regex'].match(response)
      if m:
        self.event.send(sender=self.__class__, event=event, data=m.groupdict())
        found_event = True
        break
    
    # If the event wasn't found, then fire the unhandled_event in case some plugin wants to handle it.
    # Though, you could just use add_event instead.
    if not found_event:
      self.unhandled_event.send(sender=self.__class__, data=response)