qqbot #1

Merged
milimoe merged 8 commits from qqbot into master 2025-08-02 10:45:22 +00:00
6 changed files with 325 additions and 67 deletions
Showing only changes of commit 0588ed919b - Show all commits

View File

@ -536,6 +536,30 @@ namespace Milimoe.RainBOT.Command
}
}
break;
case "ai":
if (args.Length > 0)
{
if (args[0] != "on" && args[0] != "off")
{
break;
}
status = args[0] == "on";
msg = UpdateValue("AI", GeneralSettings.IsAI ? "开启" : "关闭", status ? "开启" : "关闭");
GeneralSettings.IsAI = status;
return msg;
}
break;
case "pai":
if (args.Length > 0 && int.TryParse(args[0], out int pai))
{
if (pai >= 0 && pai <= 100)
{
msg = UpdateValue("AI的概率", GeneralSettings.PAI + "%", pai + "%");
GeneralSettings.PAI = pai;
return msg;
}
}
break;
case "mute":
if (args.Length > 0)
{

View File

@ -71,10 +71,10 @@ namespace Milimoe.RainBOT.ListeningTask
if ((e.user_id == GeneralSettings.Master || GeneralSettings.RecallAccessGroup.Contains(e.user_id)) && e.detail.Contains("撤回;") && e.message.Any(m => m.type == "reply"))
{
ReplyMessage reply = (ReplyMessage)e.message.Where(m => m.type == "reply").First();
if (int.TryParse(reply.data.id, out int id))
if (long.TryParse(reply.data.id, out long id))
{
await Bot.SendMessage(SupportedAPI.delete_msg, e.group_id, "撤回", new DeleteMsgContent(id), true);
await Bot.SendMessage(SupportedAPI.delete_msg, e.group_id, "撤回", new DeleteMsgContent(e.real_id), true);
await Bot.SendMessage(SupportedAPI.delete_msg, e.group_id, "撤回", new DeleteMsgContent(e.message_id), true);
return quick_reply;
}
}
@ -88,13 +88,13 @@ namespace Milimoe.RainBOT.ListeningTask
if (e.detail.Contains("取消精华;"))
{
await Bot.SendMessage(SupportedAPI.delete_essence_msg, e.group_id, "取消精华", new DeleteEssenceMsgContent(id), true);
await Bot.SendMessage(SupportedAPI.delete_msg, e.group_id, "撤回", new DeleteMsgContent(e.real_id), true);
await Bot.SendMessage(SupportedAPI.delete_msg, e.group_id, "撤回", new DeleteMsgContent(e.message_id), true);
return quick_reply;
}
else
{
await Bot.SendMessage(SupportedAPI.set_essence_msg, e.group_id, "设置精华", new EssenceMsgContent(id), true);
await Bot.SendMessage(SupportedAPI.delete_msg, e.group_id, "撤回", new DeleteMsgContent(e.real_id), true);
await Bot.SendMessage(SupportedAPI.delete_msg, e.group_id, "撤回", new DeleteMsgContent(e.message_id), true);
return quick_reply;
}
}
@ -102,7 +102,7 @@ namespace Milimoe.RainBOT.ListeningTask
if (e.user_id != GeneralSettings.Master && Ignore.CustomIgnore.Any(e.detail.Contains) && Bot.BotIsAdmin(e.group_id))
{
await Bot.SendMessage(SupportedAPI.delete_msg, e.group_id, "撤回", new DeleteMsgContent(e.real_id), true);
await Bot.SendMessage(SupportedAPI.delete_msg, e.group_id, "撤回", new DeleteMsgContent(e.message_id), true);
await Bot.SendMessage(SupportedAPI.set_group_ban, e.group_id, "禁言", new SetGroupBanContent(e.group_id, e.user_id, 120), true);
return quick_reply;
}
@ -111,18 +111,21 @@ namespace Milimoe.RainBOT.ListeningTask
{
if (!await Bot.CheckBlackList(true, e.user_id, e.group_id)) return quick_reply;
_ = OshimaController.Instance.SCList(e.group_id, e.user_id);
return quick_reply;
}
if (e.detail.Contains("出生榜"))
{
if (!await Bot.CheckBlackList(true, e.user_id, e.group_id)) return quick_reply;
_ = OshimaController.Instance.SCList(e.group_id, e.user_id, true);
return quick_reply;
}
if (e.detail.Contains("圣人点数") || e.detail == "查询sc" || e.detail == "sc查询")
{
if (!await Bot.CheckBlackList(true, e.user_id, e.group_id)) return quick_reply;
_ = OshimaController.Instance.SCRecord(e.group_id, e.user_id);
return quick_reply;
}
if (e.detail == "查询服务器启动时间")
@ -148,6 +151,18 @@ namespace Milimoe.RainBOT.ListeningTask
return quick_reply;
}
if (e.user_id == GeneralSettings.Master && e.detail == "查询余额")
{
string msg = await AI.GetBalance();
quick_reply = new(msg);
return quick_reply;
}
if (GeneralSettings.IsAI && GeneralSettings.FunGameGroup.Contains(e.group_id) && (e.detail.StartsWith("小雪") || e.CheckThrow(GeneralSettings.PAI, out _)))
{
AIChat(e);
}
if (!GeneralSettings.IsRun)
{
return quick_reply;
@ -600,6 +615,8 @@ namespace Milimoe.RainBOT.ListeningTask
await Bot.SendGroupMessage(e.group_id, "反向艾特", content);
}
}
AIChat(e, true);
return quick_reply;
}
@ -686,5 +703,18 @@ namespace Milimoe.RainBOT.ListeningTask
return quick_reply;
}
public static void AIChat(GroupMessageEvent e, bool isAt = false)
{
AI.Add(e.user_id == GeneralSettings.Master ? (Random.Shared.Next(0, 10) < 5 ? "小音" : "米莉") : e.sender.title, string.Join("", e.message.Where(m => m.type == "text").Select(s => s.data.ToString())));
if (!AI.CD && (isAt || e.detail.StartsWith("小雪") || AI.List.Count > 4))
{
_ = Task.Run(async () =>
{
string reply = await AI.Chat();
await Bot.SendGroupMessage(e.group_id, "AI", reply);
});
}
}
}
}

