mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-07-21 15:45:36 +08:00
prerelease of beta1
This commit is contained in:
85
src/ZM/Utils/CatCode.php
Normal file
85
src/ZM/Utils/CatCode.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZM\Utils;
|
||||
|
||||
use OneBot\V12\Object\MessageSegment;
|
||||
|
||||
class CatCode
|
||||
{
|
||||
/**
|
||||
* 从 MessageSegment 转换为 CatCode 字符串
|
||||
*/
|
||||
public static function fromSegment(mixed $message_segment): string
|
||||
{
|
||||
// 传入的必须是段数组或段对象
|
||||
if (is_array($message_segment)) {
|
||||
$str = '';
|
||||
foreach ($message_segment as $v) {
|
||||
if (!$v instanceof MessageSegment) {
|
||||
return '';
|
||||
}
|
||||
$str .= self::segment2CatCode($v);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
if ($message_segment instanceof MessageSegment) {
|
||||
return self::segment2CatCode($message_segment);
|
||||
}
|
||||
if (is_string($message_segment)) {
|
||||
return $message_segment;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 转义CatCode的特殊字符
|
||||
*
|
||||
* @param int|string|\Stringable $msg 字符串
|
||||
* @param bool $is_content 如果是转义CatCode本体内容,则为false(默认),如果是参数内的字符串,则为true
|
||||
* @return string 转义后的CatCode
|
||||
*/
|
||||
public static function encode(\Stringable|int|string $msg, bool $is_content = false): string
|
||||
{
|
||||
$msg = str_replace(['&', '[', ']'], ['&', '[', ']'], (string) $msg);
|
||||
if ($is_content) {
|
||||
$msg = str_replace(',', ',', $msg);
|
||||
}
|
||||
return $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 反转义字符串中的CatCode敏感符号
|
||||
*
|
||||
* @param int|string|\Stringable $msg 字符串
|
||||
* @param bool $is_content 如果是解码CatCode本体内容,则为false(默认),如果是参数内的字符串,则为true
|
||||
* @return string 转义后的CatCode
|
||||
*/
|
||||
public static function decode(\Stringable|int|string $msg, bool $is_content = false): string
|
||||
{
|
||||
$msg = str_replace(['&', '[', ']'], ['&', '[', ']'], (string) $msg);
|
||||
if ($is_content) {
|
||||
$msg = str_replace(',', ',', $msg);
|
||||
}
|
||||
return $msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换一个 Segment 为 CatCode
|
||||
*
|
||||
* @param MessageSegment $segment 段对象
|
||||
*/
|
||||
private static function segment2CatCode(MessageSegment $segment): string
|
||||
{
|
||||
if ($segment->type === 'text') {
|
||||
return $segment->data['text'];
|
||||
}
|
||||
$str = '[CatCode:' . $segment->type;
|
||||
foreach ($segment->data as $key => $value) {
|
||||
$str .= ',' . $key . '=' . self::encode($value, true);
|
||||
}
|
||||
$str .= ']';
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@ class ConnectionUtil
|
||||
*/
|
||||
public static function setConnection(int $fd, array $handle): void
|
||||
{
|
||||
logger()->notice('设置连接情况:' . json_encode($handle));
|
||||
self::$connection_handles[$fd] = array_merge(self::$connection_handles[$fd] ?? [], $handle);
|
||||
// 这里下面为连接准入,允许接入反向 WS
|
||||
if (ProcessStateManager::$process_mode['worker'] > 1) {
|
||||
@@ -72,4 +73,15 @@ class ConnectionUtil
|
||||
@unlink(zm_dir(ZM_STATE_DIR . '/.WS' . $fd . '.' . ProcessManager::getProcessId()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取记录连接内容的特殊信息
|
||||
*
|
||||
* @param int $fd WS 连接 ID
|
||||
* @return null|mixed
|
||||
*/
|
||||
public static function getConnection(int $fd)
|
||||
{
|
||||
return self::$connection_handles[$fd] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
76
src/ZM/Utils/MessageUtil.php
Normal file
76
src/ZM/Utils/MessageUtil.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ZM\Utils;
|
||||
|
||||
use OneBot\V12\Object\MessageSegment;
|
||||
|
||||
/**
|
||||
* 机器人消息处理工具类
|
||||
*/
|
||||
class MessageUtil
|
||||
{
|
||||
/**
|
||||
* 将消息段无损转换为 CatCode 字符串
|
||||
*
|
||||
* @param array $message_segment 消息段
|
||||
*/
|
||||
public static function arrayToStr(array $message_segment): string
|
||||
{
|
||||
return CatCode::fromSegment($message_segment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将含有 CatCode 字符串的消息文本无损转换为消息段数组
|
||||
*
|
||||
* @param string $msg 字符串消息(包含 CatCode 的)
|
||||
* @param bool $assoc_result 是否返回关联数组形式。当值为 True 时,返回的是数组形式,否则返回 MessageSegment[] 对象列表形式(默认为 False)
|
||||
* @param bool $ignore_space 是否忽略空行(默认为 True)
|
||||
* @param bool $trim_text 是否去除空格文本(默认为 False)
|
||||
* @return array|MessageSegment[]
|
||||
*/
|
||||
public static function strToArray(string $msg, bool $assoc_result = false, bool $ignore_space = true, bool $trim_text = false): array
|
||||
{
|
||||
$arr = [];
|
||||
while (($rear = mb_strstr($msg, '[CatCode:')) !== false && ($end = mb_strstr($rear, ']', true)) !== false) {
|
||||
// 把 [CatCode: 前面的文字生成段落
|
||||
$front = mb_strstr($msg, '[CatCode:', true);
|
||||
// 如果去掉空格都还有文字,或者不去掉空格有字符,且不忽略空格,则生成段落,否则不生成
|
||||
if (($trim_front = trim($front)) !== '' || ($front !== '' && !$ignore_space)) {
|
||||
$text = CatCode::decode($trim_text ? $trim_front : $front);
|
||||
$arr[] = $assoc_result ? ['type' => 'text', 'data' => ['text' => $text]] : new MessageSegment('text', ['text' => $text]);
|
||||
}
|
||||
// 处理 CatCode
|
||||
$content = mb_substr($end, 4);
|
||||
$cq = explode(',', $content);
|
||||
$object_type = array_shift($cq);
|
||||
$object_params = [];
|
||||
foreach ($cq as $v) {
|
||||
$key = mb_strstr($v, '=', true);
|
||||
$object_params[$key] = CatCode::decode(mb_substr(mb_strstr($v, '='), 1), true);
|
||||
}
|
||||
$arr[] = $assoc_result ? ['type' => $object_type, 'data' => $object_params] : new MessageSegment($object_type, $object_params);
|
||||
$msg = mb_substr(mb_strstr($rear, ']'), 1);
|
||||
}
|
||||
if (($trim_msg = trim($msg)) !== '' || ($msg !== '' && !$ignore_space)) {
|
||||
$text = CatCode::decode($trim_text ? $trim_msg : $msg);
|
||||
$arr[] = $assoc_result ? ['type' => 'text', 'data' => ['text' => $text]] : new MessageSegment('text', ['text' => $text]);
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
public static function convertToArr(MessageSegment|\Stringable|array|string $message)
|
||||
{
|
||||
if (is_array($message)) {
|
||||
return $message;
|
||||
}
|
||||
if ($message instanceof MessageSegment) {
|
||||
return [$message];
|
||||
}
|
||||
if ($message instanceof \Stringable) {
|
||||
return new MessageSegment('text', ['text' => $message->__toString()]);
|
||||
}
|
||||
return new MessageSegment('text', ['text' => $message]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user