第58批:AI聊天@前缀支持+信誉积分优化
- AIChatManager: 支持单@前缀(@厂家名/内容),不再只检测@// - AIChatManager: 自动互动提示词改为引导性话题,不点名玩家 - CreditManager: /credits <玩家名> 直接查积分,无需user关键字 - admin.php: 信誉积分卡片统一使用CSS变量,与后台风格一致
This commit is contained in:
@@ -677,8 +677,8 @@ public class AIChatManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理玩家聊天消息
|
* 处理玩家聊天消息
|
||||||
* 检测 @//模型名/ 或 @//厂家名/ 前缀触发直接提问
|
* 检测 @厂家名/内容 或 @//厂家名/内容 前缀触发直接提问
|
||||||
* 格式: @//模型名/内容 或 @//模型名 (不带内容时用默认提示)
|
* 格式: @厂家名/内容 或 @//厂家名/内容 或 @厂家名 或 @//厂家名
|
||||||
*/
|
*/
|
||||||
public void handlePlayerChat(Player p, String message) {
|
public void handlePlayerChat(Player p, String message) {
|
||||||
// 记录到聊天缓冲区
|
// 记录到聊天缓冲区
|
||||||
@@ -688,22 +688,42 @@ public class AIChatManager {
|
|||||||
recentChatBuffer.remove(0);
|
recentChatBuffer.remove(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检测 @//模型名/ 前缀
|
// 检测 @// 或 @ 前缀(支持单 @ 和双 @//)
|
||||||
|
String prefix = "";
|
||||||
|
int prefixLen = 0;
|
||||||
if (message.startsWith("@//")) {
|
if (message.startsWith("@//")) {
|
||||||
// 格式: @//模型名/内容 或 @//模型名 (尾部无斜杠)
|
prefix = "@//";
|
||||||
int slashIdx = message.indexOf('/', 3);
|
prefixLen = 3;
|
||||||
|
} else if (message.startsWith("@")) {
|
||||||
|
prefix = "@";
|
||||||
|
prefixLen = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!prefix.isEmpty()) {
|
||||||
|
// 去掉前缀后查找第一个斜杠或空格
|
||||||
|
String afterPrefix = message.substring(prefixLen);
|
||||||
|
int slashIdx = afterPrefix.indexOf('/');
|
||||||
|
int spaceIdx = afterPrefix.indexOf(' ');
|
||||||
|
|
||||||
String modelAlias;
|
String modelAlias;
|
||||||
String prompt;
|
String prompt;
|
||||||
|
|
||||||
if (slashIdx > 0) {
|
if (slashIdx > 0) {
|
||||||
modelAlias = message.substring(3, slashIdx);
|
// 格式: @厂家名/内容
|
||||||
prompt = message.substring(slashIdx + 1).trim();
|
modelAlias = afterPrefix.substring(0, slashIdx).trim();
|
||||||
|
prompt = afterPrefix.substring(slashIdx + 1).trim();
|
||||||
|
} else if (spaceIdx > 0) {
|
||||||
|
// 格式: @厂家名 内容(空格分隔)
|
||||||
|
modelAlias = afterPrefix.substring(0, spaceIdx).trim();
|
||||||
|
prompt = afterPrefix.substring(spaceIdx + 1).trim();
|
||||||
} else {
|
} else {
|
||||||
// 尾部无斜杠:整段去掉 @// 前缀作为模型名
|
// 格式: @厂家名(无内容)
|
||||||
modelAlias = message.substring(3).trim();
|
modelAlias = afterPrefix.trim();
|
||||||
prompt = "";
|
prompt = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modelAlias.isEmpty()) {
|
if (modelAlias.isEmpty()) {
|
||||||
p.sendMessage("§c[AI聊天] §f格式错误,应为 @//模型名/内容");
|
p.sendMessage("§c[AI聊天] §f格式错误,应为 @厂家名/内容");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (prompt.isEmpty()) {
|
if (prompt.isEmpty()) {
|
||||||
@@ -772,7 +792,7 @@ public class AIChatManager {
|
|||||||
|
|
||||||
// 构建自动互动提示词 — 用压缩方法(超阈值时截断旧消息)
|
// 构建自动互动提示词 — 用压缩方法(超阈值时截断旧消息)
|
||||||
String recentChat = compressChatBuffer(endpoint.maxToken);
|
String recentChat = compressChatBuffer(endpoint.maxToken);
|
||||||
String prompt = "以下是服务器最近的聊天记录:\n" + recentChat + "\n\n请根据聊天内容,自然地参与对话或回答问题。";
|
String prompt = "以下是服务器最近的聊天记录:\n" + recentChat + "\n\n请根据聊天内容,自然地抛出一个话题或问题,引导大家参与讨论,带动服务器的活跃气氛。不要直接点名任何玩家,而是抛出一个开放性的话题让大家都能参与。";
|
||||||
|
|
||||||
plugin.getLogger().info("[AI聊天] 触发自动互动");
|
plugin.getLogger().info("[AI聊天] 触发自动互动");
|
||||||
// ★ 死循环防护:触发前先更新时间戳,请求挂起/超时/失败都不会被下一秒重复触发
|
// ★ 死循环防护:触发前先更新时间戳,请求挂起/超时/失败都不会被下一秒重复触发
|
||||||
|
|||||||
@@ -564,18 +564,38 @@ public class CreditManager {
|
|||||||
if (sender instanceof Player) {
|
if (sender instanceof Player) {
|
||||||
((Player) sender).openInventory(createMainGUI((Player) sender));
|
((Player) sender).openInventory(createMainGUI((Player) sender));
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage("§c用法: /credits [user <玩家名>]");
|
sender.sendMessage("§c用法: /credits [玩家名|审批|approve]");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String sub = args[0].toLowerCase();
|
String sub = args[0].toLowerCase();
|
||||||
|
|
||||||
|
// ★ 快捷查积分:/credits <玩家名> 直接查,无需 user 关键字
|
||||||
|
// 判断第一个参数是否是已知子命令
|
||||||
|
boolean isSubCommand = sub.equals("user") || sub.equals("审批") || sub.equals("approve");
|
||||||
|
if (!isSubCommand && args.length >= 1) {
|
||||||
|
// 直接是玩家名 → 查询积分
|
||||||
|
String targetName = args[0];
|
||||||
|
int targetScore = getScore(targetName);
|
||||||
|
sender.sendMessage("§d§l[信誉积分] §f" + targetName + " §7的当前积分: §e" + targetScore
|
||||||
|
+ " §7(初始: " + DEFAULT_INIT_SCORE + ")");
|
||||||
|
// 判断是否触发限制
|
||||||
|
for (Map<String, Object> rule : getEnabledRules()) {
|
||||||
|
int minScore = ((Number) rule.get("min_score")).intValue();
|
||||||
|
if (targetScore < minScore) {
|
||||||
|
String desc = (String) rule.get("description");
|
||||||
|
sender.sendMessage("§c§l[信誉积分] §f" + targetName + " §7已触发限制: §c" + desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
switch (sub) {
|
switch (sub) {
|
||||||
case "user":
|
case "user":
|
||||||
// /credits user <玩家名> — 任何人可查他人积分
|
// /credits user <玩家名> — 兼容旧格式
|
||||||
if (args.length < 2) {
|
if (args.length < 2) {
|
||||||
sender.sendMessage("§c用法: /credits user <玩家名>");
|
sender.sendMessage("§c用法: /credits user <玩家名> 或直接 /credits <玩家名>");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
String targetName = args[1];
|
String targetName = args[1];
|
||||||
@@ -660,7 +680,7 @@ public class CreditManager {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
sender.sendMessage("§c未知子命令: " + sub);
|
sender.sendMessage("§c未知子命令: " + sub);
|
||||||
sender.sendMessage("§7用法: /credits [user <玩家名>]");
|
sender.sendMessage("§7用法: /credits [玩家名|审批|approve]");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user