Advertisement
ProgramCrafter

Stem

Aug 24th, 2021
406
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.64 KB | None | 0 0
  1. import traceback
  2. import socket
  3. import time
  4.  
  5. def byte(n):
  6.   return bytes([n])
  7.  
  8. class RetriableSocket:
  9.   def __init__(self, addr):
  10.     self.sock = socket.socket()
  11.     self.sock.connect(addr)
  12.  
  13.   def close(self):
  14.     self.sock.close()
  15.  
  16.   def send(self, s):
  17.     if isinstance(s, int): s = byte(s)
  18.     if isinstance(s, str): s = s.encode('utf-8')
  19.     i = 0
  20.     while i < len(s): i += self.sock.send(s[i:])
  21.  
  22.   def recv(self, n):
  23.     data = b''
  24.     while len(data) < n: data += self.sock.recv(n - len(data))
  25.     return data
  26.  
  27. class StemClient:
  28.   def __init__(self):
  29.     self.sock = RetriableSocket(('stem.fomalhaut.me', 5733))
  30.  
  31.   def disconnect(self):
  32.     if self.sock:
  33.       self.sock.close()
  34.       self.sock = None
  35.  
  36.   def send_package(self, _type, _id, _message=None):
  37.     pack = byte(_type)
  38.     if _type == 3 or _type == 4:
  39.       pack += _id
  40.     else:
  41.       pack += byte(len(_id))
  42.       pack += _id.encode('utf-8')
  43.       if _message: pack += _message.encode('utf-8')
  44.    
  45.     self.sock.send(len(pack) // 256)
  46.     self.sock.send(len(pack) % 256)
  47.     self.sock.send(pack)
  48.  
  49.   def subscribe(self, channel):
  50.     self.send_package(1, channel)
  51.  
  52.   def unsubscribe(self, channel):
  53.     self.send_package(2, channel)
  54.  
  55.   def send(self, channel, msg):
  56.     self.send_package(0, channel, msg)
  57.  
  58.   def recv(self):
  59.     pack_len = self.sock.recv(2)
  60.     pack_type = self.sock.recv(1)
  61.    
  62.     if pack_type == b'\0': # incoming msg
  63.       ch_len = self.sock.recv(1)[0] # getting int from byte string
  64.       ch_id = self.sock.recv(ch_len)
  65.      
  66.       msg_len = pack_len[0] * 256 + pack_len[1]
  67.       msg_len -= ch_len + 2
  68.       msg = self.sock.recv(msg_len)
  69.      
  70.       return str(msg, 'utf-8')
  71.     elif pack_type == b'\3': # pinging
  72.       msg_len = pack_len[0] * 256 + pack_len[1] - 1
  73.       self.send_package(4, self.sock.recv(msg_len))
  74.      
  75.       return None
  76.  
  77. client = StemClient()
  78.  
  79. try:
  80.   last_channel = ''
  81.   buffer = ''
  82.   while True:
  83.     command = input()
  84.     if command.startswith('/target'):
  85.       buffer = buffer[:-2]
  86.       if buffer:
  87.         client.send(last_channel, buffer)
  88.         print(buffer, 'sent')
  89.         buffer = ''
  90.       last_channel = command[8:]
  91.      
  92.     elif command.startswith('/reset'):
  93.       buffer = buffer
  94.       print(buffer, 'reset')
  95.       buffer = ''
  96.      
  97.     elif command.startswith('/flush'):
  98.       buffer = buffer[:-2]
  99.      
  100.       client.send(last_channel, buffer)
  101.       print(buffer, 'sent')
  102.       buffer = ''
  103.      
  104.     else:
  105.       buffer += command + '\r\n'
  106. except KeyboardInterrupt:
  107.   client.disconnect()
  108. except:
  109.   __import__('traceback').print_exc()
  110.   input()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement