Files
zhamao-framework/src/cqbot/utils/CQUtil.php

368 lines
13 KiB
PHP
Raw Normal View History

<?php
/**
* Created by PhpStorm.
* User: jerry
* Date: 2018/4/12
* Time: 10:39
*/
2018-04-28 16:20:44 +08:00
use DataProvider as DP;
class CQUtil
{
public static function initEmptyCaches() {
$ls = [
"user", // 储存用户对象的数组
"sent_api", // 储存每条API请求的会调函数Closure等原始内容
"msg_speed", // 储存记录消息速度的数组
"bug_msg_list" // 储存当前状态下所有未发出去的消息列表
];
foreach ($ls as $v) {
Cache::set($v, []);
}
}
2018-10-29 11:47:58 +08:00
public static function loadAllFiles() {
Cache::set("info_level", settings()["info_level"]);
Console::debug("loading configs...");
Cache::set("mods", self::getMods());//加载的模块列表
Cache::set("group_list", DP::getJsonData("group_list.json"));//获取群组列表
Cache::set("admin_group", settings()["admin_group"]);
2018-10-29 11:47:58 +08:00
//加载全局屏蔽的机器人列表
Cache::set("bots", DP::getJsonData("bots.json"));
2018-10-29 11:47:58 +08:00
//调用各个模块单独的Buffer数据
2018-07-18 17:56:36 +08:00
foreach (self::getMods() as $v) {
if (in_array("initValues", get_class_methods($v))) {
$v::initValues();
}
}
2018-04-28 16:20:44 +08:00
}
2018-04-28 16:20:44 +08:00
public static function saveAllFiles() {
Console::info("Saving files... ", null, "");
2018-10-29 11:47:58 +08:00
DP::setJsonDataAsync("bots.json", Cache::get("bots"));
DP::setJsonDataAsync("group_list.json", Cache::get("group_list"));
2018-04-28 16:20:44 +08:00
//保存用户数据
if (settings()["save_user_data"]) {
foreach (self::getAllUsers() as $k => $v) {
$serial = serialize($v);
file_put_contents(DP::getUserFolder() . $k . ".dat", $serial);
}
2018-04-28 16:20:44 +08:00
}
Console::put("Saved files.");
}
/**
* 生成报错日志
* @param $log
* @param string $head
* @param int $send_debug_message
*/
2018-10-29 11:47:58 +08:00
public static function errorLog($log, $head = "ERROR", $send_debug_message = 1) {
Console::error($log, ($head === "ERROR") ? null : "[" . $head . "] ");
$time = date("Y-m-d H:i:s");
$msg = "[$head @ $time]: $log\n";
file_put_contents(DP::getDataFolder() . "log_error.txt", $msg, FILE_APPEND);
if ($send_debug_message) CQAPI::debug($msg);
}
2018-10-29 11:47:58 +08:00
static function findRobot() {
foreach (ConnectionManager::getAll("robot") as $v) {
2018-10-29 11:47:58 +08:00
return $v->getQQ();
}
return null;
}
/**
* 获取运行时间
* @param $time
* @return array
*/
2018-04-28 16:20:44 +08:00
static function getRunTime($time) {
$time_len = time() - $time;
$run_time = [];
if (intval($time_len / 86400) > 0) {
$run_time[0] = intval($time_len / 86400);
$time_len = $time_len % 86400;
2018-04-28 16:20:44 +08:00
} else {
$run_time[0] = 0;
}
if (intval($time_len / 3600) > 0) {
$run_time[1] = intval($time_len / 3600);
$time_len = $time_len % 3600;
2018-04-28 16:20:44 +08:00
} else {
$run_time[1] = 0;
}
if (intval($time_len / 60) > 0) {
$run_time[2] = intval($time_len / 60);
$time_len = $time_len % 60;
2018-04-28 16:20:44 +08:00
} else {
$run_time[2] = 0;
}
$run_time[3] = $time_len;
return $run_time;
}
/**
* 获取格式化的运行时间
* @param $time
* @return string
*/
2018-04-28 16:20:44 +08:00
static function getRunTimeFormat($time) {
$time_len = time() - $time;
$msg = "";
if (intval($time_len / 86400) > 0) {
$msg .= intval($time_len / 86400) . "";
$time_len = $time_len % 86400;
}
if (intval($time_len / 3600) > 0) {
$msg .= intval($time_len / 3600) . "小时";
$time_len = $time_len % 3600;
}
if (intval($time_len / 60) > 0) {
$msg .= intval($time_len / 60) . "";
$time_len = $time_len % 60;
}
$msg .= $time_len . "";
return $msg;
}
/**
* 获取所有已经加载到内存的用户。
* read_all为true时会加载所有User.dat到内存中false时仅会读取已经加载到内存的用户
* @param bool $real_all
2018-10-29 11:47:58 +08:00
* @return User[]
*/
2018-04-28 16:20:44 +08:00
static function getAllUsers($real_all = false): array {
if ($real_all === true) {
$dir = scandir(DP::getUserFolder());
unset($dir[0], $dir[1]);
foreach ($dir as $d => $v) {
$vs = explode(".", $v);
if (array_pop($vs) == "dat") {
$class = unserialize(file_get_contents(DP::getUserFolder() . $v));
if (!Cache::array_key_exists("user", $vs[0])) {
Cache::appendKey("user", $vs[0], $class);
}
}
}
}
return Cache::get("user");
}
/**
* 获取用户实例
* @param $id
* @param bool $enable_init
* @return User
*/
static function getUser($id, $enable_init = true) {
$d = Cache::get("user");
if (!isset($d[$id])) {
$r = self::initUser($id, $enable_init);
if (!$r) return null;
$d = Cache::get("user");
}
/** @var User $class */
$class = $d[$id];
return $class;
}
/**
* 初始化用户实例。如果没有此用户的实例数据,会创建
* @param $id
* @param bool $enable_init
* @return bool
*/
static function initUser($id, $enable_init = true) {
if (file_exists(DP::getUserFolder() . $id . ".dat")) $class = unserialize(file_get_contents(DP::getUserFolder() . $id . ".dat"));
else {
if ($enable_init) {
Console::info("无法找到用户 " . $id . " 的数据,正在创建...");
$class = new User($id);
} else return false;
}
Cache::appendKey("user", $id, $class);
return true;
}
/**
* 获取模块列表的通用方法
* @return array
*/
2018-04-28 16:20:44 +08:00
static function getMods() {
$dir = WORKING_DIR . "src/cqbot/mods/";
$dirs = scandir($dir);
$ls = [];
unset($dirs[0], $dirs[1]);
2018-04-28 16:20:44 +08:00
foreach ($dirs as $v) {
if ($v != "ModBase.php" && (strstr($v, ".php") !== false)) {
$name = substr($v, 0, -4);
2018-04-28 16:20:44 +08:00
$ls[] = $name;
Console::debug("loading mod: " . $name);
}
}
/** @var ModBase[] $ls */
for ($i = 0; $i < count($ls) - 1; $i++) {
for ($j = 0; $j < count($ls) - $i - 1; $j++) {
$s = defined($ls[$j] . "::mod_level") ? $ls[$j]::mod_level : 10;
$s1 = defined($ls[$j + 1] . "::mod_level") ? $ls[$j + 1]::mod_level : 10;
//Console::info("Comparing mod " . $ls[$j] . " with " . $ls[$j + 1] . ", level are " . $s . ", " . $s1);
if ($s < $s1) {
$t = $ls[$j + 1];
$ls[$j + 1] = $ls[$j];
$ls[$j] = $t;
}
}
}
for ($i = count($ls) - 1; $i >= 0; $i--) {
$s = defined($ls[$i] . "::mod_level") ? $ls[$i]::mod_level : 10;
if ($s === 0) unset($ls[$i]);
}
return $ls;
}
2018-04-28 16:20:44 +08:00
/**
* 重启框架,此服务重启为全自动的
*/
static function reload() {
2018-04-28 16:20:44 +08:00
Console::info("Reloading server");
self::saveAllFiles();
Cache::$server->reload();
2018-04-28 16:20:44 +08:00
}
/**
* 停止运行框架需要用shell再次开启才能启动
*/
static function stop() {
2018-04-28 16:20:44 +08:00
Console::info("Stopping server...");
self::saveAllFiles();
Cache::$server->shutdown();
2018-04-28 16:20:44 +08:00
}
/**
* 此函数用于解析其他非消息类型事件显示在log里
* @param $req
* @return string
*/
2018-06-03 16:41:13 +08:00
static function executeType($req) {
switch ($req["post_type"]) {
case "message":
return "消息";
2018-06-03 16:41:13 +08:00
case "event"://兼容3.x
switch ($req["event"]) {
case "group_upload":
2018-06-03 16:41:13 +08:00
return "群[" . $req["group_id"] . "] 文件上传:" . $req["file"]["name"] . "" . intval($req["file"]["size"] / 1024) . "kb";
case "group_admin":
2018-06-03 16:41:13 +08:00
switch ($req["sub_type"]) {
case "set":
2018-06-03 16:41:13 +08:00
return "群[" . $req["group_id"] . "] 设置管理员:" . $req["user_id"];
case "unset":
2018-06-03 16:41:13 +08:00
return "群[" . $req["group_id"] . "] 取消管理员:" . $req["user_id"];
default:
return "unknown_group_admin_type";
}
case "group_decrease":
2018-06-03 16:41:13 +08:00
switch ($req["sub_type"]) {
case "leave":
2018-06-03 16:41:13 +08:00
return "群[" . $req["group_id"] . "] 成员主动退群:" . $req["user_id"];
case "kick":
2018-06-03 16:41:13 +08:00
return "群[" . $req["group_id"] . "] 管理员[" . $req["operator_id"] . "]踢出了:" . $req["user_id"];
case "kick_me":
2018-06-03 16:41:13 +08:00
return "群[" . $req["group_id"] . "] 本账号被踢出";
default:
return "unknown_group_decrease_type";
}
case "group_increase":
2018-06-03 16:41:13 +08:00
return "群[" . $req["group_id"] . "] " . $req["operator_id"] . " 同意 " . $req["user_id"] . " 加入了群";
default:
return "unknown_event";
}
case "notice":
switch ($req["notice_type"]) {
case "group_upload":
return "群[" . $req["group_id"] . "] 文件上传:" . $req["file"]["name"] . "" . intval($req["file"]["size"] / 1024) . "kb";
case "group_admin":
switch ($req["sub_type"]) {
case "set":
return "群[" . $req["group_id"] . "] 设置管理员:" . $req["user_id"];
case "unset":
return "群[" . $req["group_id"] . "] 取消管理员:" . $req["user_id"];
default:
return "unknown_group_admin_type";
}
case "group_decrease":
switch ($req["sub_type"]) {
case "leave":
return "群[" . $req["group_id"] . "] 成员主动退群:" . $req["user_id"];
case "kick":
return "群[" . $req["group_id"] . "] 管理员[" . $req["operator_id"] . "]踢出了:" . $req["user_id"];
case "kick_me":
return "群[" . $req["group_id"] . "] 本账号被踢出";
default:
return "unknown_group_decrease_type";
}
case "group_increase":
return "群[" . $req["group_id"] . "] " . $req["operator_id"] . " 同意 " . $req["user_id"] . " 加入了群";
default:
return "unknown_event";
}
case "request":
2018-06-03 16:41:13 +08:00
switch ($req["request_type"]) {
case "friend":
2018-06-03 16:41:13 +08:00
return "加好友请求:" . $req["user_id"] . ",验证信息:" . ($req["message"] ?? $req["comment"]);//兼容3.x
case "group":
2018-06-03 16:41:13 +08:00
switch ($req["sub_type"]) {
case "add":
2018-06-03 16:41:13 +08:00
return "加群[" . $req["group_id"] . "] 请求:" . $req["user_id"] . ",请求信息:" . ($req["message"] ?? $req["comment"]);//兼容3.x
case "invite":
2018-06-03 16:41:13 +08:00
return "用户" . $req["user_id"] . "邀请机器人进入群:" . $req["group_id"];
default:
return "unknown_group_type";
}
default:
return "unknown_request_type";
}
default:
return "unknown_post_type";
}
}
2018-10-29 11:47:58 +08:00
static function isRobot($user_id) {
$robots = [];
foreach (ConnectionManager::getAll("robot") as $v) {
if (!in_array($v->getQQ(), $robots))
$robots[] = $v->getQQ();
2018-10-29 11:47:58 +08:00
}
foreach (Cache::get("bots") as $v) {
2018-10-29 11:47:58 +08:00
$robots[] = $v;
}
return in_array($user_id, $robots);
}
static function getRobotAlias($qq) {
return RobotWSConnection::ALIAS_LIST[$qq] ?? "机器人";
2018-10-29 11:47:58 +08:00
}
/**
* 刷新消息速率(每分钟)
* $insert true 时,表明运行此函数时收到了一条消息
* @param bool $insert
*/
static function updateMsg($insert = true) {
$ls = Cache::get("msg_speed");
2018-10-29 11:47:58 +08:00
if ($insert === true)
$ls [] = time();
foreach ($ls as $k => $v) {
if ((time() - $v) > 60) {
array_splice($ls, $k, 1);
}
}
Cache::set("msg_speed", $ls);
2018-10-29 11:47:58 +08:00
}
}