mirror of
https://github.com/SilenceLurker/ST-Amily2-Chat-Optimisation.git
synced 2026-06-06 15:55:50 +00:00
Update tavernhelper-compatibility.js
This commit is contained in:
@@ -1,199 +1,69 @@
|
||||
import { loadWorldInfo, createNewWorldInfo, saveWorldInfo, world_names, createWorldInfoEntry } from "/scripts/world-info.js";
|
||||
import { characters, eventSource, event_types } from "/script.js";
|
||||
import { getContext } from "/scripts/extensions.js";
|
||||
|
||||
import { amilyHelper } from './tavern-helper/main.js';
|
||||
import { eventSource, event_types } from "/script.js";
|
||||
|
||||
// 我们现在总是“可用”的,因为我们依赖自己的实现,而不是那个屎山酒馆。
|
||||
export function isTavernHelperAvailable() {
|
||||
return typeof window.TavernHelper !== 'undefined' &&
|
||||
window.TavernHelper !== null &&
|
||||
typeof window.TavernHelper.getLorebooks === 'function';
|
||||
return true;
|
||||
}
|
||||
export async function compatibleTriggerSlash(command) {
|
||||
return await amilyHelper.triggerSlash(command);
|
||||
}
|
||||
|
||||
|
||||
export async function safeLorebooks() {
|
||||
try {
|
||||
if (isTavernHelperAvailable()) {
|
||||
return await window.TavernHelper.getLorebooks();
|
||||
}
|
||||
return [...world_names];
|
||||
} catch (error) {
|
||||
console.error('[Amily2-兼容性] 获取世界书列表失败:', error);
|
||||
return [...world_names];
|
||||
}
|
||||
return amilyHelper.getLorebooks();
|
||||
}
|
||||
|
||||
|
||||
export async function safeCharLorebooks(options = { type: 'all' }) {
|
||||
try {
|
||||
if (isTavernHelperAvailable()) {
|
||||
return await window.TavernHelper.getCharLorebooks(options);
|
||||
}
|
||||
const context = getContext();
|
||||
const character = characters[context.characterId];
|
||||
const primary = character?.data?.extensions?.world;
|
||||
return { primary: primary || null, additional: [] };
|
||||
} catch (error) {
|
||||
console.error('[Amily2-兼容性] 获取角色世界书失败:', error);
|
||||
const context = getContext();
|
||||
const character = characters[context.characterId];
|
||||
const primary = character?.data?.extensions?.world;
|
||||
return { primary: primary || null, additional: [] };
|
||||
}
|
||||
return amilyHelper.getCharLorebooks(options);
|
||||
}
|
||||
|
||||
export async function safeLorebookEntries(bookName) {
|
||||
try {
|
||||
if (isTavernHelperAvailable()) {
|
||||
return await window.TavernHelper.getLorebookEntries(bookName);
|
||||
}
|
||||
const bookData = await loadWorldInfo(bookName);
|
||||
if (!bookData || !bookData.entries) return [];
|
||||
return Object.entries(bookData.entries).map(([uid, entry]) => ({
|
||||
uid: parseInt(uid),
|
||||
comment: entry.comment || '无标题条目',
|
||||
content: entry.content || '',
|
||||
key: entry.key || [],
|
||||
enabled: !entry.disable,
|
||||
constant: entry.constant || false,
|
||||
position: entry.position || 4,
|
||||
depth: entry.depth || 998,
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error(`[Amily2-兼容性] 获取世界书 ${bookName} 条目失败:`, error);
|
||||
return [];
|
||||
}
|
||||
return amilyHelper.getLorebookEntries(bookName);
|
||||
}
|
||||
|
||||
|
||||
export async function safeUpdateLorebookEntries(bookName, entries) {
|
||||
try {
|
||||
if (isTavernHelperAvailable()) {
|
||||
await window.TavernHelper.setLorebookEntries(bookName, entries);
|
||||
return true;
|
||||
}
|
||||
|
||||
const bookData = await loadWorldInfo(bookName);
|
||||
if (!bookData) return false;
|
||||
for (const entryUpdate of entries) {
|
||||
const existingEntry = bookData.entries[entryUpdate.uid];
|
||||
if (existingEntry) {
|
||||
if (entryUpdate.content !== undefined) existingEntry.content = entryUpdate.content;
|
||||
if (entryUpdate.enabled !== undefined) existingEntry.disable = !entryUpdate.enabled;
|
||||
}
|
||||
}
|
||||
await saveWorldInfo(bookName, bookData, true);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(`[Amily2-兼容性] 更新世界书条目失败:`, error);
|
||||
return false;
|
||||
}
|
||||
return amilyHelper.setLorebookEntries(bookName, entries);
|
||||
}
|
||||
|
||||
|
||||
export async function compatibleWriteToLorebook(targetLorebookName, entryComment, contentUpdateCallback, options = {}) {
|
||||
console.log('[Amily2-兼容性] compatibleWriteToLorebook 接收到的选项:', options);
|
||||
console.log('[Amily助手-写入模块] 接收到的写入选项:', options);
|
||||
|
||||
if (isTavernHelperAvailable()) {
|
||||
try {
|
||||
if (!world_names.includes(targetLorebookName)) {
|
||||
await createNewWorldInfo(targetLorebookName);
|
||||
if (Array.isArray(world_names) && !world_names.includes(targetLorebookName)) {
|
||||
world_names.push(targetLorebookName);
|
||||
world_names.sort();
|
||||
}
|
||||
if (eventSource && typeof eventSource.emit === "function" && event_types.CHARACTER_PAGE_LOADED) {
|
||||
eventSource.emit(event_types.CHARACTER_PAGE_LOADED);
|
||||
}
|
||||
console.log(`[Amily2-兼容性] (混合模式) 已创建新世界书: ${targetLorebookName}`);
|
||||
}
|
||||
try {
|
||||
const entries = await amilyHelper.getLorebookEntries(targetLorebookName);
|
||||
const existingEntry = entries.find((e) => e.comment === entryComment && e.enabled);
|
||||
|
||||
const entries = await safeLorebookEntries(targetLorebookName);
|
||||
const existingEntry = entries.find((e) => e.comment === entryComment && !e.disable);
|
||||
if (existingEntry) {
|
||||
const newContent = contentUpdateCallback(existingEntry.content);
|
||||
await amilyHelper.setLorebookEntries(targetLorebookName, [{ uid: existingEntry.uid, content: newContent }]);
|
||||
} else {
|
||||
const newContent = contentUpdateCallback(null);
|
||||
const { keys = [], isConstant = false, insertion_position, depth: insertion_depth } = options;
|
||||
|
||||
const positionMap = { 'before_char': 0, 'after_char': 1, 'before_an': 2, 'after_an': 3, 'at_depth': 4 };
|
||||
|
||||
const newEntryData = {
|
||||
comment: entryComment,
|
||||
content: newContent,
|
||||
key: keys,
|
||||
constant: isConstant,
|
||||
position: positionMap[insertion_position] ?? 4,
|
||||
depth: parseInt(insertion_depth) || 998,
|
||||
enabled: true,
|
||||
};
|
||||
|
||||
if (existingEntry) {
|
||||
const newContent = contentUpdateCallback(existingEntry.content);
|
||||
await safeUpdateLorebookEntries(targetLorebookName, [{ uid: existingEntry.uid, content: newContent }]);
|
||||
} else {
|
||||
const newContent = contentUpdateCallback(null);
|
||||
const { keys = [], isConstant = false, insertion_position, depth: insertion_depth } = options;
|
||||
const positionMap = { 'before_char': 0, 'after_char': 1, 'before_an': 2, 'after_an': 3, 'at_depth': 4 };
|
||||
|
||||
const newEntryData = {
|
||||
comment: entryComment, content: newContent, key: keys,
|
||||
constant: isConstant, position: positionMap[insertion_position] ?? 4,
|
||||
depth: parseInt(insertion_depth) || 998, enabled: true,
|
||||
};
|
||||
|
||||
await window.TavernHelper.createLorebookEntries(targetLorebookName, [newEntryData]);
|
||||
|
||||
const bookData = await loadWorldInfo(targetLorebookName);
|
||||
const createdEntry = Object.values(bookData.entries).find(e => e.comment === entryComment);
|
||||
if (createdEntry) {
|
||||
createdEntry.constant = isConstant;
|
||||
createdEntry.position = positionMap[insertion_position] ?? 4;
|
||||
createdEntry.depth = parseInt(insertion_depth) || 998;
|
||||
await saveWorldInfo(targetLorebookName, bookData, true);
|
||||
console.log(`[Amily2-兼容性] (混合模式) 已修正条目激活状态、位置和深度。`);
|
||||
}
|
||||
}
|
||||
console.log(`[Amily2-兼容性] (混合模式) 成功写入条目 "${entryComment}"。`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(`[Amily2-兼容性] (混合模式) 写入失败:`, error);
|
||||
toastr.error(`写入世界书失败: ${error.message}`, "Amily2号-兼容性模块");
|
||||
return false;
|
||||
await amilyHelper.createLorebookEntries(targetLorebookName, [newEntryData]);
|
||||
}
|
||||
} else {
|
||||
console.warn('[Amily2-兼容性] TavernHelper 不可用,回退到传统写入逻辑。');
|
||||
try {
|
||||
if (!world_names.includes(targetLorebookName)) {
|
||||
await createNewWorldInfo(targetLorebookName);
|
||||
console.log(`[Amily2-兼容性] (传统模式) 已创建新世界书: ${targetLorebookName}`);
|
||||
}
|
||||
|
||||
const bookData = await loadWorldInfo(targetLorebookName);
|
||||
if (!bookData) throw new Error(`无法加载世界书《${targetLorebookName}》`);
|
||||
|
||||
const existingEntry = Object.values(bookData.entries).find(e => e.comment === entryComment && !e.disable);
|
||||
|
||||
if (existingEntry) {
|
||||
existingEntry.content = contentUpdateCallback(existingEntry.content);
|
||||
} else {
|
||||
const newContent = contentUpdateCallback(null);
|
||||
const { keys = [], isConstant = false, insertion_position, depth: insertion_depth } = options;
|
||||
const positionMap = { 'before_char': 0, 'after_char': 1, 'before_an': 2, 'after_an': 3, 'at_depth': 4 };
|
||||
|
||||
const newEntry = createWorldInfoEntry(targetLorebookName, bookData);
|
||||
Object.assign(newEntry, {
|
||||
comment: entryComment, content: newContent, key: keys,
|
||||
constant: isConstant, position: positionMap[insertion_position] ?? 4,
|
||||
depth: parseInt(insertion_depth) || 998, disable: false,
|
||||
});
|
||||
}
|
||||
|
||||
await saveWorldInfo(targetLorebookName, bookData, true);
|
||||
console.log(`[Amily2-兼容性] (传统模式) 成功写入条目 "${entryComment}"。`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(`[Amily2-兼容性] (传统模式) 写入失败:`, error);
|
||||
toastr.error(`传统模式写入世界书失败: ${error.message}`, "Amily2号-兼容性模块");
|
||||
return false;
|
||||
if (eventSource && typeof eventSource.emit === "function" && event_types.CHARACTER_PAGE_LOADED) {
|
||||
eventSource.emit(event_types.CHARACTER_PAGE_LOADED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function safeTriggerSlash(command) {
|
||||
if (isTavernHelperAvailable() && typeof window.TavernHelper.triggerSlash === 'function') {
|
||||
try {
|
||||
return await window.TavernHelper.triggerSlash(command);
|
||||
} catch (error) {
|
||||
console.error(`[Amily2-兼容性] TavernHelper.triggerSlash 执行失败:`, error);
|
||||
throw error;
|
||||
}
|
||||
} else {
|
||||
const errorMsg = 'TavernHelper 或 triggerSlash 方法不可用';
|
||||
console.error(`[Amily2-兼容性] ${errorMsg}`);
|
||||
throw new Error(errorMsg);
|
||||
|
||||
console.log(`[Amily助手] 成功将条目 "${entryComment}" 写入《${targetLorebookName}》。`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(`[Amily助手] 写入世界书时发生严重错误:`, error);
|
||||
toastr.error(`写入世界书失败: ${error.message}`, "Amily助手");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user