Skip to content

Commit ee3f6ca

Browse files
committed
Add Say#sayf
1 parent 3d8e41b commit ee3f6ca

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

src/Chat/Client/ChatClient.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ private function checkAndNormaliseEncoding(string $text): string
7373
return $text;
7474
}
7575

76+
public function stripPingsFromText(string $text): string
77+
{
78+
return preg_replace('#@((?:\p{L}|\p{N})(?:\p{L}|\p{N}|\.|-|_|\')*)#u', "@\u{2060}$1", $text);
79+
}
80+
7681
private function applyPostFlagsToText(string $text, int $flags): string
7782
{
7883
$text = rtrim($this->checkAndNormaliseEncoding($text));
@@ -84,7 +89,7 @@ private function applyPostFlagsToText(string $text, int $flags): string
8489
$text = preg_replace('#(^|\r?\n)#', '$1 ', $text);
8590
}
8691
if (!($flags & PostFlags::ALLOW_PINGS)) {
87-
$text = preg_replace('#@((?:\p{L}|\p{N})(?:\p{L}|\p{N}|\.|-|_|\')*)#u', "@\u{2060}$1", $text);
92+
$text = $this->stripPingsFromText($text);
8893
}
8994
if (!($flags & PostFlags::ALLOW_REPLIES)) {
9095
$text = preg_replace('#^:([0-9]+)\s*#', '', $text);

src/Plugins/Say.php

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
namespace Room11\Jeeves\Plugins;
44

55
use Room11\Jeeves\Chat\Client\ChatClient;
6+
use Room11\Jeeves\Chat\Client\PostFlags;
67
use Room11\Jeeves\Chat\Message\Command;
8+
use Room11\Jeeves\Chat\Room\Room as ChatRoom;
79
use Room11\Jeeves\System\PluginCommandEndpoint;
810

911
class Say extends BasePlugin
@@ -20,6 +22,78 @@ public function say(Command $command)
2022
return $this->chatClient->postMessage($command, implode(' ', $command->getParameters()));
2123
}
2224

25+
public function sayf(Command $command)
26+
{
27+
$current = '';
28+
$components = [];
29+
30+
foreach ($command->getParameters() as $parameter) {
31+
if ($parameter !== '/') {
32+
$current .= str_replace('\\/', '/', $parameter) . ' ';
33+
} else if ($current !== '') {
34+
$components[] = trim($current);
35+
$current = '';
36+
}
37+
}
38+
39+
if ($current !== '') {
40+
$components[] = trim($current);
41+
}
42+
43+
list($string, $args) = yield from $this->processPingFormatSpecifiers($command->getRoom(), $components);
44+
$string = $this->chatClient->stripPingsFromText($string);
45+
46+
if (false === $result = @\vsprintf($string, $args)) {
47+
return $this->chatClient->postReply($command, 'printf() failed, check your format string and arguments');
48+
}
49+
50+
return $this->chatClient->postMessage($command, $result, PostFlags::ALLOW_PINGS);
51+
}
52+
53+
private function processPingFormatSpecifiers(ChatRoom $room, array $components)
54+
{
55+
static $expr = /** @lang RegExp */ "/
56+
%
57+
(?:([0-9]+)\\$)? # position
58+
([-+])? # sign
59+
(\\x20|0|'.)? # padding char
60+
(-)? # alignment
61+
([0-9]+)? # padding width
62+
(\\.[0-9]*)? # precision
63+
(.) # type
64+
/x";
65+
66+
$string = $components[0];
67+
$args = array_slice($components, 1);
68+
69+
if (0 === $count = preg_match_all($expr, $string, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
70+
return [$string, $args];
71+
}
72+
73+
foreach ($matches as $i => $match) {
74+
if ($match[7][0] !== 'p') {
75+
continue;
76+
}
77+
78+
$string = substr_replace($string, 's', $match[7][1], 1);
79+
$argIndex = $match[1][0] !== ''
80+
? $match[1][0] - 1
81+
: $i;
82+
83+
if (!isset($args[$argIndex])) {
84+
continue;
85+
}
86+
87+
if ($args[$argIndex][0] === '@') {
88+
$args[$argIndex] = $this->chatClient->stripPingsFromText($args[$argIndex]);
89+
} else if (null !== $pingable = yield $this->chatClient->getPingableName($room, $args[$argIndex])) {
90+
$args[$argIndex] = '@' . $pingable;
91+
}
92+
}
93+
94+
return [$string, $args];
95+
}
96+
2397
public function getDescription(): string
2498
{
2599
return 'Mindlessly parrots whatever crap you want';
@@ -28,7 +102,8 @@ public function getDescription(): string
28102
public function getCommandEndpoints(): array
29103
{
30104
return [
31-
new PluginCommandEndpoint('say', [$this, 'say'])
105+
new PluginCommandEndpoint('say', [$this, 'say']),
106+
new PluginCommandEndpoint('sayf', [$this, 'sayf'], 'Same as say with printf-style formatting, separate format string and args with / slashes')
32107
];
33108
}
34109
}

0 commit comments

Comments
 (0)