Kod dine egne Twitch Chat-kontroller for roboter - eller omtrent alt annet!

Kilde node: 805836

Twitch Spiller Pokemon brast inn på den da begynnende livestreaming-scenen tilbake i 2014, og lot Twitch-seere ta kommandoen over en Game Boy-emulator som kjører Pokemon Red via enkle chat-kommandoer. Siden den gang har det samme konseptet blitt brukt på alt under solen. Andre videospill, installering av Linux og til og med handel på New York Stock Exchange har blitt spilt gjennom Twitch-chat.

TwitchPlays Pokemon startet en mani i crowdsourcet kontroll av videospill, roboter og omtrent alt annet.

Du, tørste leser, lurer på hvordan du kan få en bit av denne deilige handlingen. Frykt ikke, for med litt falleferdig kode kan du la Twitch-chat ta over stort sett alt på, på eller rundt datamaskinen din.

Det er bare IRC

Det fine med Twitch-chat er at den kjører på vanilla IRC (Internet Relay Chat). Protokollen har eksistert for alltid, og biblioteker eksisterer for å gjøre grensesnitt enkelt. Akkurat som den originale streameren bak Twitch Plays Pokemon, kommer vi til å bruke Python fordi den er flott for morsomme små eksperimenter som disse. Med det sagt, vil ethvert språk klare seg - bare bruk de samme teknikkene i den relevante syntaksen.

SimpleTwitch Commander, som jeg har kalt det på Github, forutsetter en viss kjennskap til grunnleggende Python-programmering. Koden lar deg ta kommandoer fra chat på to måter. Kommandoer fra chat kan tabuleres, og bare den med flest stemmer utføres, eller hver enkelt kommando kan utføres direkte. Det er opp til deg å få denne koden for å kontrollere roboten, videospillet eller kjæledyrhuggormen. Det vi gjør her er å bruke Twitch-chat og trekke ut kommandoer slik at du kan få den til å gjøre hva du vil. Med det sagt, for dette eksempelet, har vi satt opp koden for å analysere kommandoer for en enkel robot med hjul. La oss dykke inn.

Kodevandring

 import socket from emoji import demojize from apscheduler.schedulers.background import BackgroundScheduler 
Med denne koden kan du også se på som tilfeldige personer fra Internett kjøre roboten din rett inn i en busk.

Det første du må gjøre i koden vår er å importere bibliotekene vi trenger. Biblioteker er flotte, de er gaver fra talentfulle programmerere som gjør livene våre enklere – eller i det minste håper vi det er det. Vi bruker fire biblioteker i dette tilfellet, men du kan klare deg med bare de tre første avhengig av applikasjonen din. Den første, og kanskje viktigste, er socket bibliotek, som håndterer all vår nettverkskommunikasjon. De emoji biblioteket gir oss et pent verktøy for å fjerne emojier fra chat-meldinger, siden de kan bli rotete. APScheduler brukes til vårt kommandostemmesystem, som lar Twitch-brukere stemme på ønsket handling i stedet for bare å slippe gjennom hver Twitch-kommando.

class TwitchControl:

Denne uttalelsen setter opp klassen for programmet vårt.

 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__() er en spesiell Python-rutine som kalles når et objekt lages fra en klasse. Kort sagt, når vi ringer på TwitchControl, koden i __init__() løper først. Her lager vi variabler som lagrer adressen til Twitchs chat-server, porten og Twitch-påloggings- og kanaldetaljer. oauth-tokenet er hvordan Twitch-serveren vet hvem som kobler til chat-kanalen, og du kan generere din egen her.

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

Deretter lager vi en spesiell variabel kalt en ordbok, og gir den navnet voteDict. Ordbøker er flotte, siden de lar oss lagre data i pene små par. I vårt tilfelle har vi våre ønskede kommandoer, og hver av dem har et nummer ved siden av. Dette vil tilsvare antall stemmer for hver kommando i chatten. Vi initialiserer disse til 0 til å begynne med.

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

Linjene ovenfor er satt opp APscheduler å kjøre en funksjon med jevne 2 sekunders mellomrom. Den funksjonen går under navnet voteCount, og ved hvert to sekunders intervall sjekker den voteDict for å se hvilken kommando som fikk flest stemmer i chat, og deretter utfører vinneren. Vi kommer tilbake og ser på voteCount om litt. For nå, la oss se på hovedsløyfen som kjører når alt er initialisert.

 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 

Når vi kommer inn i while-løkken, må vi motta data fra IRC-serveren. Hvis dataene er "PING", svarer vi med "PONG" i henhold til vanlig IRC-praksis for å holde forbindelsen i live. Ellers renser vi dataene med demojize-funksjonen, som erstatter eventuelle emojier i meldingen med ren tekst. Deretter bruker vi strengfunksjoner for å dele opp råmeldingen fra serveren i dens komponenter: brukernavnet som sendte meldingen, og det faktiske meldingsinnholdet. På dette tidspunktet kan vi lete direkte etter en kommando, og hvis vi vil at den skal utløse meldinger direkte, kan vi gjøre det her.

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

Alternativt, hvis vi ønsker å samle kommandoer i chat og se hvilken som er kåret til den mest populære, kan vi gjøre det også. Hver gang en av følgende kommandoer oppdages, vises dets tilsvarende felt i voteDict ordboken økes med 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 

Det er alt hovedsløyfen vår gjør. Den mottar data fra IRC-serveren etter hvert som den kommer inn, behandler den og øker stemmeantallet fra innkommende kommandoer. For å faktisk handle på disse stemmene, må vi gå til vår voteCount funksjon. Takk til APscheduler rutine vi satte opp før, denne kjøres automatisk hvert annet sekund.

 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 er en enkel funksjon, en som bruker Pythons innebygde ordbokfunksjoner for å bestemme kommandoen som hadde flest stemmer. Merk at vi også sjekker om alle stemmer er lik null - i så fall må vi ikke gjøre noe, derav nullCheck-koden. Når vinneren er bestemt, kan koden for den aktuelle kommandoen utføres.

Hva vil du slippe løs på Twitch?

Det er litt mer kokekunst for å sette ting sammen, men grunnleggende sett er dette blokkene som får alt til å fungere. Ta den ekte varen fra Github hvis du ønsker å fikse hjemme. Herfra er det åpenbart bare et spørsmål om tilpasning for å forme koden til ditt spesielle formål. Hvis du ønsker å kontrollere en robot, plasser kommandoene dine for servoer eller motorer på de nødvendige stedene, eller send instruksjoner over serienummer til mikrokontrolleren din som håndterer disse oppgavene. Alternativt, hvis du jobber med et spill i en emulator, la Python-koden ganske enkelt emulere de relevante knappetrykkene.

Koden er på ingen måte optimalisert; å skrive denne artikkelen tok omtrent dobbelt så lang tid som å skrive selve koden. Det er sannsynligvis store gevinster å oppnå ved å bruke mer idealisert strengstyringskode og andre slike justeringer. Videre arbeid med å pakke alt dette inn i et ryddig bibliotek ligger igjen som en øvelse for leseren. Forhåpentligvis får du deg godt på vei til å ha litt crowdsourced moro på Twitch! Som alltid, lykkelig hacking.

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

Tidstempel:

Mer fra Hack en dag