Created
April 21, 2026 07:52
-
-
Save paigeadelethompson/17589d09e9e2c5ecc77ac901d4315bc6 to your computer and use it in GitHub Desktop.
5.21e5 card pickup for IRC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use strict; | |
| use warnings; | |
| use Irssi; | |
| our $VERSION = '1.7'; | |
| our %IRSSI = ( | |
| authors => 'ChatGPT', | |
| name => 'card_spam', | |
| description => '5.21e5 card pickup spammer (white card tiles restored)', | |
| license => 'Public Domain', | |
| ); | |
| # IRC colors | |
| my $WHITE_BG = "\x0300,00"; | |
| my $RED = "\x0304"; | |
| my $BLACK = "\x0301"; | |
| my $RESET = "\x0f"; | |
| my @suits = ( | |
| { sym => "♠", color => $BLACK }, | |
| { sym => "♣", color => $BLACK }, | |
| { sym => "♥", color => $RED }, | |
| { sym => "♦", color => $RED }, | |
| ); | |
| # joker removed | |
| my @ranks = ("A", 2..10, "J", "Q", "K"); | |
| my $running = 0; | |
| my $tag; | |
| # tuning | |
| my $LINE_WIDTH = 80; | |
| my $LOGICAL_W = 7; # collision + visual width | |
| my $MIN_GAP = 2; | |
| my $MAX_CARDS = 3; | |
| my $TICK_MS = 50; | |
| my $BANNER_CHANCE = 0.08; | |
| my @last_positions; | |
| sub random_card { | |
| my $s = $suits[int(rand(@suits))]; | |
| my $r = $ranks[int(rand(@ranks))]; | |
| # FIXED WIDTH LOGIC (handles 10 correctly) | |
| my $rank_len = length($r); | |
| my $gap = $LOGICAL_W - 1 - $rank_len; | |
| $gap = 1 if $gap < 1; | |
| my $text = $s->{sym} . (" " x $gap) . $r; | |
| # RESTORED WHITE BACKGROUND (card tile look) | |
| return $WHITE_BG . $s->{color} . $text . $RESET; | |
| } | |
| sub garish_banner { | |
| my $msg = " 5.21e5 CARD PICKUP! "; | |
| my @colors = (4, 7, 8, 9, 11, 12, 13); | |
| my $out = ""; | |
| my $i = 0; | |
| foreach my $ch (split //, $msg) { | |
| my $fg = $colors[$i % @colors]; | |
| $out .= sprintf("\x03%02d%s", $fg, $ch); | |
| $i++; | |
| } | |
| return $out . $RESET; | |
| } | |
| sub valid_position { | |
| my ($pos, $current_ref) = @_; | |
| for my $p (@$current_ref) { | |
| return 0 if abs($p - $pos) < ($LOGICAL_W + $MIN_GAP); | |
| } | |
| for my $p (@last_positions) { | |
| return 0 if abs($p - $pos) < ($LOGICAL_W + $MIN_GAP); | |
| } | |
| return 1; | |
| } | |
| sub pick_positions { | |
| my $count = 1 + int(rand($MAX_CARDS)); | |
| my @pos; | |
| for (1..$count) { | |
| for (1..30) { | |
| my $p = int(rand($LINE_WIDTH - $LOGICAL_W)); | |
| if (valid_position($p, \@pos)) { | |
| push @pos, $p; | |
| last; | |
| } | |
| } | |
| } | |
| return sort { $a <=> $b } @pos; | |
| } | |
| sub build_line { | |
| my @pos = pick_positions(); | |
| @last_positions = @pos; | |
| my $line = ""; | |
| my $cursor = 0; | |
| for my $p (@pos) { | |
| my $spaces = $p - $cursor; | |
| $spaces = $MIN_GAP if $spaces < $MIN_GAP; | |
| $line .= " " x $spaces; | |
| $line .= random_card(); | |
| $cursor = $p + $LOGICAL_W; | |
| } | |
| return $line; | |
| } | |
| sub spam_tick { | |
| my ($server, $target) = @_; | |
| return unless $running; | |
| return unless $server && $server->{connected}; | |
| if (rand() < $BANNER_CHANCE) { | |
| $server->command("MSG $target " . garish_banner()); | |
| } else { | |
| $server->command("MSG $target " . build_line()); | |
| } | |
| } | |
| sub cmd_cards { | |
| my ($data, $server, $witem) = @_; | |
| unless ($witem && $witem->{type} eq "CHANNEL") { | |
| Irssi::print("Join a channel first."); | |
| return; | |
| } | |
| if ($running) { | |
| Irssi::timeout_remove($tag) if defined $tag; | |
| $running = 0; | |
| Irssi::print("5.21e5 card pickup stopped."); | |
| return; | |
| } | |
| my $target = $witem->{name}; | |
| $running = 1; | |
| $tag = Irssi::timeout_add($TICK_MS, sub { | |
| spam_tick($server, $target); | |
| }, undef); | |
| Irssi::print("5.21e5 card pickup started."); | |
| } | |
| Irssi::command_bind('cards', 'cmd_cards'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment