Codifique seus próprios controles de chat do Twitch para robôs – ou qualquer outra coisa!

Nó Fonte: 805836

Twitch Plays Pokemon estourou na então nascente cena de transmissão ao vivo em 2014, permitindo que os espectadores do Twitch assumissem o comando de um emulador de Game Boy rodando Pokémon Red por meio de comandos simples de bate-papo. Desde então, o mesmo conceito tem sido aplicado a tudo o que existe sob o sol. Outros videogames, a instalação do Linux e até mesmo a negociação na Bolsa de Valores de Nova York foram todos gameificados por meio do chat do Twitch.

TwitchPlaysPokémon deu início a uma mania no controle crowdsourced de videogames, robôs e praticamente todo o resto.

Você, leitor sedento, está se perguntando como conseguir uma fatia dessa deliciosa ação. Não tenha medo, pois com um pouco de código desorganizado, você pode deixar o bate-papo do Twitch assumir o controle de praticamente qualquer coisa dentro, dentro ou ao redor do seu computador.

É apenas IRC

A grande vantagem do chat do Twitch é que ele roda em IRC (Internet Relay Chat) vanilla. O protocolo existe desde sempre e existem bibliotecas para facilitar a interface. Assim como o streamer original por trás do Twitch Plays Pokémon, usaremos Python porque é ótimo para pequenos experimentos divertidos como esses. Dito isso, qualquer linguagem servirá bem — basta aplicar as mesmas técnicas na sintaxe relevante.

SimpleTwitchCommander, como eu nomeei no Github, pressupõe alguma familiaridade com a programação básica em Python. O código permitirá que você receba comandos do chat de duas maneiras. Os comandos do chat podem ser tabulados, e apenas aquele com mais votos executados, ou cada comando pode ser executado diretamente. Na verdade, obter esse código para controlar seu robô, videogame ou víbora de estimação depende de você. O que estamos fazendo aqui é interagir com o bate-papo do Twitch e extrair comandos para que você possa fazer o que quiser. Dito isso, para este exemplo, configuramos o código para analisar comandos para um robô com rodas simples. Vamos mergulhar.

Caminhada de código

 import socket from emoji import demojize from apscheduler.schedulers.background import BackgroundScheduler 
Com este código, você também pode observar pessoas aleatórias na Internet dirija seu robô direto para um arbusto.

A primeira coisa a fazer em nosso código é importar as bibliotecas que precisamos. Bibliotecas são ótimas, são presentes de programadores talentosos que facilitam nossas vidas — ou pelo menos esperamos que sim. Estamos usando quatro bibliotecas neste caso, mas você pode usar apenas as três primeiras, dependendo da sua aplicação. A primeira, e talvez a mais importante, é a socket biblioteca, que lida com toda a nossa comunicação de rede. O emoji A biblioteca nos fornece uma ferramenta interessante para remover emojis de mensagens de bate-papo, pois eles podem ficar confusos. APScheduler é usado em nosso sistema de votação por comando, que permite que os usuários do Twitch votem na ação desejada, em vez de simplesmente deixar passar todos os comandos do Twitch.

class TwitchControl:

Esta declaração configura a classe para nosso programa.

 def __init__(self): self.server = 'irc.chat.twitch.tv' self.port = 6667 self.nickname = 'yourtwitchusername' self.token = 'oauth:youroauthkeyhere' self.channel = '#yourtwitchchannel' self.sched = BackgroundScheduler() self.sock = socket.socket() self.sock.connect((self.server,self.port)) self.sock.send(f"PASS {self.token}n".encode('utf-8')) self.sock.send(f"NICK {self.nickname}n".encode('utf-8')) self.sock.send(f"JOIN {self.channel}n".encode('utf-8')) 

__init__() é uma rotina especial do Python chamada quando um objeto é criado a partir de uma classe. Em termos simples, quando apelamos TwitchControl, o código em __init__() corre primeiro. Aqui, estamos criando variáveis ​​que armazenam o endereço do servidor de bate-papo do Twitch, a porta e nosso login do Twitch e detalhes do canal. O token oauth é como o servidor Twitch sabe quem está se conectando ao canal de chat, e você pode gerar o seu próprio aqui.

 self.voteDict = {"null": 0, "fwd" : 0, "rev" : 0, "left" : 0, "right" : 0} 

A seguir, criamos uma variável especial chamada dicionário e damos a ela o nome voteDict. Os dicionários são ótimos, pois nos permitem armazenar dados em pequenos pares organizados. No nosso caso, temos os comandos desejados, e cada um tem um número próximo a ele. Isso corresponderá ao número de votos para cada comando no chat. Inicializamos estes em 0 para começar.

 self.sched.add_job(self.voteCount, 'interval', seconds=2) self.sched.start() 