View File

@ -18,16 +18,6 @@ try
Console.ForegroundColor = ConsoleColor.Gray;
}
if (args.Contains("--test"))
{
GeneralSettings.IsDebug = true;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Test模式");
Console.ForegroundColor = ConsoleColor.Gray;
Testing testing = new();
return;
}
if (args.Any(a => a.StartsWith("-g")))
{
string debug_group = args.Where(a => a.StartsWith("-g")).FirstOrDefault() ?? "";
@ -125,6 +115,16 @@ try
Console.WriteLine("初始化完毕!");
Console.ForegroundColor = ConsoleColor.Gray;
if (args.Contains("--test"))
{
GeneralSettings.IsDebug = true;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Test模式");
Console.ForegroundColor = ConsoleColor.Gray;
await AI.Chat();
return;
}
Console.WriteLine("开始监听 -> " + listener.address);
// 绑定监听事件
@ -210,6 +210,8 @@ try
GroupRecallTask.Recalls.Remove(recall);
}
}
// 重置AI状态
AI.CD = false;
}
catch (Exception e)
{

233
src/Settings/AI.cs Normal file
View File

@ -0,0 +1,233 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Milimoe.RainBOT.Settings
{
public class AI
{
public static bool CD { get; set; } = false;
public static HashSet<string> Context { get; set; } = [];
public static HashSet<string> List { get; set; } = [];
private static readonly string apiKey = GeneralSettings.AIAPIToken;
private static readonly string apiUrl = "https://api.deepseek.com/chat/completions";
private static readonly JsonSerializerOptions jsonOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
};
public static void Add(string user, string msg)
{
if (msg.Trim() == "") return;
if (List.Count < 10)
{
if (msg.Length > 35) msg = msg[..35];
List.Add($"{user}说: {msg}");
}
}
public static async Task<string> Chat()
{
CD = true;
using HttpClient httpClient = new();
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");
ChatRequest request = new()
{
Messages = [
new() { Role = "system", Content = @"你是用户的一个傲娇好友小雪,下面是你的设定:
//
××
绿
MAX却会给流浪猫带高级罐头
1怀
...
2
...线
...
3-
...
......
4
++
...
QQ群2CS2的群
80" }
],
MaxTokens = 140
};
if (Context.Count > 0) request.Messages.Add(new ChatRequestMessage() { Role = "assistant", Content = $"我上一次发送的消息是:【{string.Join(" && ", Context)}】。这是我本次回复可以参考的内容,我需要注意不能重复这些内容。" });
request.Messages.AddRange(List.Select(s => new ChatRequestMessage { Role = "user", Content = s }));
Console.WriteLine($"本次发送 AI 请求内容:{string.Join(". ", List)}");
if (Context.Count >= 2) Context.Remove(Context.First());
List.Clear();
try
{
if (request.Stream)
{
// todo
}
else
{
string jsonRequest = JsonSerializer.Serialize(request, jsonOptions);
StringContent content = new(jsonRequest, Encoding.UTF8, "application/json");
HttpResponseMessage response = await httpClient.PostAsync(apiUrl, content);
string jsonResponse = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
ChatCompletionResponse completionResponse = JsonSerializer.Deserialize<ChatCompletionResponse>(jsonResponse, jsonOptions) ?? new();
string reply = completionResponse?.Choices?[0].Message.Content ?? "";
Context.Add(reply);
Console.WriteLine($"Assistant: {reply}");
return reply;
}
else
{
Console.WriteLine($"请求失败,状态码:{response.StatusCode}");
Console.WriteLine($"响应内容:{jsonResponse}");
}
}
return "";
}
catch (Exception ex)
{
Console.WriteLine($"发生异常:{ex.Message}");
}
return "";
}
public static async Task<string> GetBalance()
{
// DeepSeek API 查询余额的 URL
string url = "https://api.deepseek.com/user/balance";
using HttpClient httpClient = new();
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");
try
{
HttpResponseMessage response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
BalanceResponse balanceResponse = JsonSerializer.Deserialize<BalanceResponse>(responseBody, jsonOptions) ?? new();
bool isAvailable = balanceResponse.IsAvailable;
List<string> strings = [];
List<BalanceInfo> balanceInfos = balanceResponse.BalanceInfos;
strings.Add($"账户是否有余额可用:{isAvailable}");
strings.Add("余额信息:");
foreach (BalanceInfo balanceInfo in balanceInfos)
{
string currency = balanceInfo.Currency;
string totalBalance = balanceInfo.TotalBalance;
string grantedBalance = balanceInfo.GrantedBalance;
string toppedUpBalance = balanceInfo.ToppedUpBalance;
strings.Add($"货币:{currency}");
strings.Add($"总可用余额:{totalBalance}");
strings.Add($"赠金余额:{grantedBalance}");
strings.Add($"充值余额:{toppedUpBalance}");
}
return string.Join("\r\n", strings);
}
catch (HttpRequestException ex)
{
Console.WriteLine($"HTTP 请求错误: {ex.Message}");
}
catch (JsonException ex)
{
Console.WriteLine($"JSON 解析错误: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"其他错误: {ex.Message}");
}
return "未查询到余额信息。";
}
}
public class ChatRequestMessage
{
public string Role { get; set; } = "";
public string Content { get; set; } = "";
}
public class ChatRequest
{
public string Model { get; set; } = "deepseek-chat";
public List<ChatRequestMessage> Messages { get; set; } = [];
public bool Stream { get; set; } = false;
public int MaxTokens { get; set; } = 50;
}
public class ChatCompletionResponse
{
public List<Choice> Choices { get; set; } = [];
}
public class Choice
{
public Message Message { get; set; } = new();
}
public class Message
{
public string Role { get; set; } = "";
public string Content { get; set; } = "";
}
public class BalanceInfo
{
[JsonPropertyName("currency")]
public string Currency { get; set; } = "";
[JsonPropertyName("total_balance")]
public string TotalBalance { get; set; } = "";
[JsonPropertyName("granted_balance")]
public string GrantedBalance { get; set; } = "";
[JsonPropertyName("topped_up_balance")]
public string ToppedUpBalance { get; set; } = "";
}
public class BalanceResponse
{
[JsonPropertyName("is_available")]
public bool IsAvailable { get; set; } = false;
[JsonPropertyName("balance_infos")]
public List<BalanceInfo> BalanceInfos { get; set; } = [];
}
}

View File

@ -35,6 +35,10 @@ namespace Milimoe.RainBOT.Settings
public static bool IsCallBrother { get; set; } = true;
public static long PCallBrother { get; set; } = 4;
public static bool IsAI { get; set; } = true;
public static long PAI { get; set; } = 100;
public static bool IsDebug { get; set; } = false;
@ -63,6 +67,8 @@ namespace Milimoe.RainBOT.Settings
public static string FunGameServer { get; set; } = "";
public static string FunGameToken { get; set; } = "";
public static string AIAPIToken { get; set; } = "";
public static PluginConfig Configs { get; set; } = new("rainbot", "config");
@ -134,6 +140,14 @@ namespace Milimoe.RainBOT.Settings
{
PCallBrother = (long)value;
}
if (configs.TryGetValue("IsAI", out value) && value != null)
{
IsAI = (bool)value;
}
if (configs.TryGetValue("PAI", out value) && value != null)
{
PAI = (long)value;
}
if (configs.TryGetValue("BlackTimes", out value) && value != null)
{
BlackTimes = (long)value;
@ -178,6 +192,10 @@ namespace Milimoe.RainBOT.Settings
{
FunGameToken = (string)value;
}
if (configs.TryGetValue("AIAPIToken", out value) && value != null)
{
AIAPIToken = (string)value;
}
}
public static void SaveConfig()
@ -197,6 +215,8 @@ namespace Milimoe.RainBOT.Settings
Configs.Add("PReverseAt", PReverseAt);
Configs.Add("IsCallBrother", IsCallBrother);
Configs.Add("PCallBrother", PCallBrother);
Configs.Add("IsAI", IsAI);
Configs.Add("PAI", PAI);
Configs.Add("BlackTimes", BlackTimes);
Configs.Add("BlackFrozenTime", BlackFrozenTime);
Configs.Add("MuteAccessGroup", MuteAccessGroup);
@ -208,6 +228,7 @@ namespace Milimoe.RainBOT.Settings
Configs.Add("FunGameWebSocketGroup", FunGameWebSocketGroup);
Configs.Add("FunGameServer", FunGameServer);
Configs.Add("FunGameToken", FunGameToken);
Configs.Add("AIAPIToken", AIAPIToken);
Configs.Save();
}

