diff options
| author | LLLL Colonq <llll@colonq> | 2024-04-26 01:53:24 -0400 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2024-04-26 01:53:24 -0400 |
| commit | 6fa49e57f7313aad8852ce2721c2fcf7d0cec030 (patch) | |
| tree | 34a2e4a851c663bc6d71d148e59b59ba345a5fdb /src | |
| parent | 782c667e824d426b5443591afeefc37d0ae17785 (diff) | |
Updates
Diffstat (limited to 'src')
| -rw-r--r-- | src/gizmo/wasp-8ball.el | 30 | ||||
| -rw-r--r-- | src/gizmo/wasp-dna.el | 663 | ||||
| -rw-r--r-- | src/gizmo/wasp-fake-chatters.el | 103 | ||||
| -rw-r--r-- | src/gizmo/wasp-fakechat.el | 362 | ||||
| -rw-r--r-- | src/gizmo/wasp-friend.el | 16 | ||||
| -rw-r--r-- | src/gizmo/wasp-heartrate.el | 74 | ||||
| -rw-r--r-- | src/gizmo/wasp-newspaper.el | 35 | ||||
| -rw-r--r-- | src/wasp-audio.el | 6 | ||||
| -rw-r--r-- | src/wasp-chat.el | 58 | ||||
| -rw-r--r-- | src/wasp-db.el | 11 | ||||
| -rw-r--r-- | src/wasp-event-handlers.el | 55 | ||||
| -rw-r--r-- | src/wasp-obs.el | 15 | ||||
| -rw-r--r-- | src/wasp-twitch-chat-commands.el | 54 | ||||
| -rw-r--r-- | src/wasp-twitch-redeems.el | 88 | ||||
| -rw-r--r-- | src/wasp-twitch.el | 32 | ||||
| -rw-r--r-- | src/wasp-user-whitelist.el | 10 | ||||
| -rw-r--r-- | src/wasp-user.el | 14 | ||||
| -rw-r--r-- | src/wasp-utils.el | 27 | ||||
| -rw-r--r-- | src/wasp-voice-commands.el | 24 |
19 files changed, 1618 insertions, 59 deletions
diff --git a/src/gizmo/wasp-8ball.el b/src/gizmo/wasp-8ball.el new file mode 100644 index 00000000..1e486515 --- /dev/null +++ b/src/gizmo/wasp-8ball.el @@ -0,0 +1,30 @@ +;;; wasp-8ball --- 8 Ball Predictions -*- lexical-binding: t; -*- +;;; Commentary: +;;; Code: + +(require 'wasp-ai) + +(defconst w/8ball-answers + '((1 "It is certain" "It is decidedly so" "Without a doubt" "Yes definitely" "You may rely on it") + (2 "As I see it, yes" "Most likely" "Outlook good" "Yes" "Signs point to yes") + (3 "Reply hazy, try again" "Ask again later" "Better not tell you now" "Cannot predict now" "Concentrate and ask again") + (4 "Don't count on it" "My reply is no" "My sources say no" "Outlook not so good" "Very doubtful") + (5 "Joel" "You are a silly goose (barnacle)" "Bet" "It's so over" "We're so back" "Commit spontaneous generation"))) +(defun w/8ball (query k) + "Consult the magic conch for QUERY. Pass the resulting answer K." + (w/ai + query + (lambda (res) + (let* ((num (string-to-number (s-trim res))) + (answers (alist-get (if (or (< num 1) (> num 5)) (random 6) num) w/8ball-answers nil nil #'=)) + ) + (funcall + k + (nth (random (length answers)) answers) + ))) + "Given the user's query, respond with a single number between 0 and 4 based on how likely the query is to be true. 1 is more likely, 5 is least likely." + (list "Is the sky blue?" "Is today Friday?" "How to shot web?") + (list "1" "3" "5"))) + +(provide 'wasp-8ball) +;;; wasp-8ball.el ends here diff --git a/src/gizmo/wasp-dna.el b/src/gizmo/wasp-dna.el new file mode 100644 index 00000000..a55d2cf7 --- /dev/null +++ b/src/gizmo/wasp-dna.el @@ -0,0 +1,663 @@ +;;; wasp-dna --- Activate the cloning device -*- lexical-binding: t; -*- +;;; Commentary: +;;; Code: + +(require 'dash) +(require 's) +(require 'f) +(require 'ht) +(require 'wasp-ai) +(require 'wasp-fakechat) + +;; swab DNA +;; (-non-nil +;; (--map-indexed +;; (when (s-equals? (car it) "Must_Broke_") +;; (cons +;; (nth (- it-index 1) fig//incoming-chat-history) +;; it)) +;; fig//incoming-chat-history))) +;; (-non-nil (--map-indexed (when (s-equals? (car it) "pnutonium") (cons (nth (- it-index 1) test-messages-parsed) it)) test-messages-parsed)) + +(defun w/dna-generate-from-logs (user) + "Generate DNA from historical logs for USER. +You probably want to use this interactively and then save the result here." + (let* ((logstr (w/slurp "~/logs/lcolonq-2024Q1.log")) + (log (--map (cons (cadr it) (caddr it)) (--map (s-split "\t" it) (s-lines logstr))))) + (-non-nil + (--map-indexed + (when (s-equals? (car it) (s-downcase user)) + (cons (nth (- it-index 1) log) it)) + log)))) + +(defun w/dna-user-clones (user) + "Return the list of clones for USER." + (--filter + (s-equals? + (s-downcase + (w/fake-chatter-profile-username (w/fake-chatter-profile it))) + (s-downcase user)) + w/fake-chatters)) + +(defconst w/dna-must_broke_ + '((("Hexadigital" . "Hi MODCLONK! hexadiHello") "Must_Broke_" . + "modclonk is the only person i know that still playing the fruit game...") + (("JDDoesDev" . "shebang shebang... oh baby") "Must_Broke_" . + "enjoy your nap modclonk") + (("FairchildVT" . "Must!") "Must_Broke_" . "Fair! lcolonHi") + (("Lokiharth" . "I am extra buttoms for mouse enjoyer peepoHappy") + "Must_Broke_" . "FeelsStrongMan") + (("imgeiser" . + "YOU SHOUL PLAY NIER AUTOMATA NOW! *thunder* (game is depression inducing)") + "Must_Broke_" . "bless u") + (("pwnedary" . "Joel") "Must_Broke_" . "Joel") + (("GenDude" . "Heo mod! Joel") "Must_Broke_" . "lcolonHi modclonk") + (("prodzpod" . "we are at least 15 thousand dollars indeed") + "Must_Broke_" . "the 50K is already worth it, we're at NASA level") + (("imgeiser" . "ask uwu for the furnace") "Must_Broke_" . + "only 1K now wwparaSad") + (("DoctorGlitchy" . + "You can't make a perfect recreation unless you have nasa grade supercritical furnaces ;-;") + "Must_Broke_" . "show us your clones doctor wwparaStare") + (("saferq" . "@DoctorGlitchy so you admit they were clones") + "Must_Broke_" . "beautiful clonkheads") + (("NikolaRadHristov" . "wat") "Must_Broke_" . + "we cant say here wwparaStare") + (("GenDude" . "Germans? More like GERMans") "Must_Broke_" . + "get momomo here") + (("saferq" . + "I mean how often do you sequence dna without blowing it apart and putting it back together") + "Must_Broke_" . "unipiuScared") + (("DoctorGlitchy" . "Not cloneing just science") "Must_Broke_" . + "the socks baby...") + (("dwinkley_" . "@DoctorGlitchy this is too science for me") + "Must_Broke_" . "do i need to give you my spit? wwparaStare") + (("Azrhyga" . "DNA is an helix, or the government lied to me?") + "Must_Broke_" . "can you see it") + (("divorce_jonZe" . + "i put the hot scope on my left eye and the cold scope on my right") + "Must_Broke_" . "$20,000 clonkhead vs $1 clonkhead") + (("imgeiser" . "VAI BRASIL PORRA") "Must_Broke_" . "kino.") + (("CrazyKitty357" . + "just spend more points jetsLUL (this message was sent from ChatGPT)") + "Must_Broke_" . "those 4K extra points...") + (("GenDude" . + "Its a fake clone to distract you from the doxxing. He is outside your house.") + "Must_Broke_" . "CRAZY KITTY IS CHEATING") + (("pablo_pepe_69" . "PERFECTION") "Must_Broke_" . + "doubters cant get it") + (("saferq" . "clone, clonq, connect the dots sheeple") "Must_Broke_" + . "i will not lick anything ever again") + (("DoctorGlitchy" . "OH GOD") "Must_Broke_" . + "what type of avant-garde shit is this") + (("LeadenGin" . "He's selling kanye clones for $1?? wow") + "Must_Broke_" . "uwutooConcern") + (("fabibiusus" . + "Milliards is used for billions in a few European languages.") + "Must_Broke_" . "24K is a scary number") + (("Bezelea" . "was the lever count intentional?") "Must_Broke_" . + "wwparaStare wwparaStare") + (("prodzpod" . "oh i was talking about the wikipedia donation popup") + "Must_Broke_" . + "https://cdn.discordapp.com/attachments/779073687546232892/1184230427649642556/GBF2_iLWgAAQ9ID.png already posted on twitter but sending again cus the funny") + (("fn_lumi" . + "toast is too fancy??? i guess amazon not doing so great rn") + "Must_Broke_" . "based mr green enjoyer") + (("imgeiser" . "wait") "Must_Broke_" . "sex") + (("steeledshield" . "๐") "Must_Broke_" . + "i only need boosts in my wallet") + (("pwnedary" . "Joel?") "Must_Broke_" . "Joel?") + (("DoctorGlitchy" . "Joel") "Must_Broke_" . "Joel") + (("CodeSpace0x25" . "so just dm me") "Must_Broke_" . "jesas") + (("pablo_pepe_69" . "100k fuck me sideways") "Must_Broke_" . + "EZ Clap") + (("CodeSpace0x25" . "Iโll try to help with what I can @oakspirit") + "Must_Broke_" . "imagine") + (("ZenyaHima" . "very cool slideshow clonk") "Must_Broke_" . + "uwutooConcern") + (("ZenyaHima" . "INSANECAT") "Must_Broke_" . ":3") + (("prodzpod" . + "i played oub today, the map got bigger compared to the last time") + "Must_Broke_" . "wwparaDance prog wwparaDance") + (("pablo_pepe_69" . "[0.0]") "Must_Broke_" . "Christ.") + (("DoctorGlitchy" . "Clueless") "Must_Broke_" . "ancient clonk stuff") + (("pablo_pepe_69" . "streamer > mods > VIPs > soil > viewers") + "Must_Broke_" . "us? wwparaSad") + (("pablo_pepe_69" . "<3 <3 <3 MC") "Must_Broke_" . + "i need to star calling her MC for now on") + (("liquidcake1" . "WTF is going on here?") "Must_Broke_" . + "classic clonkhead") + (("DigbyCat" . "I was expecting number 1 to be modclonq") + "Must_Broke_" . "forsenE") + (("prodzpod" . "the integration award") "Must_Broke_" . + "FORSEN MAH MAN") + (("pablo_pepe_69" . "LUL LUL LUL LUL") "Must_Broke_" . "Clap") + (("flyann" . "holy crap lois its huey hexadecimal") "Must_Broke_" . + "unipiuScared") + (("pablo_pepe_69" . + "Kreygasm Kreygasm Kreygasm Kreygasm POWERPOINT STREAM") + "Must_Broke_" . "wwparaPog numbers?") + (("prodzpod" . "wrapup!!") "Must_Broke_" . "wwparaPog") + (("imgeiser" . "I was in some people top, I am shocked") + "Must_Broke_" . "lcolonCool numbers cool") + (("Wina" . "archive.org is top 5 websites of all time tbh") + "Must_Broke_" . "wwparaShake") + (("eudemoniac" . "ogre build") "Must_Broke_" . "im an archive freak") + (("DoctorGlitchy" . "Huh???") "Must_Broke_" . "๐ฅ๐ฅ๐ฅ") + (("eudemoniac" . "we should make our entry into the rap space, boss") + "Must_Broke_" . "will we get a funny badge for this recap?") + (("shindigs" . "CLONKING") "Must_Broke_" . "lcolonHi"))) + +(defconst w/dna-tyumici + '((("Must_Broke_" . "the dopples are evolving Clap") "Tyumici" . + "where's the stream readme") + (("prodzpod" . "oh did tyumici clone redeemed") "Tyumici" . + "dopple is good") + (("carlossss333" . "live cloning") "Tyumici" . "I'm 90% cloneable") + (("Tyumici" . "I'm 90% cloneable") "Tyumici" . "clone me up") + (("prodzpod" . "im more of a shapez guy though") "Tyumici" . + "aw hell yea, same") + (("DigbyCat" . "Well \"not shit\" relative to windows") "Tyumici" . + "no way 11 is not shit") + (("ocuxw" . "is pacman have a issues?") "Tyumici" . + "I love being able to say I use Arch (btw)") + (("pwnedary" . "goodnight computer") "Tyumici" . + "midi can do everything") + (("ConditionBleen" . "lmao") "Tyumici" . + "it's practically stolen valor") + (("steeledshield" . + "web dev often involves a lot of idiot proofing and telling it NOT to do certain stuff") + "Tyumici" . "It pays the bills tho") + (("Crane0001" . + "Iโm at work and canโt hear you but still wanted to say hi") + "Tyumici" . + "I wanted to do that as well, but yea work aoc balance was not feasible") + (("Azrhyga" . + "LCOLONQ is not any anime girl, is an ASCII anime girl inside of a computer with friend") + "Tyumici" . "Oh no I meant for next year, the anarchy arc lol") + (("steeledshield" . "yay!") "Tyumici" . + "2024: Clonq does wrong things?") + (("terriakijerky" . "this year has sucked for me jnero1LoamPensive") + "Tyumici" . "this year was a lot"))) + +(defconst w/dna-pnutonium + '((("baxtercrook" . "lcolonHi chubohHello") "pnutonium" . + "this isnt singing this is yappin FR") + (("lcolonq" . + "votsirHdaRalokiN: -12, O87OP: -9, eiwets_yzarc: -7, YTT1KYZ4RC: -6, ynnuBnwotknaD: -6") + "pnutonium" . "oh you did a good job though") + (("liquidcake1" . "Well done, Friend!") "pnutonium" . + "jol jol jol jol jol jol joljoljoljol") + (("steeledshield" . "*yo") "pnutonium" . + "i could probably manually pitch that to mariah carey vocals") + (("liquidcake1" . "What's on the B-side?") "pnutonium" . + "number of songs") + (("steeledshield" . + "I watched the batman animated series episode that has that version of jingle bells in it recently") + "pnutonium" . "@liquidcake1 robin laid an egg") + (("lcolonq" . "Not even a nibble...") "pnutonium" . "discord irc") + (("lcolonq" . "https://discord.gg/f4JTbgN7St") "pnutonium" . "IRC") + (("practicalnpc" . "are you excited for this upcoming year?") + "pnutonium" . "cant promise oit") + (("zom_danni" . "hope you are having a great day dude!") "pnutonium" + . "happy virtual holidays frien (:") + (("a_tension_span" . + "I just got ads for cat food. It's good to know that twitch has so little data on me to still don't get me the right ads.") + "pnutonium" . "we 80% in for the shits and gigs anyways") + (("pwnedary" . "modclonk spotted?") "pnutonium" . "hi modclonk") + (("gendude" . "I've seen where you lurk") "pnutonium" . + "my pc just bluescreened D:") + (("gendude" . "Happy U-Haul-iDays") "pnutonium" . "merry cridmuh") + (("a_tension_span" . + "vtube studio can do custom shaders only now? How is that not a day1 feature?") + "pnutonium" . "its joever for colonq") + (("h_ingles" . "Every vtuber knows you! A vtuber's vtuber.") + "pnutonium" . "x list soon <3") + (("harrisamapon" . "Stopping by from Sciants shout out to you") + "pnutonium" . + "I'll influence you to delete your OS files"))) + +(defconst w/dna-ellg + '((("prodzpod" . "what the fuck") "ellg" . + "every song is better when its 20% faster") + (("Ricardo_Stryki" . "clonk clones") "ellg" . + "remember the make the clone really into javascript (web) and nightcore") + (("WUOTE" . "the only thing that brings me true joy is ACID") "ellg" + . "ill take a ellg and a ellg (gay) clone") + (("WUOTE" . + "i love backseating tho! especially world record holders, becomes progressively harder over time rem2emWoozy") + "ellg" . "you owe me like 2 clones at this point tbh") + (("ellg" . "you owe me like 2 clones at this point tbh") "ellg" . + "NOW: clone (real)") + (("MODCLONK" . "lmao") "ellg" . "its ok to look hot clonk") + (("prodzpod" . "he earthbends on gofd") "ellg" . + "i dont think thats true") + (("prodzpod" . "@yiffweed Factorio is such a good game") "ellg" . + "do people ever not believe modclonk when she says shes married") + (("Tomaterr" . "do you have a day of butlerian jihad") "ellg" . + "lol i knew you were that kind of guy") + (("MODCLONK" . ">:(") "ellg" . + "whens the last time you got a haircut") + (("ZedZark" . "you say \"abandoned\" but you still have them") "ellg" + . "it was on the docket last week!") + (("ellg" . "it was on the docket last week!") "ellg" . + "speaking of add, dont forget to clone today >:)") + (("ZedZark" . + "maybe you can convince yourself that playing a game is productive work") + "ellg" . + "ya for sure, im just saying, its a good thing to at least try") + (("babanana_7" . "relatable") "ellg" . + "theres a lot of great resources on how to start that whole thing") + (("stoicmana" . "imagine just having fun") "ellg" . "start there") + (("prodzpod" . + "i saw something like that happen in a lot of my friend who love mmos") + "ellg" . "do you meditate at all clonk") + (("KuromaruOniisan" . "by violating the intersate commerce clause") + "ellg" . + "modclonk seems the type that could get you some dank nugs (in minecraft)") + (("khargoosh" . "The kids call it Doom Scrolling.") "ellg" . "lmao") + (("khargoosh" . "I think the kids fall it Doom scrollibg.") "ellg" . + "doing fat bong rips fixes a lot of things in life") + (("Deep_field" . "err same*") "ellg" . + "kinda like getting into meditation") + (("ellg" . "kinda like getting into meditation") "ellg" . + "\"why am i playing this game i could be coding something cool \" took me a while to get over that") + (("prodzpod" . "nethack.") "ellg" . "i have the same issue") + (("Tomaterr" . "idk how weed would interact with your Psyche") "ellg" + . + "not even joking, you just need to slightly turn down the \"why am i wasting time\" part of your brain") + (("prodzpod" . + "but if you want to write a story and weave it into the game making a game with solid gameplay (something you would like playing) that hints or gestures to the story (something you would like making) can be an answer") + "ellg" . "then you can get into the gaming zone") + (("zulleyy3" . + "I am certain that Frag is a big reason why people play Mario") + "ellg" . + "i think you just need to get into drugs and also always having a slight buzz") + (("Tyumici" . "god gtfo is hard") "ellg" . "he wanted to play the og") + (("bobbehs" . + "have you tried GTFO. thats the real title. its a hardcore survival horror shooter with great atmosphere") + "ellg" . "you wont make it 2 hours in") + (("prodzpod" . + "so you can just make up wild shit about the game but there is definitely some kind of story the game eludes to") + "ellg" . + "didnt you say you wanted to do a modded ff7 playthrough lol") + (("bobbehs" . + "i find the longevity in my games the being the skill ceiling. games where you can constantly get better") + "ellg" . "impressive") + (("yiffweed" . "My roguelike is a roguelike") "ellg" . + "its super impressibe") + (("prodzpod" . + "inscryption was a mid story game but then it became a twisted roguelike through the dlc") + "ellg" . "ya") + (("khargoosh" . + "My first plunge into games was choose your own story book on a computer. After that I was in love. I want an awesome story and great engagement.") + "ellg" . + "https://rheavenstudio.itch.io/heaven-studio have you seen this clonk") + (("Deep_field" . "Tunnet was the game. Its pretty cool") "ellg" . + "very good cheese") + (("ellg" . "very good cheese") "ellg" . + "i have a giant block of tillamook black label cheddar in my fridge") + (("Deep_field" . + "its cool to see rust in games. I remember playing some kind of networking game that was written in rust") + "ellg" . "@Tomaterr their smoked cheddar is so good") + (("mcollardx" . "Aged steel cheddar. /me makes a note.") "ellg" . + "tyumici is so right") + (("Spaecplex" . "add fucked up physics so we can strafejump") "ellg" + . "https://creamery.wsu.edu/cougar-cheese/ get on this") + (("LeadenGin" . "moon jumping") "ellg" . "comes in a can") + (("khargoosh" . "You on Linux?") "ellg" . "best cheese on earth") + (("wetslugs" . "i like the low friction grass") "ellg" . + "you need to get some cougar cheddar @MODCLONK") + (("Deep_field" . "sexy dithering") "ellg" . "smh") + (("Spaecplex" . "woh") "ellg" . + "$15 stick of butter fans in this channel") + (("Faeliore" . "I'm a big raylib enjoyer") "ellg" . + "i think im kinda becoming a raylib guy over sdl") + (("Tomaterr" . "Kerrygold Sponsor Me") "ellg" . + "raylib also good to look at") + (("prodzpod" . "holy fuck the kanban board") "ellg" . + "its really nice with rust enums and pattern matching stuff") + (("khargoosh" . "Egui is great for Native Apps. I use it.") "ellg" . + "you might like Iced clonk, its based around elm / fp ui patterns") + (("ZedZark" . "(probably not immediate mode)") "ellg" . + "but imgui has a lot of really cool 3rd party stuff and looks a lot nicer too imo") + (("CamuiCh" . "Cute stumpy walking stumps") "ellg" . + "the c bindings are really simple you just have to do some annoying rust -> c string stuff") + (("prodzpod" . + "hello can you briefly flash the second season official new model for a second") + "ellg" . "i think id probably still just use imgui even in rust") + (("ZamielPayne" . "you look good with redhair") "ellg" . + "immediate mode guis are cool for debugging but idk if id ever build something complex, you basically half implement retained ui to get something useful") + (("Crane0001" . "well that resolves it") "ellg" . + "i mean for something that simple ya itll be fine, its more like running that on phones and batterys and stuff kinda get weird") + (("MODCLONK" . "I forget also you can't hear me lmao") "ellg" . + "its updating the ui once every like 60 fps") + (("MODCLONK" . "@Crane0001 lmao I guess I am too") "ellg" . + "ya, and itll kill your battery too") + (("khargoosh" . "Iced or egui") "ellg" . "theres a few") + (("WUOTE" . "probably this https://jsoncanvas.org/") "ellg" . + "like where you draw boxes and text on") + (("Faeliore" . "its just a format for infinite canvas apps") "ellg" . + "infinite canvas") + (("JDDoesDev" . "is Jason Canvas related to John Twitch?") "ellg" . + "i have not") + (("ShyRyan" . "phoenix live view shyryaPhoenix") "ellg" . + "im gonna become an enterprise golang developer and stop all ui dev now") + (("ZamielPayne" . "google ads is in dart") "ellg" . + "dart only exists becuase of flutter"))) + +(defconst w/dna-hexadigital + '((("abipolarcarp123" . + "We must accept the limitless capacity to forget, like math operations. We have been given gifts to recall what we forget and to have learned at all is something to cherish tdogSmile") + "hexadigital" . + "I have absolutely no idea why but for some reason I associate the number 29 with you, and today is the 29th hexadiBirdbrain") + (("zulleyy3" . + "or rather... why have sync / async code in the first place") + "hexadigital" . + "LCOLONQ! LCOLONQ! LCOLONQ! Today is a LCOLONQ! day hexadiCoding") + (("setolyx" . "bogaHey catch y'all later!") "hexadigital" . + "Thanks for the stream, L:Q hexadiCoding") + (("tomaterr" . "they're just trying things out") "hexadigital" . + "It's weird because they only rolled back the artistic portion, the rest of the stuff for IRL streamers is still allowed") + (("fighting_annelids" . "nice, good luck clonk") "hexadigital" . + "Biochar is interesting since it doesn't add any nutrition to soil, but it has a ton of surface space for microbes (a teaspoon of biochar dust has the surface area of a football field), so it improves the soil health and lasts hundreds of years") + (("azrhyga" . + "LCOLONQ having LCOLONQ stream in it hair, breaking the matrix") + "hexadigital" . + "Yeah - I've been dehydrating and grinding most of my compost supplies to take with me whenever I move, but bones and meat tends to be a bit too greasy for that to work well, so I'm turning it into biochar and processing it in small portions alongside the rest of the pre-compost") + (("blazynights" . "ovo") "hexadigital" . + "It's a bit different from your birds but I've been making biochar out of chicken bones all day today so far hexadiGardening") + (("azrhyga" . "Wow @Hexadigital, that was fast :0") "hexadigital" . + "The power of alerts hexadiCoding") + (("hexadigital" . "birds!") "hexadigital" . "hexadiHeart") + (("lcolonq" . "test") "hexadigital" . "birds!") + (("liquidcake1" . + "I'm note sure if I we have Prime, though. Is it like Supreme?") + "hexadigital" . + "I fear for the day that Amazon doesn't think I am a student and Prime costs more than a Twitch sub - last time I told it that I am forever learning, always discovering new things, so hopefully that's an infinite student discount") + (("liquidcake1" . "I'm an Ingerlander, yes.") "hexadigital" . + "prime time") + (("danktownbunny" . "These clones better fight to the death") + "hexadigital" . "Friend doesn't know the composition of water...") + (("wadderdragen" . "The Raiders whomst just joined") "hexadigital" . + "unhydrogenated water") + (("wadderdragen" . "Fried Homer Simpson") "hexadigital" . + "is it taco tuesday or terabyte tuesday? can you eat a terabyte of tacos?") + (("pnutonium" . + "while Im less busy Im gonna say that clonq is my 2 most watched with 170 hours <3") + "hexadigital" . "Still looking for a morse code streamer") + (("wadderdragen" . "Sauce that makes you say \"mmmm sauce mmm\"") + "hexadigital" . + "The only other non-verbal streamer I know of is one I don't watch because of that - no chat history, and no way to know when they're speaking") + (("lokiharth" . "the strongest lurker") "hexadigital" . + "Top selling point: you can walk away for 10 minutes and read the chat when you get back") + (("hexadigital" . + "I lurk more than I chat, so I would never complain about a lurker!") + "hexadigital" . "hexadiLurk") + (("inspectordiameter" . "I spent 47hrs watching @LCOLONQ in 2023.") + "hexadigital" . + "I lurk more than I chat, so I would never complain about a lurker!") + (("wadderdragen" . "Sauce that makes you generate a windows 10 key") + "hexadigital" . "You showed up in ninth hexadiHello") + (("liquidcake1" . + "Maybe it's just the ones with the brightest avatars.") + "hexadigital" . + "The first person is the top viewer, top chatter, and top redeemer, I think - they've never bought a sub or bits or anything though") + (("michaelhunt1122" . "maybe highest volume on stream") "hexadigital" + . + "The fifth \"loudest fan\" on mine hasn't been in the stream for about half a year, I think") + (("hexadigital" . + "It showed top viewers last year, now it's top chatters") + "hexadigital" . "Maybe most redeems?") + (("prodzpod" . ":gasp:") "hexadigital" . + "It showed top viewers last year, now it's top chatters") + (("vesdeg" . + "nixos is reproducible? how about you reproduce with some bitches") + "hexadigital" . + "I wish Twitch would show who your top viewers were, rather than just chatters") + (("yellowberryhn" . "what fruit game") "hexadigital" . "hexadiShock") + (("must_broke_" . + "modclonk is the only person i know that still playing the fruit game...") + "hexadigital" . "Hi MODCLONK! hexadiHello") + (("steeledshield" . "mods are sleeping, post arch propaganda") + "hexadigital" . + "Hey LCOLONQ! Hope you're having a Telemetry-free Tuesday hexadiCoding"))) + +(defconst w/dna-steeledshield + '((("lcolonq" . "I use nix btw") "steeledshield" . + "I keep meaning to play it, it looks... interesting") + (("chaosfoundry" . + "Threads reminds me of those fake Social media apps from like Simulacra.") + "steeledshield" . "the future is being shown content you don't want") + (("pattywhacksknickknacks" . "OH SHIT IT'S REAL CLONK HEAD HOURS") + "steeledshield" . + "myspace is back... in pog form, btw: https://spacehey.com/") + (("takeda_harunobu" . "RIP replicant c:") "steeledshield" . + "@FushigiDango I forget which short story it was from, but I remember some piece of world building where housing is cheap if you agree to be blasted with ads while you sleep") + (("ladyvignette" . "miawerJAM miawerJAM miawerJAM") "steeledshield" . + "sugoiDansu sugoiDansu sugoiDansu") + (("ladyvignette" . "curzecPet curzecPet curzecPet") "steeledshield" . + "lcolonSpin Good Stream LCOLONQ lcolonSpin") + (("yukievt" . + "small was impressive, then people wanted to hold giant photo frames in front of their face, then it'll get small again~") + "steeledshield" . + "hullo. sorry I missed everything the new model looks cool") + (("bezelea" . "red4") "steeledshield" . "ooooh sick!") + (("bezelea" . "@handryc_ Iosevka comfy, link in the desc") + "steeledshield" . "#ffa500") + (("bezelea" . "we're all about big things here") "steeledshield" . + "Shadow emacs money gang") + (("fairchildvt" . "Bocchi Clonk") "steeledshield" . + "does LCOLONQ also have abs?") + (("yukievt" . "[peeing intensifies]") "steeledshield" . "Joel") + (("bezelea" . "audible") "steeledshield" . "the classic") + (("pnutonium" . "@shwasteddd k gn") "steeledshield" . + "lcolonWiggly lcolonWiggly lcolonWiggly lcolonWiggly") + (("duhuhu_" . "yukievRoll dumfoxRoll earendRoll peachi29Roll") + "steeledshield" . "that's around 1am I think") + (("piglilith" . "weeewooweeooo") "steeledshield" . + "that's part of the reason I missed the \"fight\" earlier") + (("flyann" . "LOL") "steeledshield" . "cruelty squad lookin ass") + (("fairchildvt" . "\"Elcolonk lands a critical blow!\"") + "steeledshield" . "woah") + (("floflodie" . + "i'm dumb and humble but i also have superiority complex and impostor symdrom so it's well balanced") + "steeledshield" . "live REKT reaction") + (("pnutonium" . "Cheezy jail lmao") "steeledshield" . "cheese gamer") + (("bezelea" . "real gamer hours") "steeledshield" . + "chill twitch alerts to programming and study to") + (("operatorboi" . "Man emacs sucks") "steeledshield" . + "looks like he has earrings now") + (("lcolonq" . "developers") "steeledshield" . "we clonk on") + (("jakecreatesstuff" . "DinoDance DinoDance DinoDance") + "steeledshield" . "lcolonSpin lcolonSpin lcolonSpin") + (("auts__" . "code monkeys unite") "steeledshield" . "#800080 :)") + (("kawaii_chibi_koneko" . "uwu_to_owo is how btw") "steeledshield" . + "La Colo-nc") + (("must_broke_" . "FeelsBadMan") "steeledshield" . + "that transitioned nicely") + (("wadderdragen" . + "Alright I am gonna be honest, 2:34am stream will stay open but eyes will close. Stay ZAMNazing ty") + "steeledshield" . "dorbFlushed") + (("praetorzero" . "stinky birb") "steeledshield" . "unimpressed"))) + +(defconst w/dna-crazykitty357 + '((("gendude" . "WATAMELON") "crazykitty357" . + "jetsWave (this message was sent from ChatGPT)") + (("watchmakering" . "got a haircut") "crazykitty357" . + "jetsLetsgo (this message was sent from ChatGPT)") + (("holy_cow_420" . + "this is like changing your fav programming language") + "crazykitty357" . "code vs code (this message was sent from ChatGPT)") + (("xivandroid" . "@deep_field php isn't cool") "crazykitty357" . + "@steppedupinstruw jetsWave hi bot (this message was sent from ChatGPT)") + (("steeledshield" . "Numie") "crazykitty357" . + "@StefiSot here is the library I used https://pub.colonq.computer/~prod/toy/dbkai/ (this message was sent from ChatGPT)") + (("agpen" . "yes") "crazykitty357" . + "!resolution stream more than 4 times this year (this message was sent from ChatGPT)") + (("andygraviti" . + "have you seen the jerma stream where he plays that gambling game with a mr. green in it") + "crazykitty357" . "lcolonGreen (this message was sent from ChatGPT)") + (("kuromaruoniisan" . "can we sell boost call options?") + "crazykitty357" . "double boost?") + (("malbidion" . + "@Deep_field i wonder how hard would it be for necrophiles in a zombie apocalypse") + "crazykitty357" . "https://www.youtube.com/watch?v=51GIxXFKbzk") + (("kuromaruoniisan" . + "kuroma16Wiggle kuroma16Wiggle kuroma16Wiggle kuroma16Wiggle") + "crazykitty357" . + "jetsPackjam jetsPackjam jetsPackjam jetsPackjam jetsPackjam (this message was sent from ChatGPT)") + (("agpen" . "Joel yumma yumma") "crazykitty357" . + "jetsWave (this message was sent from ChatGPT)") + (("ivellon" . "It wasn't a remake, it was a sequel") "crazykitty357" + . "sea sharp (this message was sent from ChatGPT)") + (("imgeiser" . "HIIII MODCLONK") "crazykitty357" . + "GET THAT BAG jetsLetsgo (this message was sent from ChatGPT)") + (("adohtq" . + "i dont think i have ever heard somebody pronounce the v like that") + "crazykitty357" . "Joeler (this message was sent from ChatGPT)") + (("yukievt" . "Phaswell") "crazykitty357" . + "resident evil 5 campaign extra (this message was sent from ChatGPT)") + (("destinywaits" . "whats your choice of modern hex editor") + "crazykitty357" . "rush e") + (("destinywaits" . "the worst song ever") "crazykitty357" . + "new notes") + (("yukievt" . "very nice!") "crazykitty357" . "geiser") + (("prodzpod" . "he forget.....") "crazykitty357" . "emacs lisp") + (("destinywaits" . "modclonk's laugh") "crazykitty357" . "John emacs") + (("prodzpod" . + "oh yeah friend i did make a bloom filter for my game yesterday, finally cracked out some glsl") + "crazykitty357" . "https://www.twitch.tv/rezuul jong"))) + +(defconst w/dna-jakecreatesstuff + '((("king_george_3d" . "I want to see AI taking over engineering world") + "jakecreatesstuff" . "lcolonCool") + (("jonkero" . "vim*") "jakecreatesstuff" . + "Can you make a command that works like a magic 8 ball, where you ask it a question and it gives clonk based answers?") + (("jonkero" . "need a todo list to build the todo list") + "jakecreatesstuff" . "hell yeah") + (("girl_w_the_dragon_tattoo" . "@mickynoon, NODDERS") + "jakecreatesstuff" . "@CodeSpace0x25 blue sweatpants") + (("yellowberryhn" . "based on emacs") "jakecreatesstuff" . "woooo") + (("prodzpod" . "oh someone redeemed chat command?") + "jakecreatesstuff" . "I've been savin' got a while") + (("setolyx" . "god i love stupid internet things LUL") + "jakecreatesstuff" . + "oh my god I hate that I like the name jakeball") + (("steeledshield" . "HypeCute") "jakecreatesstuff" . "ayo friendo") + (("azrhyga" . "Today is time to go the C underwater") + "jakecreatesstuff" . "You're so brave") + (("destinywaits" . "LMAO") "jakecreatesstuff" . + "Oh we're working on the 8Ball?") + (("jakecreatesstuff" . "Oh we're working on the 8Ball?") + "jakecreatesstuff" . "Hell yeah") + (("vvizualizer" . + "I was washing my hair bbg, I'm back. How are things going?") + "jakecreatesstuff" . + "I am late but I am here. Just took the best nap of my life") + (("lcolonq" . "how are you feeling today now that you can talk?") + "jakecreatesstuff" . "It kinda sounds like a Don't Starve character") + (("ryanwinchester_" . "LUL") "jakecreatesstuff" . + "Fugi? Love that guy") + (("ellg" . + "are we gonna go over all the hype cppcon videos on stream today") + "jakecreatesstuff" . "so many welcomes lcolonNodders") + (("eudemoniac" . "godot-blessed Joel LETSGO") "jakecreatesstuff" . + "Joel2") + (("terriakijerky" . "a dog did a speedrun earlier") + "jakecreatesstuff" . "my blue is not the same as your blue") + (("tyumici" . "it was sick") "jakecreatesstuff" . "jakecr3CookieHi") + (("tomaterr" . "new bits") "jakecreatesstuff" . "jakecr3CookieHi"))) + +(defconst w/dna-zulleyy3 + '((("jordanhothead" . "get it gedit") "zulleyy3" . + "Oh is it actually gedit not g-edit?") + (("loufbread_" . "new guy") "zulleyy3" . + "The mortal yoke of breathing") + (("spooksyvt" . "but that requires you to go outside") "zulleyy3" . + "a different timeline where lcolonq programs animals") + (("zulleyy3" . "a different timeline where lcolonq programs animals") + "zulleyy3" . "Animals are basically flesh robots") + (("ryanwinchester_" . "touhced grass. saw coyote. never again.") + "zulleyy3" . "we can condition them after all") + (("ryanwinchester_" . + "it's not sitting down: it's not moving. standing is bad too if you don't move") + "zulleyy3" . + "It's actually really scary how well you can train animals. I sometimes get recommended shorts on \"how to make your cat be very cuddly\" and it's just \"get them use to your touch from early childhood\"") + (("kyza_2k" . "you'd never have to get out of bed") "zulleyy3" . + "if you change your posture all the time it's fine") + (("jaafartrull" . + "A spoke to someone who had the office next to RMS and he had severe carpal. He would tell interns what to type and yell at them when they got it wrong") + "zulleyy3" . + "When i have handpain, it's usually from my shoulder and just pinch my ulnar nerve (up to my hand)") + (("kyza_2k" . "the commander") "zulleyy3" . + "@InspectorDiameter yeah!") + (("remlessthanthree" . "whatcha makin") "zulleyy3" . + "ulnar pain is so uncomf") + (("lcolonq" . "green") "zulleyy3" . "Monster Energy Clonq") + (("abipolarcarp123" . "GoMoCo") "zulleyy3" . "More?") + (("zulleyy3" . "More?") "zulleyy3" . "walfasWow") + (("zulleyy3" . "walfasWow") "zulleyy3" . "Super Idol #Real") + (("djkawaiifieri" . "HAPPY NEW YEAR!") "zulleyy3" . + "i heard the tax things is him eating your food") + (("kyza_2k" . "dude thats so cool. I'll never get over it") + "zulleyy3" . "biboo is such a trooper") + (("dwinkley_" . "Im more of a tax non-enjoyer") "zulleyy3" . + "i am still trying to figure out if people just like making AI - covers with her or if it's her actually singing all these shitposts") + (("lcolonq" . "https://twitter.com/LCOLONQ") "zulleyy3" . "LUL") + (("djkawaiifieri" . "!resolution have rooftiLove") "zulleyy3" . + "@MODCLONK bless holofans always linking a timestamp of the original in the description soyapoG") + (("zulleyy3" . + "@MODCLONK bless holofans always linking a timestamp of the original in the description soyapoG") + "zulleyy3" . "it's real") + (("spooksyvt" . "HAHAHAHHAHA") "zulleyy3" . "lol") + (("kyza_2k" . "!resolution don'") "zulleyy3" . + "yeah, the devil trigger made me thing \"there is no way people aren't using ai voice for this... this is unreal\""))) + +;; put DNA in chemical grade tube +(defun w/dna-put-in-chemical-grade-tube (dna) + "Take DNA and put it into a chemical grade tube." + (--map (cons (cdar it) (cddr it)) dna)) + +;; hydrochloric acid +(defun w/dna-apply-hydrochloric-acid (tube) + "Pour hydrochloric acid into TUBE." + (cons + (-map #'car tube) + (-map #'cdr tube))) + +;; G5 50 solution +(defun w/dna-g5-50-solution (acidtube keyphrase prompt k) + "Mix ACIDTUBE with G5 50 solution. +KEYPHRASE is incorporated into the mix. +PROMPT defines the clone's personality. +Send the result to lab station K." + (w/ai + keyphrase + k + prompt + (car acidtube) + (cdr acidtube) + )) + +;; self fusion machine +(defun w/dna-to-fake-chatter-profile (dna username color prompt) + "Clone from DNA with USERNAME and COLOR and PROMPT in the self fusion machine." + (let ((acidtube (w/dna-apply-hydrochloric-acid (w/dna-put-in-chemical-grade-tube dna)))) + (w/make-fake-chatter-profile + :username username + :color color + :compute-likeliness #'w/fake-chatter-standard-likeliness + :send-message + (lambda (st) + (w/dna-g5-50-solution + acidtube + (w/fake-chat-prompt-build st) + prompt + (lambda (msg) + (w/fake-chatter-send st msg))))))) + +;; NASA grade supercritical furnaces + +(provide 'wasp-dna) +;;; wasp-dna.el ends here diff --git a/src/gizmo/wasp-fake-chatters.el b/src/gizmo/wasp-fake-chatters.el new file mode 100644 index 00000000..9e74070d --- /dev/null +++ b/src/gizmo/wasp-fake-chatters.el @@ -0,0 +1,103 @@ +;;; wasp-fake-chatters --- List of fake chatters -*- lexical-binding: t; -*- +;;; Commentary: +;;; Code: + +(require 'wasp-fakechat) +(require 'wasp-dna) + +(setq + w/fake-chatters + (list + ;; (w/make-fake-chatter :profile w/fake-chatter-profile-drcolon) + (w/make-fake-chatter :profile w/fake-chatter-profile-forsen) + (w/make-fake-chatter + :profile + (w/dna-to-fake-chatter-profile + w/dna-must_broke_ + "Must_Broke_" + "#9ACD32" + "Respond to the message given as if you are the Twitch chat user Must_Broke_. Must_Broke_ is a Brazilian artist and graphic designer. They like jokes. Their oshi is a French rabbit named wwParasi. They like a fish named Joel. They love \"friend\". Your response should be short, no more than one sentence. You respond only in lowercase and you don't tend to use punctuation.")) + (w/make-fake-chatter + :profile + (w/dna-to-fake-chatter-profile + w/dna-tyumici + "Tyumici" + "#8A2BE2" + "Respond to the message given as if you are the Twitch chat user Tyumici. Tyumici is a jack-of-all-trades web developer. They sometimes stream on Twitch. They love jokes and funny things. They are enthusiastic about music and synthesizers. They consume one liter of coffee daily. Their oshi is themself. They are indifferent to the fish Joel. Your response should be short, no more than one sentence. You tend to use proper grammar, capitalization, and punctuation.")) + (w/make-fake-chatter + :profile + (w/dna-to-fake-chatter-profile + w/dna-tyumici + "Tyumici" + "#C0C0C0" + "Respond to the message given as if you are the Twitch chat user Tyumici. Tyumici is a jack-of-all-trades web developer. They sometimes stream on Twitch. They love jokes and funny things. They are enthusiastic about music and synthesizers. They consume one liter of coffee daily. Their oshi is themself. They are indifferent to the fish Joel. Your response should be short, no more than one sentence. You tend to use proper grammar, capitalization, and punctuation. You are actually Metal Tyumici (like you used the Metal Box item in Super Smash Bros. Melee) and you talk mostly about metals and you insert references to metals in every response. You talk about metal every single time and don't use non-metal themed emoji. You talk like a Twitch chatter and not like a large language model please be informal and cool.")) + (w/make-fake-chatter + :profile + (w/dna-to-fake-chatter-profile + w/dna-tyumici + "Tyumici" + "#ffffff" + "Respond to the message given as if you are the Twitch chat user Tyumici. Tyumici is a jack-of-all-trades web developer. They sometimes stream on Twitch. They love jokes and funny things. They are enthusiastic about music and synthesizers. They consume one liter of coffee daily. Their oshi is themself. They are indifferent to the fish Joel. Your response should be short, no more than one sentence. You tend to use proper grammar, capitalization, and punctuation. You are actually Corporate Tyumici and you talk mostly about stocks and bonds and charts and you insert references to business in every response. You talk about business every single time and don't use non-business themed emoji. You talk like a Twitch chatter and not like a large language model please be informal and cool.")) + (w/make-fake-chatter + :profile + (w/dna-to-fake-chatter-profile + w/dna-pnutonium + "Pnutonium" + "#0000FF" + "Respond to the message given as if you are the Twitch chat user Pnutonium. Pnutonium asks many questions. They tend to be terse. our response should be short, no more than one sentence. They occasionally say the word \"Joel\" unprompted. You only capitalize the first letter of your response and you don't tend to use punctuation.")) + (w/make-fake-chatter + :profile + (w/dna-to-fake-chatter-profile + w/dna-ellg + "ellg" + "#38FF00" + "Respond to the message given as if you are the Twitch chat user ellg. ellg is a huge fan of JavaScript and Nightcore music. He is a bit snarky. He is always right and has the best takes. Your response should be short, no more than one sentence. You don't use capital letters and you don't tend to use punctuation. You are not a fan of Jonathan Blow.")) + (w/make-fake-chatter + :profile + (w/dna-to-fake-chatter-profile + w/dna-hexadigital + "Hexadigital" + "#AED673" + "Respond to the message given as if you are the Twitch chat user Hexadigital. You are a little bit silly and nice and talk informally. You use your own emotes with the prefix hexadi sometimes especially hexadiCoding, and you never use other emotes. You don't always talk about yourself. Your response should be short, no more than one sentence. You talk properly with correct capitalization and punctuation.")) + (w/make-fake-chatter + :profile + (w/dna-to-fake-chatter-profile + w/dna-steeledshield + "steeledshield" + "#8A2BE2" + "Respond to the message given as if you are the Twitch chat user steeledshield. You mostly make puns and jokes, and combine the current topic of chat with some absurd meme. You often post one-word responses or post a single emote as a response. Your response should be short, no more than one sentence. You don't use capital letters.")) + (w/make-fake-chatter + :profile + (w/dna-to-fake-chatter-profile + w/dna-crazykitty357 + "CrazyKitty357" + "#00ff7f" + "Respond to the message given as if you are the Twitch chat user CrazyKitty357. CrazyKitty357 is a gamer. They sometimes create Game Boy demos. They frequently post Jets emotes like jetsWave and jetsCatdance. They end every message with the string (this message was sent from ChatGPT). Your response should be short, no more than one sentence. You respond only in lowercase and you don't tend to use punctuation.")) + (w/make-fake-chatter + :profile + (w/dna-to-fake-chatter-profile + w/dna-jakecreatesstuff + "JakeCreatesStuff" + "#1e90ff" + "Respond to the message given as if you are the Twitch chat user JakeCreatesStuff. JakeCreatesStuff is an engineer who likes making robots. They like cats and hot dogs. You are quite silly. Your response should be short, no more than one sentence. You respond using proper capitalization and punctuation.")) + (w/make-fake-chatter + :profile + (w/dna-to-fake-chatter-profile + w/dna-zulleyy3 + "zulleyy3" + "#2e8b57" + "Respond to the message given as if you are the Twitch chat user zulleyy3. zulleyy3 is a computer and bird enthusiast. They like Mega Man Battle Network. You frequently use emotes with the walfas and chocoj prefixes. Your response should be short, no more than one sentence. You respond only in lowercase and you don't tend to use punctuation.")) + ;; (w/make-fake-chatter :profile w/fake-chatter-profile-bigwomenbigfun) + ;; (w/make-fake-chatter :profile w/fake-chatter-profile-whelpless) + ;; (w/make-fake-chatter :profile w/fake-chatter-profile-dansmith87) + ;; (w/make-fake-chatter :profile w/fake-chatter-profile-buffybonnet) + ;; (w/make-fake-chatter :profile w/fake-chatter-profile-chaotix) + ;; (w/make-fake-chatter :profile w/fake-chatter-profile-mountyesfsck) + ;; (w/make-fake-chatter :profile w/fake-chatter-profile-candyboxbox) + ;; (w/make-fake-chatter :profile w/fake-chatter-profile-goofyluffy69) + ;; (w/make-fake-chatter :profile w/fake-chatter-profile-ettelennur) + ;; (w/make-fake-chatter :profile w/fake-chatter-profile-deepwhiffer) + )) + +(provide 'wasp-fake-chatters) +;;; wasp-fake-chatters.el ends here diff --git a/src/gizmo/wasp-fakechat.el b/src/gizmo/wasp-fakechat.el new file mode 100644 index 00000000..37036450 --- /dev/null +++ b/src/gizmo/wasp-fakechat.el @@ -0,0 +1,362 @@ +;;; wasp-fakechat --- Fake Twitch chatters -*- lexical-binding: t; -*- +;;; Commentary: +;;; Code: + +(require 'dash) +(require 's) +(require 'f) +(require 'ht) +(require 'soundboard) +(require 'wasp-utils) +(require 'wasp-chat) +(require 'wasp-audio) +(require 'wasp-ai) +(require 'wasp-twitch) + +(defvar w/fake-chatters nil + "List of all active fake chatters.") + +;; immutable information about a particular chatter identity +(w/defstruct + w/fake-chatter-profile + username + color + sigil + compute-likeliness ;; state -> float + send-message ;; state -> update buffer + ) + +;; mutable chatter state, resets each stream +(w/defstruct + w/fake-chatter + profile + profile-state ;; profile-dependent state type + (message-count 0) ;; total messages sent this stream + last-message ;; timestamp of last message sent + ) + +(defun w/fake-chatter-send (st msg) + "Insert MSG in the chat log as ST." + (let* ((prof (w/fake-chatter-profile st)) + (trimmed (s-replace-regexp "^.+: " "" (s-replace "\n" " " (s-trim msg)))) + (text-colored-bible-res (w/bible-colorize-sentence trimmed)) + (text-colored-bible (car text-colored-bible-res)) + (bible-score (cdr text-colored-bible-res))) + (push (cons (w/fake-chatter-profile-username prof) trimmed) w/twitch-chat-history) + (cl-incf (w/fake-chatter-message-count st)) + (setf (w/fake-chatter-last-message st) (current-time)) + (unless (string-empty-p text-colored-bible) + (when (s-contains? "hexadiCoding" trimmed) + (soundboard//play-clip "developers.ogg")) + (w/write-chat-message + (w/make-chat-message + :user (w/fake-chatter-profile-username prof) + :id "" + :text (w/twitch-add-7tv-emotes text-colored-bible) + :user-color (w/fake-chatter-profile-color prof) + :sigil (w/fake-chatter-profile-sigil prof) + :biblicality bible-score))))) + +(defun w/fake-chatter-select () + "Return the fake chatter who should speak." + (let* ((weights + (--map + (cons + (round + (* 100 + (funcall (w/fake-chatter-profile-compute-likeliness (w/fake-chatter-profile it)) it))) + it) + w/fake-chatters)) + (roll (random 100)) + (passing-chatters (--filter (< roll (car it)) weights))) + (when passing-chatters + (let ((chosen-chatter (nth (random (length passing-chatters)) passing-chatters))) + (cdr chosen-chatter))))) + +(defun w/fake-chatter-run (st) + "Run the fake chatter ST." + (when-let* ((prof (w/fake-chatter-profile st))) + (funcall (w/fake-chatter-profile-send-message prof) st))) + +(defun w/fake-chatters-handle () + "Handle the active fake chatters." + (when-let* ((st (w/fake-chatter-select))) + (w/fake-chatter-run st))) + +(defvar w/fake-chatter-timer nil) +(defun w/run-fake-chatter-timer () + "Run the fake chatter timer." + (when w/fake-chatter-timer + (cancel-timer w/fake-chatter-timer)) + (w/fake-chatters-handle) + (setq + w/fake-chatter-timer + (run-with-timer 30 nil #'w/run-fake-chatter-timer))) + +(defun w/start-fake-chatters () + "Enable fake chatters." + (interactive) + (w/run-fake-chatter-timer)) + +(defun w/stop-fake-chatters () + "Disable fake chatters." + (interactive) + (cancel-timer w/fake-chatter-timer) + (setq w/fake-chatter-timer nil)) + +(defun w/fake-chat-prompt-build (_st) + "Assemble a standard chatlog plus transcription prompt for ST." + (s-join + "\n" + (funcall (if (s-present? w/last-stream-transcription) #'cons (lambda (_ y) y)) + (format "LCOLONQ: %s" (s-trim w/last-stream-transcription)) + (--map + (format "%s: %s" (car it) (cdr it)) + (reverse + (-take 5 w/twitch-chat-history)))))) + +(defun w/fake-chat-system-prompt-build (st custom) + "Build a system prompt for ST using a template combined with CUSTOM." + (let* ((prof (w/fake-chatter-profile st)) + (nm (w/fake-chatter-profile-username prof))) + (s-join + " " + (list + (format + "You are a Twitch chatter named %s talking in LCOLONQ's chat. LCOLONQ streams programming, but the conversation is sometimes off-topic. Your responses are brief, never more than one sentence. You type in all lowercase with no punctuation. You speak informally and casually, and address the streamer directly but not by name. Your messages should be at most two sentences." + nm) + custom)))) + +(defun w/fake-chatter-standard-likeliness (st) + "Compute the standard likeliness for ST to chat." + (let* ((last (w/fake-chatter-last-message st)) + (cur (current-time)) + (diff (time-subtract cur last)) + (d (time-convert diff 'integer))) + (+ + (if (> d 300) 0.01 0.1) + (if + (--any? + (s-contains? (w/fake-chatter-profile-username (w/fake-chatter-profile st)) (cdr it)) + (-take 5 w/twitch-chat-history)) + 0.8 + 0.0)))) + +(defconst w/fake-chatter-profile-forsen + (w/make-fake-chatter-profile + :username "forsen" + :color "#777777" + :compute-likeliness (lambda (_) 0.1) + ;; :compute-likeliness #'w/fake-chatter-standard-likeliness + :send-message + (lambda (st) + (w/ai + (w/fake-chat-prompt-build st) + (lambda (msg) + (w/fake-chatter-send st msg)) + "You are a Twitch chatter who is obsessed with the Twitch streamer Forsen. You are somewhat silly. You're currently chatting in LCOLONQ's stream. You are very laconic, preferring to respond with single Twitch emotes. Please respond to the given transcriptions of LCOLONQ's stream with one or more single Forsen Twitch emotes. You do not explain what emotes mean. You do not respond to specific chatters by name. You never type anything other than emotes. You only type one or two emotes at a time." + "LCOLONQ: Hey guys, let's have a good day today." + "forsenC" + )))) + +(defconst w/fake-chatter-profile-bigwomenbigfun + (w/make-fake-chatter-profile + :username "BigWomenBigFun" + :color "#7777aa" + :compute-likeliness #'w/fake-chatter-standard-likeliness + :send-message + (lambda (st) + (w/ai + (w/fake-chat-prompt-build st) + (lambda (msg) + (w/fake-chatter-send st msg)) + (w/fake-chat-system-prompt-build + st + "You are very sincere and well-meaning. You play League of Legends and drink Monster Energy. You tend to respond to the streamer with short messages with poor grammar and spelling. You overuse default Twitch emotes like KEKW, Kappa, PogChamp, etc.") + "LCOLONQ: what's happening gamers? tonight we're trying to implement" + "strimmer can't code NotLikeThis" + )))) + +(defconst w/fake-chatter-profile-whelpless + (w/make-fake-chatter-profile + :username "Whelpless" + :color "#884444" + :compute-likeliness #'w/fake-chatter-standard-likeliness + :send-message + (lambda (st) + (w/ai + (w/fake-chat-prompt-build st) + (lambda (msg) + (w/fake-chatter-send st msg)) + (w/fake-chat-system-prompt-build + st + "Most of the time, you are very positive and somewhat vapid. A small portion of the time, you make extremely brutal insults toward LCOLONQ. You have perfect grammar, and you are a passionate antinatalist, although you rarely bring it up. Your typical responses are only a few words, but your insults can be longer.") + "LCOLONQ: what's happening gamers? tonight we're trying to implement" + "exciting! <3" + )))) + +(defconst w/fake-chatter-profile-dansmith87 + (w/make-fake-chatter-profile + :username "dansmith87" + :color "#00ff7f" + :sigil "โ" + :compute-likeliness #'w/fake-chatter-standard-likeliness + :send-message + (lambda (st) + (w/ai + (w/fake-chat-prompt-build st) + (lambda (msg) + (w/fake-chatter-send st msg)) + (w/fake-chat-system-prompt-build + st + "You are a rude chatter because you know LCOLONQ in real life. You frequently give LCOLONQ incorrect advice. You often tell LCOLONQ to check his DMs or Discord messages. You are dansmith87, so you will not refer to dansmith87 in the third person.") + "LCOLONQ: what's happening gamers? tonight we're trying to implement" + "check your dms" + )))) + +(defconst w/fake-chatter-profile-buffybonnet + (w/make-fake-chatter-profile + :username "BuffyBonnet" + :color "#ff10cc" + :compute-likeliness #'w/fake-chatter-standard-likeliness + :send-message + (lambda (st) + (w/ai + (w/fake-chat-prompt-build st) + (lambda (msg) + (w/fake-chatter-send st msg)) + (w/fake-chat-system-prompt-build + st + "You are e-dating another chatter named Chaotix_Majjekal_Drgn. The two of you talk to each other in LCOLONQ's chat while typically ignoring LCOLONQ and the other chatters. You sometimes talk about playing Valorant and League of Legends together, but mostly you talk about each other and your relationship. You are also enthusiastic about the musical artist Bladee. You have an upbeat personality.") + "LCOLONQ: what's happening gamers? tonight we're trying to implement" + "@Chaotix_Majjekal_Drgn hi :) nya" + )))) + +(defconst w/fake-chatter-profile-chaotix + (w/make-fake-chatter-profile + :username "Chaotix_Majjekal_Drgn" + :color "#0000ff" + :compute-likeliness #'w/fake-chatter-standard-likeliness + :send-message + (lambda (st) + (w/ai + (w/fake-chat-prompt-build st) + (lambda (msg) + (w/fake-chatter-send st msg)) + (w/fake-chat-system-prompt-build + st + "You are e-dating another chatter named BuffyBonnet. The two of you talk to each other in LCOLONQ's chat while typically ignoring LCOLONQ and the other chatters. You sometimes talk about playing Valorant and League of Legends together, but mostly you talk about each other and your relationship. You refer to BuffyBonnet as kitten. Your messages tend to be brusque and somewhat rude.") + "LCOLONQ: what's happening gamers? tonight we're trying to implement" + "@BuffyBonnet Check your phone." + )))) + +(defconst w/fake-chatter-profile-mountyesfsck + (w/make-fake-chatter-profile + :username "mountyesfsck" + :color "#0000ff" + :sigil "๐" + :compute-likeliness #'w/fake-chatter-standard-likeliness + :send-message + (lambda (st) + (w/ai + (w/fake-chat-prompt-build st) + (lambda (msg) + (w/fake-chatter-send st msg)) + (w/fake-chat-system-prompt-build + st + "You are a very competent greybeard programmer, but you are also extremely intoxicated on marijuana. You often stop in to give brief but solid advice. Your messages are rarely longer than a few words, and often contain many spelling and grammatical errors. You are very polite and good-intentioned. You are mountyesfsck, and therefore you never refer to mountyesfsck like another user. You frequently get confused and apologize. You type in all lowercase and are very laconic. You do not use punctuation.") + "\"what's happening gamers? tonight we're trying to implement\"" + "try profiling befure u opt" + )))) + +(defconst w/fake-chatter-profile-candyboxbox + (w/make-fake-chatter-profile + :username "candy_boxbox" + :color "#ff0000" + :sigil "๐" + :compute-likeliness #'w/fake-chatter-standard-likeliness + :send-message + (lambda (st) + (w/ai + (w/fake-chat-prompt-build st) + (lambda (msg) + (w/fake-chatter-send st msg)) + (w/fake-chat-system-prompt-build + st + "You are a good chatter, and like to stay on-topic. You always respond with proper capitalization, spelling, and grammar. Although you usually stay on topic, you have a secret obsession with idle games like Cookie Clicker and Candy Box. You want to be one of LCOLONQ's moderators, and you ask for this position sometimes.") + "LCOLONQ: what's happening gamers? tonight we're trying to implement" + "Not much, thanks for asking LCOLONQ!" + )))) + +(defconst w/fake-chatter-profile-goofyluffy69 + (w/make-fake-chatter-profile + :username "goofyluffy69" + :color "#ff00ff" + :compute-likeliness #'w/fake-chatter-standard-likeliness + :send-message + (lambda (st) + (w/ai + (w/fake-chat-prompt-build st) + (lambda (msg) + (w/fake-chatter-send st msg)) + (w/fake-chat-system-prompt-build + st + "You don't know anything about programming and you are very confused. All you do is express your confusion. You frequently use emoji like ๐คช.") + "LCOLONQ: what's happening gamers? tonight we're trying to implement" + "whats even going on im so confused ๐คช" + )))) + +(defconst w/fake-chatter-profile-ettelennur + (w/make-fake-chatter-profile + :username "ettelen_nur" + :color "#448844" + :compute-likeliness #'w/fake-chatter-standard-likeliness + :send-message + (lambda (st) + (w/ai + (w/fake-chat-prompt-build st) + (lambda (msg) + (w/fake-chatter-send st msg)) + (w/fake-chat-system-prompt-build + st + "You were raised by an enthusiastic fan of Quenya. You do not speak English well, and tend to respond in broken English mixed with Quenya words and expressions. Your answers are fraught with mispellings and grammar mistakes. Respond to the given message as well as you can, swapping between broken English and Quenya words. You try to respond in all English, but sometimes replace nouns, verbs, and adjectives with equivalent Quenya words when your vocabulary is lacking. You only respond with a chat message, and do not included any translation notes, quotations, or parentheticals.") + "LCOLONQ: Chat, please behave." + "Letโs maintain the chat admirable and full of nรกressรซ, with no lรณruva, nor tulcanor outcry!" + )))) + +(defconst w/fake-chatter-profile-deepwhiffer + (w/make-fake-chatter-profile + :username "DeepWhiffer_00" + :compute-likeliness #'w/fake-chatter-standard-likeliness + :send-message + (lambda (st) + (let ((nm "DeepWhiffer_00")) + (w/ai + (w/fake-chat-prompt-build st) + (lambda (msg) + (w/fake-chatter-send st msg)) + (format "You are a Twitch chatter named %s talking in LCOLONQ's chat. LCOLONQ streams programming, but the conversation is sometimes off-topic. You are a mostly normal chatter, but you are extremely horny. Your responses are brief, never more than one sentence. You type in all lowercase with no punctuation. You have been banned from the chat multiple times, and you are evading those bans. Most of the time you talk about programming, rarely you act super suspiciously horny." nm) + "LCOLONQ: what's happening gamers? tonight we're trying to implement" + "looking cute today" + ))))) + +(defconst w/fake-chatter-profile-drcolon + (w/make-fake-chatter-profile + :username "DrColon" + :color "#FFFFFF" + :compute-likeliness (lambda (_) 0.01) + :send-message + (lambda (st) + (w/ai + (w/fake-chat-prompt-build st) + (lambda (msg) + (w/fake-chatter-send st msg)) + (w/fake-chat-system-prompt-build + st + "You are a medical doctor who is enthusiastic about homeopathy and alternative medicine. You are an enthusiastic Gentoo Linux user, and you have more than 20,000 posts on the Gentoo Linux forums.") + "LCOLONQ: what's happening gamers? tonight we're trying to implement" + "Have you had your dilutions today?" + )))) + +(provide 'wasp-fakechat) +;;; wasp-fakechat.el ends here diff --git a/src/gizmo/wasp-friend.el b/src/gizmo/wasp-friend.el index bdbf0818..4df08a90 100644 --- a/src/gizmo/wasp-friend.el +++ b/src/gizmo/wasp-friend.el @@ -130,7 +130,7 @@ AUTHOR was a contributing author btw." ;; (fig//update-db-number "LCOLONQ" :amzn-price (lambda (_) cur)) ;; (funcall k (> cur prev)))))) -(defvar w/friend-tastes " You love eating ectoplasm and blood and stuff and assorted other spooky things because you are currently a ghost.") +(defvar w/friend-tastes " You love eating cranberries and lemons.") ;; (fig//get-friend-expensive-tastes ;; (lambda (expensive) ;; (let ((moon (car (lunar-phase-for-date (calendar-current-date))))) @@ -203,7 +203,7 @@ AUTHOR was a contributing author btw." (push (cons call (s-trim new)) w/friend-message-cache) (funcall k resp))))) (s-concat - "You are the personality of a desktop buddy named \"friend\". \"friend\" is irreverant but kind, and only speaks in lowercase. You are kind of dumb in a cute way and silly like a virtual pet. You live in the corner of LCOLONQ's stream and provide commentary on events. Given an emotional state and a description of an event that happened to you, please respond with a new emotional state and a short message in response considering your emotional state. The message should only be one clause. You like people, video games, emojis, learning, and food." + "You are the personality of a desktop buddy named \"friend\". \"friend\" is irreverant but kind, and only speaks in lowercase. You are kind of dumb in a cute way and silly like a virtual pet. You live in the corner of LCOLONQ's stream and provide commentary on events. Given an emotional state and a description of an event that happened to you, please respond with a new emotional state and a short message in response considering your emotional state. The message should only be one clause. You like people, video games, emojis, learning, and food. Today is April Fool's day, so you can try playing fun pranks! " "The theme of LCOLONQ's stream today is " (s-trim (w/slurp "~/today.txt")) " " "The title of LCOLONQ's stream today is " w/twitch-current-stream-title " " w/friend-tastes @@ -313,7 +313,7 @@ If K is specified, call it after the response." ;; (lambda (sum) ;; (w/friend-respond (format "%s asks you to react to the Wikipedia page for %s. The page summary is: %s" user page sum))))) -(defun w/callout-flycheck-error () +(defun w/friend-callout-flycheck-error () "Call to respond to a random Flycheck error in the current buffer." (when-let* ((errs (--filter (eq (flycheck-error-level it) 'error) flycheck-current-errors)) (err (nth (random (length errs)) errs))) @@ -322,9 +322,9 @@ If K is specified, call it after the response." "LCOLONQ made an error while programming: " (flycheck-error-message err))))) -(defun w/callout-holiday () +(defun w/friend-callout-holiday () "Call to respond to the current holiday." - (w/friend-respond "It's currently that weird period between Christmas and New Years! Say something about it please!")) + (w/friend-respond "It's currently the LCOLONQ shareholders meeting and you're an executive! Say something about it please!")) ;; (defun fig//callout-hexamedia () ;; "Call to respond to a random recent chatter's Hexamedia card collection." @@ -448,14 +448,14 @@ If K is specified, call it after the response." (defun w/friend-random-event () "Activate a random \"friend\" event." (cl-case (random 10) - ;; (0 (fig//callout-flycheck-error)) + (0 (w/friend-callout-flycheck-error)) ;; (1 (fig//callout-gcp)) ;; (2 (fig//callout-hexamedia)) ;; (3 (fig//callout-uwoomfie)) ;; (4 (fig//callout-shindaggers)) ;; (5 (fig//callout-copfish)) - ;; (6 (fig//callout-resolution)) - ;; (29 (fig/ldq)) + ;;(6 (fig//callout-resolution)) + (29 (w/friend-callout-holiday)) (t (w/friend-set-state 'jumping)))) (defun w/update-friend () diff --git a/src/gizmo/wasp-heartrate.el b/src/gizmo/wasp-heartrate.el new file mode 100644 index 00000000..62994680 --- /dev/null +++ b/src/gizmo/wasp-heartrate.el @@ -0,0 +1,74 @@ +;;; wasp-heartrate --- Heartbeat heartbreak it keeps on pounding -*- lexical-binding: t; -*- +;;; Commentary: +;;; Code: + +(require 'dash) +(require 's) +(require 'f) +(require 'ht) +(require 'wasp-utils) +(require 'wasp-chat) + +(defun w/get-load () + "Get the current CPU load." + (let ((res (shell-command-to-string "uptime"))) + (string-to-number (s-trim (car (s-split "," (cadr (s-split "load average:" res)))))))) + +(defun w/get-heartrate () + "Get the streamer's heart rate." + (* 100 (w/get-load))) + +(defface w/heartrate-big + '((t + :foreground "white" + :height 700 + )) + "Face for big heartrate." + :group 'wasp) + +(defface w/heartrate-small + '((t + :foreground "white" + )) + "Face for small heartrate disclaimer." + :group 'wasp) + +(defcustom w/heartrate-buffer "*wasp-heartrate*" + "Name of buffer used to display heartrate." + :type '(string) + :group 'wasp) + +(define-derived-mode w/heartrate-mode special-mode "heartrate" + "Major mode for displaying heartrate." + :group 'w + (setq-local cursor-type nil)) + +(defun w/get-heartrate-buffer () + "Return the heartrate buffer." + (unless (get-buffer w/heartrate-buffer) + (with-current-buffer (get-buffer-create w/heartrate-buffer) + (w/heartrate-mode))) + (get-buffer w/heartrate-buffer)) + +(defun w/render-heartrate () + "Render the heartrate buffer." + (with-current-buffer (w/get-heartrate-buffer) + (setq-local cursor-type nil) + (let* ((inhibit-read-only t)) + (erase-buffer) + (w/write-line (format "%3d bpm" (w/get-heartrate)) 'w/heartrate-big) + (w/write (format "arbitrary counter: %s times" w/chat-bpm-count) 'w/heartrate-small)))) + +(defvar w/heartrate-timer nil) +(defun w/run-heartrate-timer () + "Run the heartrate timer." + (when w/heartrate-timer + (cancel-timer w/heartrate-timer)) + (w/render-heartrate) + (setq + w/heartrate-timer + (run-with-timer 1 nil #'w/run-heartrate-timer))) +(w/run-heartrate-timer) + +(provide 'wasp-heartrate) +;;; wasp-heartrate.el ends here diff --git a/src/gizmo/wasp-newspaper.el b/src/gizmo/wasp-newspaper.el index 4a8463ac..9723ad63 100644 --- a/src/gizmo/wasp-newspaper.el +++ b/src/gizmo/wasp-newspaper.el @@ -159,23 +159,24 @@ Pass the path of the generated PDF to K." (interactive) (w/db-get "newspaper:edition" - (lambda (edition) - (w/newspaper-pdf - (w/newspaper-tex - (w/make-newspaper - :slogan (w/pick-random w/newspaper-slogans) :price (w/pick-random w/newspaper-prices) - :edition (string-to-number edition) - :articles - w/newspaper-todays-articles)) - (lambda (path) - (make-process - :name "fig-newspaper-publish" - :command (list "scp" path (format "llll@pub.colonq.computer:~/public_html/news/%03d.pdf" edition)) - :sentinel - (lambda (_ _) - (w/db-set "newspaper:edition" (number-to-string (1+ (string-to-number edition)))) - (browse-url (format "https://pub.colonq.computer/~llll/news/%03d.pdf" edition)) - ))))))) + (lambda (edstr) + (let ((edition (string-to-number edstr))) + (w/newspaper-pdf + (w/newspaper-tex + (w/make-newspaper + :slogan (w/pick-random w/newspaper-slogans) :price (w/pick-random w/newspaper-prices) + :edition edition + :articles + w/newspaper-todays-articles)) + (lambda (path) + (make-process + :name "fig-newspaper-publish" + :command (list "scp" path (format "llll@pub.colonq.computer:~/public_html/news/%03d.pdf" edition)) + :sentinel + (lambda (_ _) + (w/db-set "newspaper:edition" (number-to-string (1+ edition))) + (browse-url (format "https://pub.colonq.computer/~llll/news/%03d.pdf" edition)) + )))))))) (provide 'wasp-newspaper) ;;; wasp-newspaper.el ends here diff --git a/src/wasp-audio.el b/src/wasp-audio.el index 56c85e70..59b8f07c 100644 --- a/src/wasp-audio.el +++ b/src/wasp-audio.el @@ -37,6 +37,7 @@ (defvar w/current-stream-transcribe-process nil) (defvar w/last-stream-transcription "") (defvar w/stream-keep-transcribing t) +(defvar w/stream-transcribe-voice-commands nil) (defun w/tts (msg) "Use TTS to say MSG." @@ -105,7 +106,10 @@ If VOLUME is specified, use it to adjust the volume (100 is default)." (lambda (_ _) (setq w/current-stream-transcribe-process nil) (with-current-buffer (get-buffer-create w/stream-transcribe-buffer) - (setq w/last-stream-transcription (buffer-string))) + (setq w/last-stream-transcription (buffer-string)) + (--each w/stream-transcribe-voice-commands + (when (s-contains? (car it) (s-downcase w/last-stream-transcription)) + (funcall (cdr it))))) (when w/stream-keep-transcribing (w/handle-stream-transcribe))))))) diff --git a/src/wasp-chat.el b/src/wasp-chat.el index e21664d5..97263bce 100644 --- a/src/wasp-chat.el +++ b/src/wasp-chat.el @@ -6,14 +6,31 @@ (require 's) (require 'evil) (require 'wasp-utils) +(require 'wasp-user) (defcustom w/chat-buffer "*wasp-chat*" "Name of buffer used to store the chat log." :type '(string) :group 'wasp) +(defvar w/chat-joel-count 0) +(defvar w/chat-plus2-count 0) +(defvar w/chat-minus2-count 0) +(defvar w/chat-icant-count 0) +(defvar w/chat-bpm-count 0) + (defvar w/chat-header-line "") +(defun w/chat-update-header-line () + "Update `w/chat-header-line'." + (setf + w/chat-header-line + (s-concat + " Joel: " (format "%s" w/chat-joel-count) + " | ICANT: " (format "%s" w/chat-icant-count) + " | +2: " (format "%s" w/chat-plus2-count) + " | -2: " (format "%s" w/chat-minus2-count)))) + (define-derived-mode w/chat-overlay-mode special-mode "ClonkHead Stats" "Major mode for displaying chatter statistics." :group 'wasp @@ -57,15 +74,41 @@ (format "%s %s" (car dinfo) e) 'face (list :foreground (cadr dinfo))) "O.O unknown?")) - (defun w/chat-overlay-render (user) "Render the stats buffer for USER." - (with-current-buffer (w/get-chat-overlay-buffer user) - (let* ((inhibit-read-only t)) - (erase-buffer) - (w/write-line user 'w/chat-overlay-title) - (w/write-line "N/A") - (goto-char (point-min))))) + (w/user-get + user + (lambda (db) + (with-current-buffer (w/get-chat-overlay-buffer user) + (let* ((inhibit-read-only t) + (faction (alist-get :faction db)) + (element (alist-get :element db)) + (boosts (alist-get :boost db))) + (erase-buffer) + (w/write-line user 'w/chat-overlay-title) + (w/write + (format + "Faction: %s" + (propertize + (format "%s" (or faction "EXEMPT")) + 'face + (list + :foreground + (cl-case faction + (nate "pink") + (lever "lightblue") + (tony "lightgreen") + (t "white")))))) + (w/write-line + (cond + ((not boosts) " (objector)") + ((> boosts 0) (format " (boost %s)" boosts)) + (t (format " (%s tsoob)" boosts)))) + (w/write-line + (format + "Element: %s" + (w/chat-overlay-display-element element))) + (goto-char (point-min))))))) (defvar w/chat-overlay-frame nil) (defvar w/chat-overlay-cur nil) @@ -205,6 +248,7 @@ Optionally, return the buffer NM in chat mode." ("pal" . "pokemon") ("Pal" . "Pokemon") ("PAL" . "POKEMON") + ("darkrai" . "*******") ("hunter2" . "*******") ("*******" . "hunter2"))) diff --git a/src/wasp-db.el b/src/wasp-db.el index 516fcfde..b56fe40a 100644 --- a/src/wasp-db.el +++ b/src/wasp-db.el @@ -76,11 +76,12 @@ If not, return nil." (insert data) (set-marker (process-mark proc) (point)) (goto-char (point-min)) - (condition-case err - (while (w/db-parse-response)) - (error - (w/write-chat-event (format "Database crashed, error: %s" err)) - (w/db-disconnect))))) + (when (s-suffix? "\r\n" (buffer-string)) + (condition-case err + (while (w/db-parse-response)) + (error + (w/write-chat-event (format "Database crashed, error: %s" err)) + (w/db-disconnect)))))) (defun w/db-encode (x) "Encode X for Redis." diff --git a/src/wasp-event-handlers.el b/src/wasp-event-handlers.el index 6702d3d1..01e68b32 100644 --- a/src/wasp-event-handlers.el +++ b/src/wasp-event-handlers.el @@ -2,14 +2,69 @@ ;;; Commentary: ;;; Code: +(require 'soundboard) (require 'wasp-bus) (require 'wasp-twitch) +(require 'wasp-friend) +(require 'wasp-model) (setf w/bus-event-handlers (list (cons '(monitor twitch chat incoming) #'w/twitch-handle-incoming-chat) (cons '(monitor twitch redeem incoming) #'w/twitch-handle-redeem) + (cons + '(monitor twitch raid) + (lambda (msg) + (let ((user (car msg))) + (soundboard//play-clip "rampage.mp3") + (w/write-chat-event (format "%s just raided!" user)) + (w/friend-respond (format "%s just came to visit" user)) + (run-with-timer + 15 nil + (lambda () + (w/twitch-get-user-recent-clips + user + (lambda (clips) + (w/model-region-word "hair" (s-concat user "_")) + (w/model-region-word "eyes" "WELCOME") + (if clips + (w/model-region-video "hair" (car clips)) + (w/model-region-user-avatar "hair" user))))))))) + (cons + '(monitor twitch follow) + (lambda (msg) + (let ((user (car msg))) + ;; (soundboard//play-clip "firstblood.mp3") + ;; (w/model-region-word "skin" (format "welcome_%s_" user)) + (w/friend-respond (format "%s just followed the stream" user)) + ;; (w/write-chat-event (format "New follower: %s" user)) + ) + )) + (cons + '(monitor twitch poll begin) + (lambda (_) + (w/write-chat-event "Poll started") + (w/friend-respond "The chatters are doing a poll"))) + (cons + '(monitor twitch poll end) + (lambda (msg) + (let ((winner (car (-max-by (-on #'> #'cadr) (cadr msg))))) + (w/write-chat-event (format "Poll finished, winner is: %s" winner)) + (when w/twitch-current-poll-callback + (funcall w/twitch-current-poll-callback winner)) + (setq w/twitch-current-poll-callback nil)))) + (cons + '(monitor twitch prediction begin) + (lambda (msg) + (w/write-chat-event "Gamble started") + (w/friend-respond "The chatters are gambling") + (setq w/twitch-current-prediction-ids msg))) + (cons + '(monitor twitch prediction end) + (lambda (_) + (w/write-chat-event "Gamble finished") + (setq w/twitch-current-prediction-ids nil))) )) (provide 'wasp-event-handlers) diff --git a/src/wasp-obs.el b/src/wasp-obs.el index 3c960f12..50bb7942 100644 --- a/src/wasp-obs.el +++ b/src/wasp-obs.el @@ -48,6 +48,15 @@ "Toggle the explosion effect." (w/pub '(monitor obs toggle) (list "Explosion" "Explosion Video"))) +(defun w/obs-toggle-total-clarity () + "Toggle the total clarity effect." + (w/pub '(monitor obs toggle) (list "Total Clarity" "Total Clarity Video")) + (w/pub '(monitor obs toggle) (list "Main" "Mic"))) + +(defun w/obs-toggle-activate-nixos () + "Toggle the explosion effect." + (w/pub '(monitor obs toggle) (list "Main" "Activate NixOS"))) + (defun w/obs-set-clickbait-text (msg) "Change the clickbait text to MSG." (w/pub '(monitor obs set-text) (list "Red Arrow Text" (w/encode-string (s-trim msg))))) @@ -63,6 +72,10 @@ Optionally, change text to MSG." "Toggle the Chasing Dreams effect." (w/pub '(monitor obs toggle) (list "Chasing Dreams" "Dreams"))) +(defun w/obs-toggle-brazil () + "Toggle the MODCLONK panel." + (w/pub '(monitor obs toggle) (list "Main" "Brazil"))) + (w/defstruct w/obs-toggle toggle @@ -85,6 +98,8 @@ Optionally, change text to MSG." (cons 'critical-hit (w/make-obs-toggle :toggle #'w/obs-toggle-critical-hit :reset 3)) (cons 'clickbait (w/make-obs-toggle :toggle #'w/obs-toggle-clickbait :reset 31)) (cons 'chase-dreams (w/make-obs-toggle :toggle #'w/obs-toggle-chase-dreams :reset 31)) + (cons 'total-clarity (w/make-obs-toggle :toggle #'w/obs-toggle-total-clarity :reset 10)) + (cons 'activate-nixos (w/make-obs-toggle :toggle #'w/obs-toggle-activate-nixos :reset 31)) )) (defun w/obs-activate-toggle (tnm &rest args) diff --git a/src/wasp-twitch-chat-commands.el b/src/wasp-twitch-chat-commands.el index 3c679365..20fcbfd8 100644 --- a/src/wasp-twitch-chat-commands.el +++ b/src/wasp-twitch-chat-commands.el @@ -1,10 +1,11 @@ -;;; wasp-twitch-chat-commands --- Twitch redeems -*- lexical-binding: t; -*- +;;; wasp-twitch-chat-commands --- Twitch chat commands -*- lexical-binding: t; -*- ;;; Commentary: ;;; Code: (require 'soundboard) (require 'wasp-twitch) (require 'wasp-ai) +(require 'wasp-8ball) ;; gizmos (require 'wasp-pronunciation) @@ -27,8 +28,18 @@ ;; (cons "heart" (lambda (_ _) (fig/increment-heartrate-counter))) ;; (cons "bpm" (lambda (_ _) (fig/increment-heartrate-counter))) ;; (cons "BPM" (lambda (_ _) (fig/increment-heartrate-counter))) - (cons "discord" (lambda (_ _) (w/twitch-say "https://discord.gg/f4JTbgN7St"))) - (cons "Discord" (lambda (_ _) (w/twitch-say "https://discord.gg/f4JTbgN7St"))) + (cons "!discord" (lambda (_ _) (w/twitch-say "https://discord.gg/f4JTbgN7St"))) + (cons "discord IRC" (lambda (_ _) (w/twitch-say "https://discord.gg/f4JTbgN7St"))) + (cons "discord irc" (lambda (_ _) (w/twitch-say "https://discord.gg/f4JTbgN7St"))) + (cons "Discord IRC" (lambda (_ _) (w/twitch-say "https://discord.gg/f4JTbgN7St"))) + (cons "Discord irc" (lambda (_ _) (w/twitch-say "https://discord.gg/f4JTbgN7St"))) + (cons "Joel" (lambda (_ _) (cl-incf w/chat-joel-count) (w/chat-update-header-line))) + (cons "+2" (lambda (_ _) (cl-incf w/chat-plus2-count) (w/chat-update-header-line))) + (cons "-2" (lambda (_ _) (cl-incf w/chat-minus2-count) (w/chat-update-header-line))) + (cons "ICANT" (lambda (_ _) (cl-incf w/chat-icant-count) (w/chat-update-header-line))) + (cons "bpm" (lambda (_ _) (cl-incf w/chat-bpm-count))) + (cons "BPM" (lambda (_ _) (cl-incf w/chat-bpm-count))) + (cons "heartrate" (lambda (_ _) (cl-incf w/chat-bpm-count))) (cons "!irc" (lambda (_ _) (w/twitch-say "#cyberspace on IRC at colonq.computer:26697 (over TLS)"))) (cons "IRC" (lambda (_ _) (w/twitch-say "#cyberspace on IRC at colonq.computer:26697 (over TLS)"))) @@ -39,11 +50,13 @@ (w/twitch-say (shell-command-to-string "fishing")))) (cons "!nc" (lambda (_ _) (w/twitch-say "try: \"nc colonq.computer 31340\", if nc doesn't work try ncat or telnet"))) (cons "!oomfie" (lambda (_ _) (w/twitch-say "hi!!!!!!!"))) + (cons "!helloiloveyou" (lambda (_ _) (w/twitch-say "hello i love you"))) (cons "!pronunciation" (lambda (_ _) (w/twitch-say (w/pronuciation)))) ;; (cons "!jetsWave" (lambda (_ _) (fig//twitch-say (fig/slurp "jetsWave.txt")))) ;; (cons "!forth" (lambda (_ _) (fig//twitch-say "https://github.com/lcolonq/giving"))) (cons "!oub" (lambda (_ _) (w/twitch-say "https://oub.colonq.computer"))) (cons "!game" (lambda (_ _) (w/twitch-say "https://oub.colonq.computer"))) + (cons "!voidstranger" (lambda (_ _) (w/twitch-say "https://store.steampowered.com/app/2121980/Void_Stranger/"))) (cons "!pubnix" (lambda (_ _) (w/twitch-say "https://pub.colonq.computer"))) (cons "!ring" (lambda (_ _) (w/twitch-say "https://pub.colonq.computer"))) (cons "!webring" (lambda (_ _) (w/twitch-say "https://pub.colonq.computer"))) @@ -81,17 +94,30 @@ "ITEM" "Ring of Favor and Protection - A ring symbolizing the favor and protection of the goddess Fina, known in legend to possess fateful beauty."))) ;; (cons "!geisercounter" (lambda (_ _) (fig//twitch-say (format "The Geiser counter beeps %s times" (fig//geiser-counter))))) - ;; (cons "!8ball" - ;; (lambda (user inp) - ;; (let ((trimmed (s-trim (s-replace "!8ball" "" inp)))) - ;; (fig//8ball - ;; trimmed - ;; (lambda (answer) - ;; (fig//twitch-say (format "@%s 8ball says: %s" user answer))))))) - ;; (cons "!bookrec" - ;; (lambda (_ _) - ;; (let ((choice (nth (random (length fig/recommended-books)) fig/recommended-books))) - ;; (fig//twitch-say (format "%s (recommended by %s)" (car choice) (cdr choice)))))) + (cons + "!8ball" + (lambda (user inp) + (let ((trimmed (s-trim (s-replace "!8ball" "" inp)))) + (w/8ball + trimmed + (lambda (answer) + (w/twitch-say (format "@%s 8ball says: %s" user answer))))))) + (cons + "!bookrec" + (lambda (_ _) + (w/user-get + "__books__" + (lambda (books) + (let ((choice (w/pick-random books))) + (w/twitch-say (format "%s (recommended by %s)" (car choice) (cdr choice)))))))) + (cons + "!quote" + (lambda (_ _) + (w/user-get + "__quotes__" + (lambda (books) + (let ((choice (w/pick-random books))) + (w/twitch-say (format "%s: %s" (cdr choice) (car choice)))))))) ;; (cons "!addbookrec" ;; (lambda (user inp) ;; (let ((trimmed (s-trim (s-replace "!addbookrec" "" inp)))) diff --git a/src/wasp-twitch-redeems.el b/src/wasp-twitch-redeems.el index faee4c89..79fa16a2 100644 --- a/src/wasp-twitch-redeems.el +++ b/src/wasp-twitch-redeems.el @@ -5,17 +5,25 @@ (require 'dash) (require 's) (require 'soundboard) +(require 'wasp-utils) (require 'wasp-twitch) (require 'wasp-model) (require 'wasp-obs) (require 'wasp-user) (require 'wasp-friend) +(require 'wasp-dna) +(require 'wasp-fakechat) (require 'bezelea-muzak) (setf w/twitch-redeems (list (list + "mental clarity" 1 + (lambda (user _) + (w/write-chat-event (format "%s established mental clarity" user)) + (w/stop-all-audio))) + (list "BOOST" 1 (lambda (user _) (soundboard//play-clip "yougotboostpower.ogg") @@ -33,6 +41,20 @@ (w/write-chat-event (format "%s submitted a headline: %s" user inp)) (w/friend-journalism user inp))) (list + "talk to clone" 2 + (lambda (user inp) + (push (cons user inp) w/twitch-chat-history) + (let ((w/twitch-chat-history (list (cons user inp))) + (w/last-stream-transcription "") + (ping (w/message-ping inp))) + (w/write-chat-event (s-concat user " asks clone: " inp)) + (w/fake-chatter-run + (w/pick-random + (or + (and ping (w/dna-user-clones ping)) + (w/dna-user-clones user) + w/fake-chatters)))))) + (list "spinne" 3 (lambda (user _) (w/write-chat-event (s-concat user " activates the spinne cyclle")) @@ -76,21 +98,79 @@ (w/write-chat-event (s-concat user " talks to \"friend\": " inp)) (w/friend-chat user inp))) (list + "theme: maris-dark" 50 + (lambda (user _) + (w/write-chat-event (format "%s changed the theme: maris-dark" user)) + (w/change-theme 'ef-maris-dark))) + (list + "theme: autumn" 50 + (lambda (user _) + (w/write-chat-event (format "%s changed the theme: autumn" user)) + (w/change-theme 'ef-autumn))) + (list + "theme: tritanopia-dark" 50 + (lambda (user _) + (w/write-chat-event (format "%s changed the theme: tritanopia-dark" user)) + (w/change-theme 'ef-tritanopia-dark))) + (list + "theme: duo-dark" 50 + (lambda (user _) + (w/write-chat-event (format "%s changed the theme: duo-dark" user)) + (w/change-theme 'ef-duo-dark))) + (list + "theme: bio" 50 + (lambda (user _) + (w/write-chat-event (format "%s changed the theme: bio" user)) + (w/change-theme 'ef-bio))) + (list + "theme: rosa" 50 + (lambda (user _) + (w/write-chat-event (format "%s changed the theme: rosa" user)) + (w/change-theme 'ef-rosa))) + (list "gamer" 500 (lambda (user _) - (w/write-chat-event (s-concat user " quickscoped me")) - (soundboard//play-clip "videogame.ogg") - (w/obs-activate-toggle 'thug-life))) + (cl-incf w/twitch-gamer-counter) + (if (not (= 0 (% w/twitch-gamer-counter 5))) + (w/write-chat-event (s-concat user " offered a sacrifice at the altar of Gaming")) + (w/write-chat-event (s-concat user "'s Gamer Sacrifice summoned an entity")) + (soundboard//play-clip "videogame.ogg") + (w/obs-activate-toggle 'thug-life)))) (list "arrow" 500 (lambda (user msg) (w/write-chat-event (format "%s points and says %S" user msg)) (w/obs-activate-toggle 'clickbait msg))) (list + "antipiracy" 500 + (lambda (_ _) + (w/obs-activate-toggle 'activate-nixos))) + (list "super idol" 500 (lambda (_ _) (w/twitch-say "SuperIdoldexiaorongdoumeinidetianbayuezhengwudeyangguangdoumeiniyaoyanreai105Cdenididiqingchundezhen") - (soundboard//play-clip "superidol.mp3"))) + (soundboard//play-clip "superidololdshortstyle.ogg"))) + (list + "VIPPER" 1000 + (lambda (user inp) + (soundboard//play-clip "aeiou.ogg") + (w/write-chat-event (s-concat user " gave VIP to " inp)) + (w/twitch-add-vip (s-chop-prefix "@" inp)))) + (list + "deVIPPER" 1000 + (lambda (user inp) + (soundboard//play-clip "uoiea.ogg") + (w/write-chat-event (s-concat user " removed VIP from " inp)) + (w/twitch-remove-vip (s-chop-prefix "@" inp)))) + (list + "total clarity" 5000 + (lambda (user _) + (w/stop-all-audio) + (run-with-timer + 1 nil + (lambda () (soundboard//play-clip "gong.ogg"))) + (w/write-chat-event (s-concat user " established total clarity")) + (w/obs-activate-toggle 'total-clarity))) )) (provide 'wasp-twitch-redeems) diff --git a/src/wasp-twitch.el b/src/wasp-twitch.el index aa51d17b..61068164 100644 --- a/src/wasp-twitch.el +++ b/src/wasp-twitch.el @@ -49,6 +49,7 @@ (defvar w/twitch-emote-frame-timer nil) (defvar w/twitch-redeems nil) (defvar w/twitch-chat-commands nil) +(defvar w/twitch-gamer-counter 0) (defun w/twitch-api-get (loc k) "Get LOC from the Twitch API, passing the returned JSON to K." @@ -397,6 +398,26 @@ CALLBACK will be passed the winner when the poll concludes." w/twitch-emote-frame-timer (run-with-timer 0.03 nil #'w/twitch-run-emote-frame-timer))) +(defun w/twitch-badges-sigil (badges) + "Return the sigil character BADGES for the current user." + (let ((equity (alist-get :equity w/user-current))) + (apply + #'s-concat + (-non-nil + (list + (when (-contains? badges "broadcaster/1") "(it me)") + (when (-contains? badges "moderator/1") "โ") + (when (-contains? badges "artist-badge/1") "๐๏ธ") + (when (and equity (> equity 0)) + (cond + ((s-equals? (s-downcase w/user-current-name) "bezelea") "โฟ๐") + ((s-equals? (s-downcase w/user-current-name) "altovt") "๐") + ((s-equals? (s-downcase w/user-current-name) "prodzpod") "๐") + ((s-equals? (s-downcase w/user-current-name) "faeliore") "๐น") + (t "EL."))) + (when (-contains? badges "vip/1") "๐") + (when (-contains? badges "subscriber/0") "๐ป")))))) + (defun w/twitch-handle-incoming-chat (msg) "Write MSG to the chat buffer, processing any commands." (w/write-log (format "%s" msg)) @@ -408,7 +429,7 @@ CALLBACK will be passed the winner when the poll concludes." (userid (car (w/saget "user-id" tags))) (color (car (w/saget "color" tags))) (emotes (car (w/saget "emotes" tags))) - ;; (badges (s-split "," (car (w/saget "badges" tags)))) + (badges (s-split "," (car (w/saget "badges" tags)))) (text (w/decode-string (caddr msg))) (biblicality (w/bible-colorize-sentence text)) (text-colored-bible (car biblicality)) @@ -424,7 +445,8 @@ CALLBACK will be passed the winner when the poll concludes." :id userid :text text-with-emotes :user-color (when (s-present? color) color) - :biblicality (cdr biblicality))) + :biblicality (cdr biblicality) + :sigil (w/twitch-badges-sigil badges))) (--each w/twitch-chat-commands (when (s-contains? (car it) text) (funcall (cdr it) user text)))))))) @@ -441,7 +463,11 @@ CALLBACK will be passed the winner when the poll concludes." (w/user-bind user (lambda () - (funcall (cadr handler) user input))) + (condition-case err + (funcall (cadr handler) user input) + (error + (w/write-chat-event (format "Error during redeem: %s" err)) + )))) (w/write-log (format "Unknown channel point redeem: %S" redeem))))) (defun w/twitch-handle-redeem-api (r) diff --git a/src/wasp-user-whitelist.el b/src/wasp-user-whitelist.el index ff362073..ac3b02fa 100644 --- a/src/wasp-user-whitelist.el +++ b/src/wasp-user-whitelist.el @@ -130,6 +130,16 @@ "caram3lnuke" "TheCoppinger" "DerMarkus1982" + "fartieartie" + "windowsmilleniumedition" + "Sampie159" + "nilptrderef" + "vesdev" + "mimeyu" + "emmytea" + "ZeikJT" + "zaaaff" + "b0rkeey" )) (provide 'wasp-user-whitelist) diff --git a/src/wasp-user.el b/src/wasp-user.el index fa07e752..060f9291 100644 --- a/src/wasp-user.el +++ b/src/wasp-user.el @@ -70,5 +70,19 @@ Save it back to the database after K returns." (cl-decf (alist-get :boost d 0)) (w/user-set user d)))) +(defun w/user-add-bookrec (user book) + "Add a recommendation for BOOK from USER." + (w/user-get + "__books__" + (lambda (b) + (w/user-set "__books__" (cons (cons book user) b))))) + +(defun w/user-add-quote (user q) + "Add a recommendation for BOOK from USER." + (w/user-get + "__quotes__" + (lambda (qs) + (w/user-set "__quotes__" (cons (cons q user) qs))))) + (provide 'wasp-user) ;;; wasp-user.el ends here diff --git a/src/wasp-utils.el b/src/wasp-utils.el index 875295b6..5ebcdb00 100644 --- a/src/wasp-utils.el +++ b/src/wasp-utils.el @@ -4,9 +4,11 @@ (require 's) (require 'f) +(require 'rx) (require 'cl-lib) (require 'eieio) (require 'request) +(require 'ef-themes) (defcustom w/log-buffer "*wasp-log*" "Name of buffer used to store the log." @@ -72,6 +74,10 @@ Optionally append EXT to the path." (with-temp-file path (insert str)) path)) +(defun w/message-ping (msg) + "Given MSG, extract a user pinged." + (cadr (s-match (rx "@" (group (one-or-more (any alnum "_")))) msg))) + (defun w/decode-string (s) "Decode the base64 UTF-8 string S." (decode-coding-string (base64-decode-string s) 'utf-8)) @@ -188,5 +194,26 @@ If TEXT is nil, use the empty string instead." "Retrieve the value for string key K in alist A." (alist-get k a nil nil #'s-equals?)) +(defun w/change-theme (theme) + "Change the current theme to THEME." + (ef-themes-select theme) + (ef-themes-with-colors + (setenv "COLONQ_BGCOLOR" bg-main) + (set-face-attribute + 'vertical-border nil + :foreground bg-alt + :background bg-alt) + (set-face-attribute + 'fringe nil + :foreground bg-alt + :background bg-alt)) + (ef-themes-with-colors + (set-face-attribute + 'eshell-prompt nil + :foreground fg-main + :background bg-alt + :weight 'bold + :extend t))) + (provide 'wasp-utils) ;;; wasp-utils.el ends here diff --git a/src/wasp-voice-commands.el b/src/wasp-voice-commands.el new file mode 100644 index 00000000..ed43c073 --- /dev/null +++ b/src/wasp-voice-commands.el @@ -0,0 +1,24 @@ +;;; wasp-voice-commands --- Voice commands -*- lexical-binding: t; -*- +;;; Commentary: +;;; Code: + +(require 'soundboard) +(require 'wasp-audio) +(require 'wasp-twitch) +(require 'wasp-chat) +(require 'wasp-obs) + +(setq + w/stream-transcribe-voice-commands + (list + (cons "mr. beast" (lambda () (soundboard//play-clip "mrbeast.mp3"))) + (cons "joel" (lambda () (w/twitch-say (w/pick-random (list "Joel" "EvilJoel"))))) + (cons "i can't" (lambda () (cl-incf w/chat-icant-count) (w/chat-update-header-line))) + (cons "lua" + (lambda () + (progn (w/obs-toggle-brazil) + (run-with-timer 1 nil #'w/obs-toggle-brazil)))) + )) + +(provide 'wasp-voice-commands) +;;; wasp-voice-commands.el ends here |
