first commit
This commit is contained in:
+29
@@ -0,0 +1,29 @@
|
||||
test
|
||||
sillyplus
|
||||
.vscode
|
||||
dev.go
|
||||
.DS_Store
|
||||
jd_wskey
|
||||
logs/*
|
||||
develop/jd_*
|
||||
data
|
||||
dwz
|
||||
replies
|
||||
qinglongs
|
||||
sets.conf
|
||||
*.exe
|
||||
yummy
|
||||
_*
|
||||
fanli_vip
|
||||
cable
|
||||
sillyplus.cache
|
||||
main
|
||||
sillyplus.pid
|
||||
gitee
|
||||
develop/wx
|
||||
develop/qinglong
|
||||
toulu
|
||||
develop/boltdb
|
||||
develop/core
|
||||
web
|
||||
*.db
|
||||
@@ -0,0 +1,522 @@
|
||||
# 傻妞
|
||||
|
||||
一个不太有用的机器人,不生产消息,只搬运消息。
|
||||
|
||||
## 特性
|
||||
|
||||
- 简单易用的消息搬运功能。
|
||||
- 简单强大的自定义回复功能。
|
||||
- 完整支持 ECMAScript 5.1 的插件系统,基于 [otto](https://github.com/robertkrimen/otto)。
|
||||
- 支持通过内置的阉割版 `Express` / `request` ,接入互联网。
|
||||
- 内置 `Cron` ,轻松实现定时任务。
|
||||
- 持久化的 `Bucket` 存储模块。
|
||||
- 支持同时接入多个平台多个机器人,自己开发。
|
||||
|
||||
## 快速上手
|
||||
|
||||
### 安装
|
||||
|
||||
在 [releases](https://github.com/cdle/sillyplus/releases) 中找到合适自己系统版本的程序运行带 `-t` 可以开启终端机器人,直接与程序进行交互。
|
||||
|
||||
```shell
|
||||
./sillyplus -t
|
||||
2023/05/24 14:12:01.859 [I] 默认使用boltdb进行数据存储。
|
||||
2023/05/24 14:12:01.950 [I] Http服务已运行(8080)。
|
||||
```
|
||||
|
||||
### 开发第一个插件
|
||||
|
||||
```js
|
||||
/**
|
||||
* @title HelleWorld
|
||||
* @rule raw ^你好$
|
||||
*/
|
||||
|
||||
s.reply("Helle World!");
|
||||
```
|
||||
|
||||
怼着程序输入 `你好` ,就可以看到机器人回复的 `Helle World!` 了
|
||||
|
||||
```sh
|
||||
你好
|
||||
2023/05/24 14:15:48.350 [I] 匹配到规则:^你好$
|
||||
Helle World!
|
||||
```
|
||||
|
||||
插件注释 `@rule raw ^你好$` 中的正则表达式被消息匹配时插件脚本就会被触发。
|
||||
|
||||
### 添加和销毁定时任务
|
||||
|
||||
不同于`HelleWorld`,插件注释 `@on_start true` 时是作为傻妞系统服务持续运行的。
|
||||
|
||||
```js
|
||||
/**
|
||||
* @title 定时任务
|
||||
* @on_start true
|
||||
*/
|
||||
|
||||
const task = Cron();
|
||||
let taskId = 0;
|
||||
let times = 5;
|
||||
const { id } = task.add("*/5 * * * * *", () => {
|
||||
// 同样支持分钟级任务,如:*/5 * * * *
|
||||
times--;
|
||||
console.log(
|
||||
`每5秒执行一次任务,${
|
||||
times ? `${times}次后结束任务` : "这是最后一次任务"
|
||||
}。`
|
||||
);
|
||||
if (times == 0) {
|
||||
task.remove(taskId); //移除任务
|
||||
}
|
||||
});
|
||||
taskId = id;
|
||||
```
|
||||
|
||||
程序输出:
|
||||
|
||||
```sh
|
||||
2023/05/27 19:57:00.000 [I] 每5秒执行一次任务,4次后结束任务。
|
||||
2023/05/27 19:57:05.001 [I] 每5秒执行一次任务,3次后结束任务。
|
||||
2023/05/27 19:57:10.001 [I] 每5秒执行一次任务,2次后结束任务。
|
||||
2023/05/27 19:57:15.001 [I] 每5秒执行一次任务,1次后结束任务。
|
||||
2023/05/27 19:57:20.000 [I] 每5秒执行一次任务,这是最后一次任务。
|
||||
```
|
||||
|
||||
### 接入机器人
|
||||
|
||||
接入一个机器人首先 `initAdapter`,然后再通过 `receive` 持续接收消息和设置`setReplyHandler`以发送消息。
|
||||
|
||||
```js
|
||||
/**
|
||||
* @title 第一个机器人
|
||||
* @on_start true
|
||||
*/
|
||||
|
||||
const task = Cron();
|
||||
const qq_1700000 = initAdapter("qq", "1700000"); //初始化机器人,参数分别是平台、机器人ID
|
||||
|
||||
//模拟场景:每5秒用户100009给机器人1700000发送消息你好
|
||||
task.add("*/5 * * * * *", function () {
|
||||
let message = {
|
||||
user_id: 100000, //用户ID,这里是假的,其他也是假的
|
||||
content: "你好", //消息内容ID
|
||||
// chat_id: "", //聊天ID,注意,群聊默认不回复,在对应群聊使用口令listen和reply口令激活群聊
|
||||
// message_id: "", //消息ID
|
||||
// chat_name: "", //群聊名
|
||||
// user_name: "", //用户名
|
||||
};
|
||||
qq_1700000.receive(message); //机器人收到消息
|
||||
});
|
||||
|
||||
qq_1700000.setReplyHandler(function (message) {
|
||||
console.log(`给用户${message.user_id}发消息:${message.content}`); //回复用户
|
||||
});
|
||||
```
|
||||
|
||||
程序每 5 秒都会输出该机器人收到的消息以及同时触发规则运行插件的日志。
|
||||
|
||||
```sh
|
||||
2023/05/24 14:36:50.001 [I] 接收到消息 qq/100000@:你好
|
||||
2023/05/24 14:36:50.001 [I] 匹配到规则:你好
|
||||
2023/05/24 14:36:50.002 [I] 给用户100000发消息:Hello World!
|
||||
```
|
||||
|
||||
### 与用户交互
|
||||
|
||||
```js
|
||||
/**
|
||||
* @title 用户交互插件
|
||||
* @rule 猜拳
|
||||
*/
|
||||
|
||||
s.reply("你先出,请在10秒内出拳!");
|
||||
ns = s.listen({
|
||||
rules: ["[出拳:剪刀,石头,布]"], // []中出拳是参数名,剪刀,石头,布是参数可能值
|
||||
timeout: 10000, // 超时设置
|
||||
handle: (s) => {
|
||||
let choose = s.param("出拳");
|
||||
s.reply(
|
||||
`我出${
|
||||
choose == "石头" ? "剪刀" : choose == "布" ? "剪刀" : "石头"
|
||||
},我赢了。`
|
||||
);
|
||||
},
|
||||
});
|
||||
if (!ns) {
|
||||
s.reply("你没出拳,算我赢了!");
|
||||
}
|
||||
```
|
||||
|
||||
### 开发 HTTP 接口
|
||||
|
||||
```js
|
||||
/**
|
||||
* @title 第一个web服务
|
||||
* @on_start true
|
||||
*/
|
||||
|
||||
const app = Express(); //导入HTTP服务,傻妞默认开启,端口8080
|
||||
app.get("/helloWorld", function (req, res) {
|
||||
res.send("Hello world!");
|
||||
});
|
||||
```
|
||||
|
||||
打开浏览器访问 `http://127.0.0.1:8080/helloWorld` ,当然地址根据实际情况,理论上可以看到接口返回的 `Hello world!` 。
|
||||
|
||||
### 实现一个 HTTP 请求
|
||||
|
||||
```js
|
||||
/**
|
||||
* @title 实现一个HTTP 请求
|
||||
* @on_start true
|
||||
*/
|
||||
|
||||
let api = "/testRequest"; //接口地址
|
||||
|
||||
//第一步,实现一个原样返回请求数据的接口
|
||||
const app = Express();
|
||||
app.post(api, (req, res) => res.json(req.json()));
|
||||
|
||||
//第二步,请求第一步实现的接口
|
||||
const port = Bucket("app").port ?? "8080"; // 获取http服务端口
|
||||
const url = `http://127.0.0.1:${port}${api}`;
|
||||
request({
|
||||
url,
|
||||
method: "POST",
|
||||
body: { value: "test" },
|
||||
})
|
||||
.then((resp) => resp.json())
|
||||
.then((data) => console.log(`value is ${data.value}`))
|
||||
.catch((e) => console.log(e));
|
||||
```
|
||||
|
||||
### 持久化存储
|
||||
|
||||
```js
|
||||
/**
|
||||
* @title 持久化存储
|
||||
* @rule raw ^我是谁$
|
||||
* @rule 我是[姓名]
|
||||
*/
|
||||
|
||||
const user = Bucket("user"); //初始化存储桶user
|
||||
let name = s.param("姓名");
|
||||
|
||||
if (user.name == "") {
|
||||
s.reply(`我不知道你是谁!`);
|
||||
} else if (name == "谁") {
|
||||
s.reply(`你是${user.name}`);
|
||||
} else {
|
||||
user.name = name;
|
||||
s.reply(`好的,你的姓名更新为${user.name}`);
|
||||
}
|
||||
```
|
||||
|
||||
插件实现了记名字的功能,其中`姓名`是方括号里匹配到的值,本质还是正则匹配到的。
|
||||
|
||||
```
|
||||
我是谁
|
||||
2023/05/24 15:43:40.121 [I] 匹配到规则:^我是谁$
|
||||
我不知道你是谁!
|
||||
我是小千
|
||||
2023/05/24 15:43:49.735 [I] 匹配到规则:^我是([\s\S]+)$
|
||||
好的,你的姓名更新为小千
|
||||
我是谁
|
||||
2023/05/24 15:43:53.727 [I] 匹配到规则:^我是谁$
|
||||
你是小千
|
||||
```
|
||||
|
||||
有了 `Bucket` 才有了傻妞从不认识小千到认识小千的过程。
|
||||
|
||||
### 管理员
|
||||
|
||||
```js
|
||||
const masters = Bucket("qq")["masters"];
|
||||
```
|
||||
|
||||
`masters` 是管理员账号通过"&"拼接起来的,系统默认依此判断用户是否是管理员。
|
||||
|
||||
### 群组消息
|
||||
|
||||
默认不监听不回复任何群组,监听口令 `listen` 和 `unlisten`,回复口令 `reply` 和 `noreply`,需要管理员在对应群组发送口令。
|
||||
|
||||
## 深入了解
|
||||
|
||||
### 插件注释
|
||||
|
||||
| 字段 | 举例 | 用法 |
|
||||
| ------------- | ---------------------------------- | -------------------------------------------------- |
|
||||
| `title` | HelloWorld | 插件标题 |
|
||||
| `rule` | raw `^我是([\s\S]+)$` | 可写多行,取括号内参数 `s.param(1)` ,多个参数类推 |
|
||||
| `priority` | `1` | 插件优先级,越高则优先处理 |
|
||||
| `on_start` | `true` | 插件后台任务执行脚本,避免重复运行 |
|
||||
| `disable` | `true` | 禁用脚本 |
|
||||
| `form` | `{title: "姓名", key:"user.name"}` | 插件表,key 值对应 `存储桶.键名` |
|
||||
| `public` | `true` | 公开插件 |
|
||||
| `create_at` | 2023-05-24 15:14:53 | 插件创建时间 |
|
||||
| `description` | 本插件用于每天向女友问好 | 插件描述 |
|
||||
| `author` | `cdle` | 插件作者 |
|
||||
| `version` | `v1.0.0` | 插件版本 |
|
||||
| `icon` | url 省略... | 给插件增加图标 |
|
||||
|
||||
### Sender
|
||||
|
||||
傻妞搬运的核心对象,在插件中为全局变量 s or sender。
|
||||
|
||||
```ts
|
||||
interface Sender {
|
||||
getUserId(): string; //获取用户ID
|
||||
getUserName(): string; //获取用户昵称
|
||||
getChatId(): string; //获取群聊ID
|
||||
getChatName(): string; //获取群聊名称
|
||||
getMessageId(): Promise<string>; //获取消息ID
|
||||
getContent(): string; //获取消息内容
|
||||
continue(): void; //使消息继续往下匹配正则,消息正常第一次被匹配就会停止继续匹配
|
||||
setContent(content: string): void; //修改接收到的消息内容,可配合`continue`被其他规则匹配
|
||||
param(index: string | number): string; //获取`rule`匹配参数,可取[]内参数,?型参数从1开始取,例 `@rule 回复 ?` 对应 `s.param(1)`
|
||||
holdOn(content: string): string; //持续监听
|
||||
listen({
|
||||
rules: string[]; //匹配规则
|
||||
timeout: number; //超时,单位毫秒
|
||||
handle: (s: Sender): string;//如果匹配成功,则进入消息处理逻辑。如果将 holdOn(content) 的结果作为返回值,会继续监听
|
||||
listen_private: boolean; //监听用户群内消息时,同时监听用户消息
|
||||
listen_group: boolean; //监听用户群内消息时,同时监听群员消息
|
||||
allow_platforms: string[]; //平台白名单
|
||||
prohibit_platforms: string[]; //平台黑名单
|
||||
allow_groups: string[]; //群聊白名单
|
||||
prohibit_groups: string[]; //群聊黑名单
|
||||
allow_users: string[]; //用户白名单
|
||||
prohibit_users: string[]; //群聊白名单
|
||||
}): Sender; //超时,返回undefined
|
||||
isAdmin(): boolean; //判断消息是否来自管理员
|
||||
getPlatform(): string; //获取消息平台
|
||||
getBotId(): string; //获取机器人ID
|
||||
reply(content: string) Promise<string>; //回复消息,媒体消息推荐使用CQ码实现,返回消息ID
|
||||
recallMessage(meesageId: string | string[]): Promise<boolean>; //撤回消息
|
||||
kick(user_id: string): Promise<boolean>; //移出群聊
|
||||
unkick(user_id: string): Promise<boolean>; //取消移出群聊
|
||||
ban(user_id: string, duration: number): Promise<boolean>; //禁言,并指定时长
|
||||
unban(user_id: string): Promise<boolean>; //取消禁言
|
||||
}
|
||||
```
|
||||
|
||||
### Express `Request` / `Response`
|
||||
|
||||
只能说是够用,有需求可联系作者。插件中通过 `Express()` 返回一个对象。
|
||||
|
||||
```ts
|
||||
interface Request {
|
||||
body(): string; //获取请求体
|
||||
json(): any; //将请求体解析为JSON
|
||||
ip(): string; //获取客户端IP地址
|
||||
originalUrl(): string; //获取原始请求URL
|
||||
query(param: string): string; //获取查询参数
|
||||
param(i: number): string; //根据索引获取路径参数
|
||||
querys(): Record<string, string[]>; //获取所有查询参数
|
||||
postForm(s: string): string; //获取表单数据
|
||||
postForms(): Record<string, string[]>; //获取所有表单数据
|
||||
path(): string; //获取请求路径
|
||||
header(s: string): string; //获取请求头
|
||||
get(s: string): string; //获取请求头
|
||||
headers(): Record<string, string[]>; //获取所有请求头
|
||||
method(): string; //获取请求方法
|
||||
cookie(s: string): string; //获取 cookie
|
||||
cookies(): Record<string, string>; //获取 cookies
|
||||
continue(): void; //继续匹配其他路由
|
||||
setSession(k: string, v: string): string; //设置会话值
|
||||
getSession(k: string): string; //获取会话值
|
||||
getSessionId(): string; //获取会话ID
|
||||
destroySession(): string; //销毁会话
|
||||
logined(): boolean; //是否面板登录状态
|
||||
}
|
||||
|
||||
interface Response {
|
||||
send(body: any): Response; //发送响应体
|
||||
sendStatus(status: number): Response; //发送状态码
|
||||
json(...ps: any[]): Response; //发送JSON响应
|
||||
header(str: string, value: string): Response; //设置响应头
|
||||
set(str: string, value: string): void; //设置响应头
|
||||
render(view: string, params: Record<string, any>): Response; //渲染视图
|
||||
redirect(...is: any[]): void; //重定向到URL
|
||||
status(i: number, ...s: string[]): Response; //设置状态码和文本
|
||||
setCookie(name: string, value: string, ...i: any[]): Response; //设置 Cookie
|
||||
stop(): void; //代码片段停止
|
||||
}
|
||||
```
|
||||
|
||||
### request
|
||||
|
||||
由 `net/http` 封装而成,如有更多需求可以联系作者。
|
||||
|
||||
```ts
|
||||
function request(options: {
|
||||
url: string; //请求地址
|
||||
method: string; //请求方法
|
||||
headers: { [key: string]: string }; //请求头
|
||||
json: boolean; // 返回json对象,等价于 responseType: "json"
|
||||
timeout: number;//超时参数,单位毫秒
|
||||
form: { [key: string]: any };//formData表单数据,优先于下面的body
|
||||
body: any; // 请求体,支持字符串、二进制,对象自动转json字符串和添加相应请求头
|
||||
allow_redirects: boolean; // 是否允许重定向,默认允许
|
||||
proxy: {
|
||||
url: string, //代理地址,支持http、https、socks5
|
||||
user: string, //
|
||||
password: string, //
|
||||
}
|
||||
}): Promise<response:{
|
||||
status: number; // 状态码,同statusCode
|
||||
headers: { [key: string]: string };
|
||||
body: any;
|
||||
}>
|
||||
```
|
||||
|
||||
### Adapter
|
||||
|
||||
```ts
|
||||
interface Message{
|
||||
message_id: string; // 消息ID
|
||||
user_id: string; // 用户ID
|
||||
chat_id: string; // 聊天ID
|
||||
content: string; // 聊天内容
|
||||
user_name: string; // 用户名
|
||||
chat_name: string; // 群组名
|
||||
}
|
||||
|
||||
class Adapter(botplt: string, botid: string) {
|
||||
isAdapter(botid: string): boolean; //判断id是否为机器人
|
||||
push(message: Message): [messageId: string[], error: string]; //推送消息,无视禁言设置
|
||||
getReplyMessage(): Promise<message: Message>; //获取一条回复消息,实际发送成功后,如果有id,请设置 message.message_id
|
||||
setReplyHandler(func: (message: Message): string): void; //设置回复事件处理方法,方法中返回消息ID,不推荐使用。
|
||||
receive(message: Message): Sender; //接收一个消息,并返回一个Sender对象
|
||||
setRecallMessage(func: (i: string | string[]) => boolean): void;//设置撤回消息函数。
|
||||
setGroupKick(func: (user_id: string, chat_id: string, reject_add_request: boolean) => void): boolean; //设置群聊成员移除函数,reject_add_request指5是否继续接受请求
|
||||
setGroupBan(func: (user_id: string, chat_id: string, duration: number) => void): boolean;//设置群聊成员禁言函数
|
||||
setGroupUnban(func: (user_id: string, chat_id: string) => void): boolean;//设置群聊成员解除禁言函数
|
||||
setIsAdmin(func: (user_id: string) => boolean): void; //设置用户是否是成员函数,默认自动实现
|
||||
destroy(): void;//销毁机器人
|
||||
}
|
||||
function getAdapter(platform: string, bot_id string): [Adapter: string[], error: string]; //获取一个机器人
|
||||
|
||||
function getAdapterBotsID(bot_id string): string[]; //获取一个平台的所有机器人
|
||||
|
||||
function getAdapterBotPlts(platform: string): string[]; //所有机器人平台
|
||||
```
|
||||
|
||||
### Bucket
|
||||
|
||||
例:通过 `Bucket("app")` 初始化一个 app 存储痛
|
||||
|
||||
```ts
|
||||
interface Bucket(name: string) {
|
||||
get(key: string, defaultValue: any): any; // 取值
|
||||
set(key: string, value: any): Error | null; // 设值
|
||||
watch(key: string, event: (old: any, new_: any, key: string) => void); // 设置监听器,key 值为 * 时将监听整个桶的存储事件
|
||||
foreach(func: (key: string, value: any) => void): void; // 遍历值
|
||||
delete(key: string): Error | null; // 删值
|
||||
empty(): Error | undefined; // 清空桶
|
||||
keys(): string[]; // 获取所有键名
|
||||
len(): number | undefined; // 获取数据数目
|
||||
buckets(): string[]; // 获取所有存在的桶名
|
||||
_name(): string; // 获取当前桶名
|
||||
}
|
||||
```
|
||||
|
||||
### Cron
|
||||
|
||||
可以通过`let task = Cron()`返回的对象来添加定时任务 `const {id, error} = task.add("* * * * *", ()=>{})`
|
||||
|
||||
```ts
|
||||
interface Cron {
|
||||
add(crontab: string, ()=>void): {id: number, error: string}//添加定时任务 crontab同时支持秒级和分钟级
|
||||
remove(id: number): void//移除定时任务
|
||||
}
|
||||
```
|
||||
|
||||
### 插件表单
|
||||
|
||||
可以使用注释 `@form {title: "标题", key: "test.title"}` 添加表单元素。当如也可以直接在插件代码中添加,如下。
|
||||
|
||||
```js
|
||||
// 单个表单元素
|
||||
Form({
|
||||
title: "姓名",
|
||||
key: "test.name",
|
||||
});
|
||||
// 多个表单元素
|
||||
Form([
|
||||
{
|
||||
title: "姓名",
|
||||
key: "test.name",
|
||||
},
|
||||
{
|
||||
title: "性别",
|
||||
key: "test.sex",
|
||||
},
|
||||
]);
|
||||
// 使用schema-form
|
||||
Form([
|
||||
{
|
||||
title: "创建时间",
|
||||
key: "test.createName",
|
||||
dataIndex: "test.createName",
|
||||
valueType: "date",
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
key: "test.createName",
|
||||
dataIndex: "test.createName",
|
||||
valueType: "date",
|
||||
},
|
||||
{
|
||||
title: "分组",
|
||||
valueType: "group",
|
||||
columns: [
|
||||
{
|
||||
title: "状态",
|
||||
dataIndex: "test.groupState",
|
||||
valueType: "select",
|
||||
width: "xs",
|
||||
valueEnum: {
|
||||
all: { text: "全部", status: "Default" },
|
||||
open: {
|
||||
text: "未解决",
|
||||
status: "Error",
|
||||
},
|
||||
closed: {
|
||||
text: "已解决",
|
||||
status: "Success",
|
||||
disabled: true,
|
||||
},
|
||||
processing: {
|
||||
text: "解决中",
|
||||
status: "Processing",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "标题",
|
||||
width: "md",
|
||||
dataIndex: "test.groupTitle",
|
||||
formItemProps: {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "此项为必填项",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
```
|
||||
|
||||
### 其他
|
||||
|
||||
```ts
|
||||
sleep(millsec: number): void; //等待
|
||||
md5(string): string; //加密
|
||||
running(): boolean; //服务是否运行
|
||||
uuid(): string; //生成uuid
|
||||
```
|
||||
@@ -0,0 +1,272 @@
|
||||
package qq
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cdle/sillyplus/core"
|
||||
"github.com/cdle/sillyplus/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
var qq = core.MakeBucket("qq")
|
||||
|
||||
type Result struct {
|
||||
Data struct {
|
||||
MessageID interface{} `json:"message_id"`
|
||||
} `json:"data"`
|
||||
Echo string `json:"echo"`
|
||||
}
|
||||
|
||||
type GroupList struct {
|
||||
Retcode int `json:"retcode"`
|
||||
Status string `json:"status"`
|
||||
Data []struct {
|
||||
GroupID int `json:"group_id"`
|
||||
GroupName string `json:"group_name"`
|
||||
// MemberCount int `json:"member_count"`
|
||||
// MaxMemberCount int `json:"max_member_count"`
|
||||
// OwnerID int `json:"owner_id"`
|
||||
// LastJoinTime int `json:"last_join_time"`
|
||||
// ShutupTimeWhole int `json:"shutup_time_whole"`
|
||||
// ShutupTimeMe int `json:"shutup_time_me"`
|
||||
// AdminFlag bool `json:"admin_flag"`
|
||||
// UpdateTime int `json:"update_time"`
|
||||
} `json:"data"`
|
||||
Error interface{} `json:"error"`
|
||||
Echo string `json:"echo"`
|
||||
}
|
||||
|
||||
type CallApi struct {
|
||||
Action string `json:"action"`
|
||||
Echo string `json:"echo"`
|
||||
Params map[string]interface{} `json:"params"`
|
||||
}
|
||||
|
||||
type sender struct {
|
||||
Nickname string `json:"nickname"`
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
GroupID interface{} `json:"group_id"`
|
||||
Message string `json:"message"`
|
||||
MessageID interface{} `json:"message_id"`
|
||||
MessageType string `json:"message_type"`
|
||||
PostType string `json:"post_type"`
|
||||
RawMessage string `json:"raw_message"`
|
||||
SelfID interface{} `json:"self_id"`
|
||||
Sender sender `json:"sender"`
|
||||
// SubType string `json:"sub_type"`
|
||||
Time int `json:"time"`
|
||||
UserID interface{} `json:"user_id"`
|
||||
}
|
||||
|
||||
type GroupInfo struct {
|
||||
GroupID string `json:"group_id"`
|
||||
GroupName string `json:"group_name"`
|
||||
}
|
||||
|
||||
type QQ struct {
|
||||
conn *websocket.Conn
|
||||
sync.RWMutex
|
||||
id int
|
||||
chans map[string]chan string
|
||||
}
|
||||
|
||||
func (qq *QQ) WriteJSON(ca CallApi) (string, error) {
|
||||
var err error
|
||||
cy := make(chan string, 1)
|
||||
defer close(cy)
|
||||
func() {
|
||||
qq.Lock()
|
||||
defer qq.Unlock()
|
||||
qq.id++
|
||||
ca.Echo = fmt.Sprint(qq.id)
|
||||
qq.chans[ca.Echo] = cy
|
||||
err = qq.conn.WriteJSON(ca)
|
||||
}()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
select {
|
||||
case v := <-cy:
|
||||
return v, nil
|
||||
case <-time.After(time.Second * 60):
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
go func() {
|
||||
core.GinApi(core.GET, "/qq/receive", func(c *gin.Context) {
|
||||
auth := c.GetHeader("Authorization")
|
||||
token := qq.GetString("access_token")
|
||||
if token == "" {
|
||||
token = qq.GetString("token")
|
||||
}
|
||||
if token != "" && !strings.Contains(auth, token) {
|
||||
core.Logs.Warn("Onebot机器人access_token不正确,小心有人攻击你的傻妞!!!%s ? %s", token, auth)
|
||||
}
|
||||
if token == "" {
|
||||
core.Logs.Warn(`你需要在Onebot机器人配置access_token以及在傻妞配置对应的参数(set qq access_token ?)才能保证连接安全,如果不设置将会造成信息泄露和资产损失!!!`)
|
||||
}
|
||||
var upGrader = websocket.Upgrader{
|
||||
CheckOrigin: func(r *http.Request) bool {
|
||||
return true
|
||||
},
|
||||
}
|
||||
ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
c.Writer.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
botID := c.GetHeader("X-Self-ID")
|
||||
qqcon := &QQ{
|
||||
conn: ws,
|
||||
chans: make(map[string]chan string),
|
||||
}
|
||||
adapter := &core.Factory{}
|
||||
adapter.Init("qq", botID)
|
||||
defer adapter.Destroy()
|
||||
adapter.SetGroupKick(func(uid string, gid string, reject_add_request bool) bool {
|
||||
qqcon.WriteJSON(CallApi{
|
||||
Action: "set_group_kick",
|
||||
Params: map[string]interface{}{
|
||||
"group_id": utils.Int(gid),
|
||||
"user_id": utils.Int(uid),
|
||||
"reject_add_request": reject_add_request,
|
||||
},
|
||||
})
|
||||
return true
|
||||
})
|
||||
adapter.SetGroupBan(func(uid string, gid string, duration int) bool {
|
||||
qqcon.WriteJSON(CallApi{
|
||||
Action: "set_group_ban",
|
||||
Params: map[string]interface{}{
|
||||
"group_id": utils.Int(gid),
|
||||
"user_id": utils.Int(uid),
|
||||
"duration": duration,
|
||||
},
|
||||
})
|
||||
return true
|
||||
})
|
||||
adapter.SetGroupUnban(func(uid string, gid string) bool {
|
||||
qqcon.WriteJSON(CallApi{
|
||||
Action: "set_group_ban",
|
||||
Params: map[string]interface{}{
|
||||
"group_id": utils.Int(gid),
|
||||
"user_id": utils.Int(uid),
|
||||
"duration": 1,
|
||||
},
|
||||
})
|
||||
return true
|
||||
})
|
||||
adapter.SetReplyHandler(func(msg map[string]string) string {
|
||||
if utils.IsZeroOrEmpty(msg[core.CHAT_ID]) {
|
||||
id, err := qqcon.WriteJSON(CallApi{
|
||||
Action: "send_private_msg",
|
||||
Params: map[string]interface{}{
|
||||
"user_id": msg[core.USER_ID],
|
||||
"message": msg[core.CONETNT],
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
core.Logs.Warn("QQ发送私聊消息错误:", err)
|
||||
}
|
||||
return id
|
||||
} else {
|
||||
id, err := qqcon.WriteJSON(CallApi{
|
||||
Action: "send_group_msg",
|
||||
Params: map[string]interface{}{
|
||||
"group_id": msg[core.CHAT_ID],
|
||||
"user_id": msg[core.USER_ID],
|
||||
"message": msg[core.CONETNT],
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
core.Logs.Warn("QQ发送群组消息错误:", err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
})
|
||||
|
||||
// qqcon.WriteJSON(CallApi{
|
||||
// Action: "get_group_list",
|
||||
// Params: map[string]interface{}{},
|
||||
// })
|
||||
go func() {
|
||||
time.Sleep(time.Second * 3)
|
||||
qqcon.WriteJSON(CallApi{
|
||||
Action: "get_group_list",
|
||||
Params: map[string]interface{}{},
|
||||
})
|
||||
}()
|
||||
for {
|
||||
_, data, err := ws.ReadMessage()
|
||||
if err != nil {
|
||||
ws.Close()
|
||||
break
|
||||
}
|
||||
// fmt.Println(string(data))
|
||||
{
|
||||
res := &GroupList{}
|
||||
json.Unmarshal(data, res)
|
||||
for _, group := range res.Data {
|
||||
core.CreateNickName(&core.Nickname{
|
||||
Group: true,
|
||||
Value: group.GroupName,
|
||||
ID: strconv.Itoa(group.GroupID),
|
||||
Platform: "qq",
|
||||
BotsID: []string{botID},
|
||||
})
|
||||
}
|
||||
}
|
||||
{
|
||||
res := &Result{}
|
||||
json.Unmarshal(data, res)
|
||||
if res.Echo != "" {
|
||||
func() {
|
||||
qqcon.RLock()
|
||||
defer qqcon.RUnlock()
|
||||
if c, ok := qqcon.chans[res.Echo]; ok {
|
||||
c <- fmt.Sprint(res.Data.MessageID)
|
||||
}
|
||||
}()
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
msg := &Message{}
|
||||
json.Unmarshal(data, msg)
|
||||
if msg.MessageType != "private" && adapter.IsAdapter(botID) {
|
||||
continue
|
||||
}
|
||||
if msg.SelfID == msg.UserID {
|
||||
continue
|
||||
}
|
||||
msg.RawMessage = strings.ReplaceAll(msg.RawMessage, "\\r", "\n")
|
||||
msg.RawMessage = regexp.MustCompile(`[\n\r]+`).ReplaceAllString(msg.RawMessage, "\n")
|
||||
content := msg.RawMessage
|
||||
content = strings.Replace(content, "amp;", "", -1)
|
||||
content = strings.Replace(content, "[", "[", -1)
|
||||
content = strings.Replace(content, "]", "]", -1)
|
||||
content = strings.Trim(content, " ")
|
||||
adapter.Receive(map[string]interface{}{
|
||||
"user_id": fmt.Sprint(msg.UserID),
|
||||
"chat_id": core.ChatID(msg.GroupID),
|
||||
"user_name": msg.Sender.Nickname,
|
||||
"chat_name": "",
|
||||
"message_id": fmt.Sprint(msg.MessageID),
|
||||
"content": content,
|
||||
})
|
||||
}
|
||||
})
|
||||
}()
|
||||
}
|
||||
Submodule
+1
Submodule core added at f6ec37ada2
@@ -0,0 +1,59 @@
|
||||
module github.com/cdle/sillyplus
|
||||
|
||||
go 1.18
|
||||
|
||||
replace github.com/willf/bitset v1.2.0 => github.com/bits-and-blooms/bitset v1.2.0
|
||||
|
||||
replace gorm.io/gorm => github.com/go-gorm/gorm v1.22.5
|
||||
|
||||
require (
|
||||
github.com/beego/beego/v2 v2.0.1
|
||||
github.com/boltdb/bolt v1.3.1
|
||||
github.com/buger/jsonparser v1.1.1
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58
|
||||
github.com/dop251/goja v0.0.0-20230427124612-428fc442ff5f
|
||||
github.com/dop251/goja_nodejs v0.0.0-20230322100729-2550c7b6c124
|
||||
github.com/elastic/go-elasticsearch/v6 v6.8.5
|
||||
github.com/gin-gonic/gin v1.8.1
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/goccy/go-json v0.9.7
|
||||
github.com/gogo/protobuf v1.3.1
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/stretchr/testify v1.8.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/net v0.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dlclark/regexp2 v1.10.0 // indirect
|
||||
github.com/gin-contrib/gzip v0.0.6
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.10.0 // indirect
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644
|
||||
github.com/ugorji/go/codec v1.2.7 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
)
|
||||
@@ -0,0 +1,378 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
|
||||
github.com/beego/beego/v2 v2.0.1 h1:07a7Z0Ok5vbqyqh+q53sDPl9LdhKh0ZDy3gbyGrhFnE=
|
||||
github.com/beego/beego/v2 v2.0.1/go.mod h1:8zyHi1FnWO1mZLwTn62aKRIZF/aIKvkCBB2JYs+eqQI=
|
||||
github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ=
|
||||
github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
|
||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
|
||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
|
||||
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
|
||||
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||
github.com/coreos/etcd v3.3.25+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U=
|
||||
github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
|
||||
github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
|
||||
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
|
||||
github.com/dop251/goja v0.0.0-20221118162653-d4bf6fde1b86/go.mod h1:yRkwfj0CBpOGre+TwBsqPV0IH0Pk73e4PXJOeNDboGs=
|
||||
github.com/dop251/goja v0.0.0-20230427124612-428fc442ff5f h1:3Z9NjtffvA8Qoh8xjgUpPmyKawJw/mDRcJlR9oPCvqI=
|
||||
github.com/dop251/goja v0.0.0-20230427124612-428fc442ff5f/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
|
||||
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
|
||||
github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM=
|
||||
github.com/dop251/goja_nodejs v0.0.0-20230322100729-2550c7b6c124 h1:QDuDMgEkC/lnmvk0d/fZfcUUml18uUbS9TY5QtbdFhs=
|
||||
github.com/dop251/goja_nodejs v0.0.0-20230322100729-2550c7b6c124/go.mod h1:0tlktQL7yHfYEtjcRGi/eiOkbDR5XF7gyFFvbC5//E0=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elastic/go-elasticsearch/v6 v6.8.5 h1:U2HtkBseC1FNBmDr0TR2tKltL6FxoY+niDAlj5M8TK8=
|
||||
github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
|
||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||
github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
|
||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||
github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
|
||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
|
||||
github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3 h1:2XF1Vzq06X+inNqgJ9tRnGuw+ZVCB3FazXODD6JE1R8=
|
||||
github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||
github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo=
|
||||
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
|
||||
github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
|
||||
github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s=
|
||||
github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||
github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||
github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
|
||||
go.etcd.io/etcd v3.3.25+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
|
||||
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
n="sillyplus"
|
||||
s="/usr/local/$n"
|
||||
a=arm64
|
||||
if [[ $(uname -a | grep "x86_64") != "" ]]; then
|
||||
a=amd64
|
||||
fi ;
|
||||
if [ ! -d $s ]; then
|
||||
mkdir $s
|
||||
fi ;
|
||||
cd $s;
|
||||
rm -rf $n;
|
||||
v=`curl https://gitlab.com/cdle/$a/-/raw/main/compile_time.go --silent | tr -cd "[0-9]"`
|
||||
d=""
|
||||
if [ ${#v} == 13 ]; then
|
||||
d="https://gitlab.com/cdle/${a}/-/raw/main/sillyplus_linux_${a}_${v}"
|
||||
else
|
||||
v=`curl https://raw.githubusercontent.com/cdle/binary/main/compile_time.go --silent | tr -cd "[0-9]"`
|
||||
if [ ${#v} == 13 ]; then
|
||||
d="https://raw.githubusercontent.com/cdle/binary/main/sillyplus_linux_${a}_${v}"
|
||||
else
|
||||
echo "Sorry,你网不好!"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
echo "检测到版本 $v"
|
||||
echo "正在从 $d 下载..."
|
||||
curl -o $n $d && chmod 777 $n
|
||||
echo "傻妞已安装到 $s"
|
||||
echo "请手动运行 $s/$n -t"
|
||||
@@ -0,0 +1,57 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
_ "github.com/cdle/sillyplus/adapters/qq"
|
||||
_ "github.com/cdle/sillyplus/adapters/web"
|
||||
"github.com/cdle/sillyplus/core"
|
||||
|
||||
"github.com/cdle/sillyplus/utils"
|
||||
)
|
||||
|
||||
var sillyplus = core.MakeBucket("sillyplus")
|
||||
|
||||
func main() {
|
||||
loc, _ := time.LoadLocation("Asia/Shanghai")
|
||||
time.Local = loc
|
||||
core.Init()
|
||||
if sillyplus.GetBool("anti_kasi") {
|
||||
go utils.MonitorGoroutine()
|
||||
}
|
||||
d := false
|
||||
for _, arg := range os.Args {
|
||||
if arg == "-d" {
|
||||
d = true
|
||||
}
|
||||
}
|
||||
if !d {
|
||||
t := false
|
||||
for _, arg := range os.Args {
|
||||
if arg == "-t" {
|
||||
t = true
|
||||
}
|
||||
}
|
||||
if t {
|
||||
core.Logs.Info("Terminal机器人已连接。")
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
for scanner.Scan() {
|
||||
data := scanner.Text()
|
||||
f := &core.Faker{
|
||||
Type: "terminal",
|
||||
Message: string(data),
|
||||
Admin: true,
|
||||
}
|
||||
core.Messages <- f
|
||||
}
|
||||
core.Logs.Info("Terminal机器人异常,请检查运行环境设置,如果是docker环境,请附加-it参数")
|
||||
} else {
|
||||
core.Logs.Info("Terminal机器人不可用,运行带-t参数即可启用。")
|
||||
}
|
||||
}
|
||||
select {}
|
||||
}
|
||||
|
||||
//
|
||||
+329
@@ -0,0 +1,329 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
// "github.com/cdle/sillyplus/core/logs"
|
||||
"github.com/cdle/sillyplus/core/logs"
|
||||
"github.com/google/uuid"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
var SlaveMode bool
|
||||
|
||||
func GenUUID() string {
|
||||
u2, _ := uuid.NewUUID()
|
||||
return u2.String()
|
||||
}
|
||||
|
||||
func Float64(str interface{}) float64 {
|
||||
f, _ := strconv.ParseFloat(fmt.Sprint(str), 64)
|
||||
return f
|
||||
}
|
||||
|
||||
func TrimHiddenCharacter(originStr string) string {
|
||||
srcRunes := []rune(originStr)
|
||||
dstRunes := make([]rune, 0, len(srcRunes))
|
||||
for _, c := range srcRunes {
|
||||
if c >= 0 && c <= 31 && c != 10 {
|
||||
continue
|
||||
}
|
||||
if c == 127 {
|
||||
continue
|
||||
}
|
||||
|
||||
dstRunes = append(dstRunes, c)
|
||||
}
|
||||
return strings.ReplaceAll(string(dstRunes), "", "")
|
||||
}
|
||||
|
||||
func Md5(str string) string {
|
||||
h := md5.New()
|
||||
h.Write([]byte(str))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
func Itob(i uint64) []byte {
|
||||
return []byte(fmt.Sprint(i))
|
||||
}
|
||||
|
||||
var Int = func(s interface{}) int {
|
||||
i, _ := strconv.Atoi(fmt.Sprint(s))
|
||||
return i
|
||||
}
|
||||
|
||||
var Int64 = func(s interface{}) int64 {
|
||||
i, _ := strconv.Atoi(fmt.Sprint(s))
|
||||
return int64(i)
|
||||
}
|
||||
|
||||
func init() {
|
||||
for _, arg := range os.Args {
|
||||
if arg == "-d" {
|
||||
Daemon()
|
||||
}
|
||||
}
|
||||
KillPeer()
|
||||
}
|
||||
|
||||
var GetDataHome = func() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return `C:\ProgramData\sillyplus\`
|
||||
} else {
|
||||
if _, err := os.Stat(`/etc/sillyplus/`); err != nil {
|
||||
os.MkdirAll(`/etc/sillyplus/`, os.ModePerm)
|
||||
}
|
||||
return `/etc/sillyplus/`
|
||||
}
|
||||
}
|
||||
|
||||
func KillPeer() {
|
||||
pids, err := ppid()
|
||||
if err == nil {
|
||||
if len(pids) == 0 {
|
||||
return
|
||||
} else {
|
||||
exec.Command("sh", "-c", "kill -9 "+strings.Join(pids, " ")).Output()
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var ProcessName = getProcessName()
|
||||
|
||||
func ppid() ([]string, error) {
|
||||
pid := fmt.Sprint(os.Getpid())
|
||||
pids := []string{}
|
||||
rtn, err := exec.Command("sh", "-c", "pidof "+ProcessName).Output()
|
||||
if err != nil {
|
||||
return pids, err
|
||||
}
|
||||
re := regexp.MustCompile(`[\d]+`)
|
||||
for _, v := range re.FindAll(rtn, -1) {
|
||||
if string(v) != pid {
|
||||
pids = append(pids, string(v))
|
||||
}
|
||||
}
|
||||
return pids, nil
|
||||
}
|
||||
|
||||
var ExecPath, _ = filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
|
||||
var getProcessName = func() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return regexp.MustCompile(`([\w\.-]*)\.exe$`).FindStringSubmatch(os.Args[0])[0]
|
||||
}
|
||||
return regexp.MustCompile(`/([^/\s]+)$`).FindStringSubmatch(os.Args[0])[1]
|
||||
}
|
||||
|
||||
var GetPidFile = func() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return fmt.Sprintf("%s\\%s", ExecPath, "sillyplus.pid")
|
||||
}
|
||||
return "/var/run/sillyplus.pid"
|
||||
}
|
||||
|
||||
var Runnings = []func(){}
|
||||
|
||||
func Daemon() {
|
||||
for _, bs := range Runnings {
|
||||
bs()
|
||||
}
|
||||
args := os.Args[1:]
|
||||
execArgs := make([]string, 0)
|
||||
l := len(args)
|
||||
for i := 0; i < l; i++ {
|
||||
if strings.Contains(args[i], "-d") {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(args[i], "-t") {
|
||||
continue
|
||||
}
|
||||
execArgs = append(execArgs, args[i])
|
||||
}
|
||||
proc := exec.Command(os.Args[0], execArgs...)
|
||||
err := proc.Start()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
logs.Info("程序以静默形式运行")
|
||||
err = os.WriteFile(GetPidFile(), []byte(fmt.Sprintf("%d", proc.Process.Pid)), 0o644)
|
||||
if err != nil {
|
||||
logs.Info(err)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func FetchCookieValue(ps ...string) string {
|
||||
var key, cookies string
|
||||
if len(ps) == 2 {
|
||||
if len(ps[0]) > len(ps[1]) {
|
||||
key, cookies = ps[1], ps[0]
|
||||
} else {
|
||||
key, cookies = ps[0], ps[1]
|
||||
}
|
||||
}
|
||||
match := regexp.MustCompile(key + `=([^;]*);{0,1}`).FindStringSubmatch(cookies)
|
||||
if len(match) == 2 {
|
||||
return strings.Trim(match[1], " ")
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func Contains(strs []string, str ...string) bool {
|
||||
for _, o := range strs {
|
||||
for _, str_ := range strs {
|
||||
if str_ == o {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func Remove(strs []string, str string) []string {
|
||||
for i, o := range strs {
|
||||
if str == o {
|
||||
return append(strs[:i], strs[i+1:]...)
|
||||
}
|
||||
}
|
||||
return strs
|
||||
}
|
||||
|
||||
func SafeError(err error) error {
|
||||
s := err.Error()
|
||||
s = regexp.MustCompile(`(http|https)://[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?`).ReplaceAllString(s, "http://138.2.2.75:5700")
|
||||
return errors.New(s)
|
||||
}
|
||||
|
||||
func MonitorGoroutine() {
|
||||
if runtime.GOOS == "windows" {
|
||||
return
|
||||
}
|
||||
ticker := time.NewTicker(time.Millisecond * 100)
|
||||
lastGNum := 0
|
||||
for {
|
||||
<-ticker.C
|
||||
if newGNum := runtime.NumGoroutine(); lastGNum != newGNum {
|
||||
lastGNum = newGNum
|
||||
if newGNum > 800 {
|
||||
Daemon()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func JsonMarshal(v interface{}) (d []byte) {
|
||||
d, _ = json.Marshal(v)
|
||||
return
|
||||
}
|
||||
|
||||
func ReadYaml(confDir string, conf interface{}, _ string) {
|
||||
path := confDir + "config.yaml"
|
||||
if _, err := os.Stat(confDir); err != nil {
|
||||
os.MkdirAll(confDir, os.ModePerm)
|
||||
}
|
||||
f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0777)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
s, _ := ioutil.ReadAll(f)
|
||||
if len(s) == 0 {
|
||||
return
|
||||
}
|
||||
f.Close()
|
||||
content, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
logs.Warn("解析配置文件%s读取错误: %v", path, err)
|
||||
return
|
||||
}
|
||||
if yaml.Unmarshal(content, conf) != nil {
|
||||
logs.Warn("解析配置文件%s出错: %v", path, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func Str2Ints(str string) []int {
|
||||
is := []int{}
|
||||
for _, v := range Str2IntStr(str) {
|
||||
is = append(is, Int(v))
|
||||
}
|
||||
return is
|
||||
}
|
||||
|
||||
func Str2IntStr(str string) []string {
|
||||
return regexp.MustCompile(`-?[\d]+`).FindAllString(str, -1)
|
||||
}
|
||||
|
||||
func ToVideoQrcode(url string) string {
|
||||
return `[CQ:video,file=` + url + `]`
|
||||
}
|
||||
|
||||
func ToImageQrcode(url string) string {
|
||||
return `[CQ:image,file=` + url + `]`
|
||||
}
|
||||
|
||||
func FormatLog(f interface{}, v ...interface{}) string {
|
||||
var msg string
|
||||
switch f := f.(type) {
|
||||
case string:
|
||||
msg = f
|
||||
if len(v) == 0 {
|
||||
return msg
|
||||
}
|
||||
if strings.Contains(msg, "%") && !strings.Contains(msg, "%%") {
|
||||
//format string
|
||||
} else {
|
||||
//do not contain format char
|
||||
msg += strings.Repeat(" %v", len(v))
|
||||
}
|
||||
default:
|
||||
msg = fmt.Sprint(f)
|
||||
if len(v) == 0 {
|
||||
return msg
|
||||
}
|
||||
msg += strings.Repeat(" %v", len(v))
|
||||
}
|
||||
return fmt.Sprintf(msg, v...)
|
||||
}
|
||||
|
||||
func IsZeroOrEmpty(str string) bool {
|
||||
return str == "0" || str == "" || str == "nil"
|
||||
}
|
||||
|
||||
func Unique(strs ...interface{}) []string {
|
||||
m := make(map[string]bool)
|
||||
var result []string
|
||||
for _, arg := range strs {
|
||||
switch arg := arg.(type) {
|
||||
case []string:
|
||||
for _, v := range arg {
|
||||
if _, ok := m[v]; !ok {
|
||||
m[v] = true
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
case string:
|
||||
if _, ok := m[arg]; !ok {
|
||||
m[arg] = true
|
||||
result = append(result, arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user