View File

@ -1,52 +0,0 @@
using Milimoe.OneBot.Framework.Utility;
using Milimoe.OneBot.Model.Event;
namespace Milimoe.RainBOT.Settings
{
public class Testing
{
public Testing()
{
GeneralSettings.LoadSetting();
QQOpenID.LoadConfig();
OshimaController.Config.FunGame_isAutoRetry = true;
Task r = Task.Run(async () =>
{
await OshimaController.Instance.Start();
await OshimaController.Instance.ConnectToAnonymousServer();
OshimaController.Config.FunGame_isAutoRetry = true;
string json = @"{""self_id"":928884953,""user_id"":3305106902,""time"":1737787658,""message_id"":212281255,""real_id"":212281255,""message_seq"":212281255,""message_type"":""group"",""sender"":{""user_id"":3305106902,""nickname"":""心音"",""card"":""高僧预测:"",""role"":""admin"",""title"":""注意素质""},""raw_message"":""签到"",""font"":14,""sub_type"":""normal"",""message"":[{""type"":""text"",""data"":{""text"":""签到""}}],""message_format"":""array"",""post_type"":""message"",""group_id"":667678970}";
try
{
GroupMessageEvent e = JsonTools.GetObject<GroupMessageEvent>(json) ?? new();
await RainBOTFunGame.Handler2(e);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
});
while (true)
{
if (Console.ReadLine() == "test")
{
string json = @"{""self_id"":928884953,""user_id"":3305106902,""time"":1737787658,""message_id"":212281255,""real_id"":212281255,""message_seq"":212281255,""message_type"":""group"",""sender"":{""user_id"":3305106902,""nickname"":""心音"",""card"":""高僧预测:"",""role"":""admin"",""title"":""注意素质""},""raw_message"":""签到"",""font"":14,""sub_type"":""normal"",""message"":[{""type"":""text"",""data"":{""text"":""签到""}}],""message_format"":""array"",""post_type"":""message"",""group_id"":667678970}";
try
{
GroupMessageEvent e = JsonTools.GetObject<GroupMessageEvent>(json) ?? new();
_ = RainBOTFunGame.Handler2(e);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
if (Console.ReadLine() == "quit")
break;
}
}
}
}