As linhas acima configuradas APscheduler para executar uma função em intervalos regulares de 2 segundos. Essa função atende pelo nome voteCount, e a cada intervalo de dois segundos ele verifica voteDict para ver qual comando obteve mais votos no chat e então executa o vencedor. Voltaremos e daremos uma olhada em voteCount daqui a pouco. Por enquanto, vamos dar uma olhada no loop principal que é executado quando tudo é inicializado.

 def loop(self): while True: resp = self.sock.recv(2048).decode('utf-8') if resp.startswith('PING'): self.sock.send("PONGn".encode('utf-8')) elif len(resp) > 0: respClean = demojize(resp) print(respClean) msgComponents=respClean.split(" ",3) msgUser=msgComponents[0] #get username from message msgUser = msgUser[msgUser.find(':')+1: msgUser.find('!')] msgContent=msgComponents[3] #print message content 

Assim que entrarmos no loop while, precisaremos receber dados do servidor de IRC. Se os dados forem “PING”, respondemos com “PONG” conforme prática típica do IRC para manter a conexão ativa. Caso contrário, limpamos os dados com a função demojize, que substitui quaisquer emojis na mensagem por texto simples. Em seguida, usamos funções de string para dividir a mensagem bruta do servidor em seus componentes: o nome de usuário que enviou a mensagem e o conteúdo real da mensagem. Neste ponto, podemos procurar diretamente um comando e, se quisermos que ele seja acionado diretamente nas mensagens, podemos fazê-lo aqui.

 if msgContent.find("LIGHTS") >=0: print("Turning Lights On!") #code to turn lights on here 

Alternativamente, se quisermos coletar comandos no chat e ver qual é eleito o mais popular, podemos fazer isso também. Cada vez que um dos seguintes comandos é detectado, seu campo correspondente no voteDict dicionário é incrementado em 1.

 if msgContent.find("FWD") >=0: self.voteDict["fwd"] = self.voteDict["fwd"] +1 if msgContent.find("REV") >=0: self.voteDict["rev"] = self.voteDict["rev"] +1 if msgContent.find("LEFT") >=0: self.voteDict["left"] = self.voteDict["left"] +1 if msgContent.find("RIGHT") >=0: self.voteDict["right"] = self.voteDict["right"] +1 

Isso é tudo que nosso loop principal faz. Ele recebe dados do servidor IRC à medida que chegam, processa-os e aumenta a contagem de votos dos comandos recebidos. Para realmente agirmos com base nessas votações, precisamos de recorrer ao nosso voteCount função. Graças ao APscheduler rotina que configuramos antes, ela é executada automaticamente a cada dois segundos.

 def voteCount(self): #function responsible for checking votes and executing commands print('Counting votes and executing command') voteWinner = max(self.voteDict, key=self.voteDict.get) print("biggest vote:" + voteWinner) nullCheck=all(x==0 for x in self.voteDict.values()) if nullCheck: print('doing a nullo') elif voteWinner=="fwd": print('going Forward') #code to go forward here elif voteWinner=="rev": print('going Reverse') #code to go reverse here elif voteWinner=="left": print('going Left') #code to go left here elif voteWinner=="right": print('going Right') #code to go right here self.voteDict = {"null" : 0, "fwd" : 0, "rev" : 0, "left" : 0, "right" : 0} 

voteCount é uma função simples, que usa funções de dicionário embutidas do Python para determinar o comando que teve mais votos. Observe que também verificamos se todos os votos são iguais a zero — nesse caso, não devemos fazer nada, daí o código nullCheck. Assim que o vencedor for determinado, o código do comando relevante pode ser executado.

O que você vai liberar no Twitch?

Há um pouco mais de padronização para unir as coisas, mas fundamentalmente, esses são os blocos que fazem tudo funcionar. Pegue a versão real do Github se quiser mexer em casa. Obviamente, a partir daqui, é simplesmente uma questão de personalização para moldar o código de acordo com seu propósito específico. Se você deseja controlar um robô, coloque seus comandos para servos ou motores nos locais necessários ou envie instruções serial para o seu microcontrolador que realiza essas tarefas. Como alternativa, se você estiver trabalhando com um jogo em um emulador, faça com que o código Python simplesmente emule os pressionamentos de botão relevantes.

O código não está de forma alguma otimizado; escrever este artigo demorou cerca de duas vezes mais tempo do que escrever o código em si. É provável que haja enormes ganhos com o uso de código de gerenciamento de strings mais idealizado e outros ajustes semelhantes. O trabalho adicional de reunir tudo isso em uma biblioteca organizada é deixado como um exercício para o leitor. Esperamos que isso ajude você a se divertir com crowdsourcing no Twitch! Como sempre, feliz hacking.

Fonte: https://hackaday.com/2021/04/08/code-your-own-twitch-chat-controls-for-robots-or-just-about-anything-else/

Carimbo de hora:

Mais de Hackear um dia