From 9824620be2be850b7ec2e225a3204d0408215e3a Mon Sep 17 00:00:00 2001 From: Wx-2025 <351320169@qq.com> Date: Sun, 7 Dec 2025 21:12:35 +0800 Subject: [PATCH] Update manager.js --- core/relationship-graph/manager.js | 165 +---------------------------- 1 file changed, 1 insertion(+), 164 deletions(-) diff --git a/core/relationship-graph/manager.js b/core/relationship-graph/manager.js index ee872f0..8f6c981 100644 --- a/core/relationship-graph/manager.js +++ b/core/relationship-graph/manager.js @@ -1,164 +1 @@ -import { getContext, extension_settings } from "/scripts/extensions.js"; -import { getCharacterStableId } from "../utils/context-utils.js"; -import { getMemoryState } from "../table-system/manager.js"; -import { extensionName } from "../../utils/settings.js"; - -const GRAPH_KEY = 'Amily2_Relationship_Graph'; - -let graphData = { - nodes: [], - edges: [] -}; - -export function getGraph() { - return graphData; -} - -export function clearGraph() { - graphData = { nodes: [], edges: [] }; - saveGraph(); -} - - -export function syncGraphFromTables() { - const tables = getMemoryState(); - if (!tables) return; - - const charTable = tables.find(t => t.name.includes('角色') || t.name === 'Character'); - if (!charTable) return; - - graphData = { nodes: [], edges: [] }; - - const context = getContext(); - const userName = context.name1 || '用户'; - addNode('user', userName, 'user'); - - const nameIdx = charTable.headers.findIndex(h => h.includes('角色名') || h.includes('Name')); - const relationIdx = charTable.headers.findIndex(h => h.includes('关系') || h.includes('Relation')); - const infoIdx = charTable.headers.findIndex(h => h.includes('重要信息') || h.includes('Info')); - - if (nameIdx === -1) return; - - charTable.rows.forEach(row => { - const name = row[nameIdx]; - if (!name) return; - - const metadata = {}; - if (infoIdx !== -1) metadata.info = row[infoIdx]; - addNode(name, name, 'character', metadata); - - if (relationIdx !== -1 && row[relationIdx]) { - const relation = row[relationIdx]; - addEdge(name, 'user', relation); - } - }); - - console.log(`[关系图谱] 已从表格同步 ${graphData.nodes.length} 个节点和 ${graphData.edges.length} 条边。`); - saveGraph(); -} - -export function addNode(id, label, type = 'entity', metadata = {}) { - const safeId = id.trim(); - if (!graphData.nodes.find(n => n.id === safeId)) { - graphData.nodes.push({ id: safeId, label, type, metadata }); - return true; - } - return false; -} - -export function addEdge(source, target, relation, weight = 1.0) { - const safeSource = source.trim(); - const safeTarget = target.trim(); - - const sourceNode = graphData.nodes.find(n => n.id === safeSource); - const targetNode = graphData.nodes.find(n => n.id === safeTarget); - - if (!sourceNode || !targetNode) { - return false; - } - - const existingEdge = graphData.edges.find(e => - e.source === safeSource && e.target === safeTarget && e.relation === relation - ); - - if (!existingEdge) { - graphData.edges.push({ source: safeSource, target: safeTarget, relation, weight }); - return true; - } - return false; -} - -export function getRelatedNodes(nodeId, maxDepth = 1) { - const related = []; - const queue = [{ id: nodeId, depth: 0 }]; - const visited = new Set([nodeId]); - - while (queue.length > 0) { - const { id, depth } = queue.shift(); - if (depth >= maxDepth) continue; - - const outgoing = graphData.edges.filter(e => e.source === id); - for (const edge of outgoing) { - if (!visited.has(edge.target)) { - visited.add(edge.target); - const node = graphData.nodes.find(n => n.id === edge.target); - if (node) { - related.push({ node, relation: edge.relation, direction: 'out', depth: depth + 1 }); - queue.push({ id: edge.target, depth: depth + 1 }); - } - } - } - - const incoming = graphData.edges.filter(e => e.target === id); - for (const edge of incoming) { - if (!visited.has(edge.source)) { - visited.add(edge.source); - const node = graphData.nodes.find(n => n.id === edge.source); - if (node) { - related.push({ node, relation: edge.relation, direction: 'in', depth: depth + 1 }); - queue.push({ id: edge.source, depth: depth + 1 }); - } - } - } - } - - return related; -} - -export async function saveGraph() { - const context = getContext(); - const charId = getCharacterStableId(); - if (!charId) return; - - if (!context.extensionSettings.relationship_graphs) { - context.extensionSettings.relationship_graphs = {}; - } - - context.extensionSettings.relationship_graphs[charId] = graphData; - context.saveSettingsDebounced(); -} - -export async function loadGraph() { - const context = getContext(); - const charId = getCharacterStableId(); - if (!charId) return; - - if (context.extensionSettings.relationship_graphs && context.extensionSettings.relationship_graphs[charId]) { - graphData = context.extensionSettings.relationship_graphs[charId]; - console.log(`[关系图谱] 已加载角色 ${charId} 的图谱: ${graphData.nodes.length} 个节点, ${graphData.edges.length} 条边。`); - } else { - graphData = { nodes: [], edges: [] }; - } -} - -const context = getContext(); -if (context) { - loadGraph(); - document.addEventListener('AMILY2_TABLE_UPDATED', (e) => { - const { tableName } = e.detail; - if (tableName.includes('角色') || tableName === 'Character') { - console.log('[关系图谱] 检测到角色表格更新,正在同步图谱...'); - syncGraphFromTables(); - } - }); -} +const _0x408395=_0x3853;(function(_0x348d4e,_0x1e6c1a){const _0x15b264=_0x3853,_0x2c51f8=_0x348d4e();while(!![]){try{const _0x5c3931=-parseInt(_0x15b264(0x17c))/0x1*(-parseInt(_0x15b264(0x15f))/0x2)+-parseInt(_0x15b264(0x17f))/0x3+-parseInt(_0x15b264(0x170))/0x4+parseInt(_0x15b264(0x17b))/0x5*(-parseInt(_0x15b264(0x176))/0x6)+parseInt(_0x15b264(0x164))/0x7+parseInt(_0x15b264(0x168))/0x8*(parseInt(_0x15b264(0x15e))/0x9)+parseInt(_0x15b264(0x15b))/0xa*(parseInt(_0x15b264(0x16e))/0xb);if(_0x5c3931===_0x1e6c1a)break;else _0x2c51f8['push'](_0x2c51f8['shift']());}catch(_0xd5852d){_0x2c51f8['push'](_0x2c51f8['shift']());}}}(_0x5c65,0x650a7));import{getContext,extension_settings}from'/scripts/extensions.js';import{getCharacterStableId}from'../utils/context-utils.js';function _0x3853(_0x535bed,_0x518503){_0x535bed=_0x535bed-0x14c;const _0x5c65aa=_0x5c65();let _0x3853c6=_0x5c65aa[_0x535bed];return _0x3853c6;}import{getMemoryState}from'../table-system/manager.js';import{extensionName}from'../../utils/settings.js';function _0x5c65(){const _0x366393=['[关系图谱]\x20已从表格同步\x20','source','extensionSettings','edges','name1','Relationship','53690saAZzM','relationship_graphs','filter','27lZCeAr','1061494CRwUJs','\x20条边。','find','findIndex','addEventListener','1530144IKgtxG','detail','info','Info','822576wGRJPx','\x20的图谱:\x20','entity','push','rows','length','99bwSoAx','\x20个节点和\x20','2108748fXZjfs','out','Amily2_Relationship_Graph','relation','headers','Relation','42VFtQbc','includes','test','user','Character','68375mxYXhi','1qGwFDD','add','trim','208053ZVXzIk','重要信息','log','Name','saveSettingsDebounced','nodes','name','has','target','[关系图谱]\x20检测到相关表格更新,正在同步图谱...'];_0x5c65=function(){return _0x366393;};return _0x5c65();}const GRAPH_KEY=_0x408395(0x172);let graphData={'nodes':[],'edges':[]};export function getGraph(){return graphData;}export function clearGraph(){graphData={'nodes':[],'edges':[]},saveGraph();}export function syncGraphFromTables(){const _0x19b90f=_0x408395,_0x1ddac4=getMemoryState();if(!_0x1ddac4)return;graphData={'nodes':[],'edges':[]};const _0x5382f3=getContext(),_0x19e86c=_0x5382f3[_0x19b90f(0x159)]||'用户';addNode(_0x19b90f(0x179),_0x19e86c,_0x19b90f(0x179));const _0x4ffc75=_0x1ddac4[_0x19b90f(0x161)](_0x5ab32c=>_0x5ab32c[_0x19b90f(0x151)][_0x19b90f(0x177)]('角色')||_0x5ab32c[_0x19b90f(0x151)]==='Character');if(_0x4ffc75){const _0x4519a7=_0x4ffc75['headers'][_0x19b90f(0x162)](_0x5c0440=>_0x5c0440[_0x19b90f(0x177)]('角色名')||_0x5c0440[_0x19b90f(0x177)](_0x19b90f(0x14e))),_0x5a1fef=_0x4ffc75['headers'][_0x19b90f(0x162)](_0x431eb0=>_0x431eb0['includes']('关系')||_0x431eb0[_0x19b90f(0x177)](_0x19b90f(0x175))),_0x2ef242=_0x4ffc75['headers'][_0x19b90f(0x162)](_0x3a0ae4=>_0x3a0ae4[_0x19b90f(0x177)](_0x19b90f(0x14c))||_0x3a0ae4[_0x19b90f(0x177)](_0x19b90f(0x167))),_0x40758b=_0x4ffc75[_0x19b90f(0x174)][_0x19b90f(0x162)](_0x1f658e=>/(对象|指向|Target|To|Object)/i['test'](_0x1f658e));_0x4519a7!==-0x1&&_0x4ffc75['rows']['forEach'](_0x3a8683=>{const _0x3b4990=_0x19b90f,_0xbe0b36=_0x3a8683[_0x4519a7];if(!_0xbe0b36)return;const _0x1332b3={};if(_0x2ef242!==-0x1)_0x1332b3[_0x3b4990(0x166)]=_0x3a8683[_0x2ef242];addNode(_0xbe0b36,_0xbe0b36,'character',_0x1332b3);if(_0x5a1fef!==-0x1&&_0x3a8683[_0x5a1fef]){const _0x206ce7=_0x3a8683[_0x5a1fef];let _0x23ca1a=_0x3b4990(0x179);_0x40758b!==-0x1&&_0x3a8683[_0x40758b]&&(_0x23ca1a=_0x3a8683[_0x40758b][_0x3b4990(0x17e)](),addNode(_0x23ca1a,_0x23ca1a,_0x23ca1a===_0x3b4990(0x179)||_0x23ca1a===_0x19e86c?_0x3b4990(0x179):'entity')),addEdge(_0xbe0b36,_0x23ca1a,_0x206ce7);}});}const _0x29b5a3=_0x1ddac4['find'](_0x3ce2a6=>_0x3ce2a6[_0x19b90f(0x151)][_0x19b90f(0x177)]('关系')||_0x3ce2a6['name']===_0x19b90f(0x15a));if(_0x29b5a3){const _0x11bcb6=_0x29b5a3[_0x19b90f(0x174)][_0x19b90f(0x162)](_0x38295c=>/(主动方|Source|Subject|From)/i[_0x19b90f(0x178)](_0x38295c)),_0x5952c0=_0x29b5a3[_0x19b90f(0x174)][_0x19b90f(0x162)](_0x16d459=>/(被动方|对象|Target|Object|To)/i[_0x19b90f(0x178)](_0x16d459)),_0x267c19=_0x29b5a3['headers']['findIndex'](_0x33b690=>/(关系|Relation)/i[_0x19b90f(0x178)](_0x33b690)),_0xc838d9=_0x29b5a3[_0x19b90f(0x174)]['findIndex'](_0x4f3b25=>/(详情|Detail|Info)/i['test'](_0x4f3b25));_0x11bcb6!==-0x1&&_0x5952c0!==-0x1&&_0x267c19!==-0x1&&_0x29b5a3[_0x19b90f(0x16c)]['forEach'](_0x23784e=>{const _0x53a66e=_0x19b90f,_0x4d7b94=_0x23784e[_0x11bcb6],_0x31e78d=_0x23784e[_0x5952c0],_0x237735=_0x23784e[_0x267c19];if(!_0x4d7b94||!_0x31e78d||!_0x237735)return;addNode(_0x4d7b94,_0x4d7b94,_0x4d7b94===_0x19e86c?_0x53a66e(0x179):'entity'),addNode(_0x31e78d,_0x31e78d,_0x31e78d===_0x19e86c?_0x53a66e(0x179):_0x53a66e(0x16a)),addEdge(_0x4d7b94,_0x31e78d,_0x237735);});}console[_0x19b90f(0x14d)](_0x19b90f(0x155)+graphData[_0x19b90f(0x150)]['length']+_0x19b90f(0x16f)+graphData[_0x19b90f(0x158)][_0x19b90f(0x16d)]+_0x19b90f(0x160)),saveGraph();}export function addNode(_0x3b49a3,_0x16d32c,_0x1191fb=_0x408395(0x16a),_0x315878={}){const _0x246240=_0x408395,_0x3789fe=_0x3b49a3['trim']();if(!graphData['nodes'][_0x246240(0x161)](_0x36f5b4=>_0x36f5b4['id']===_0x3789fe))return graphData[_0x246240(0x150)][_0x246240(0x16b)]({'id':_0x3789fe,'label':_0x16d32c,'type':_0x1191fb,'metadata':_0x315878}),!![];return![];}export function addEdge(_0x3f8ea4,_0x4110a1,_0x3499fd,_0x6c66b2=0x1){const _0x55e9be=_0x408395,_0x32b6a7=_0x3f8ea4[_0x55e9be(0x17e)](),_0x1ce544=_0x4110a1['trim'](),_0x31e8ad=graphData[_0x55e9be(0x150)]['find'](_0x2308e1=>_0x2308e1['id']===_0x32b6a7),_0x58df64=graphData[_0x55e9be(0x150)][_0x55e9be(0x161)](_0x5bd4a5=>_0x5bd4a5['id']===_0x1ce544);if(!_0x31e8ad||!_0x58df64)return![];const _0x190401=graphData[_0x55e9be(0x158)][_0x55e9be(0x161)](_0xf0c7d1=>_0xf0c7d1[_0x55e9be(0x156)]===_0x32b6a7&&_0xf0c7d1['target']===_0x1ce544&&_0xf0c7d1[_0x55e9be(0x173)]===_0x3499fd);if(!_0x190401)return graphData[_0x55e9be(0x158)][_0x55e9be(0x16b)]({'source':_0x32b6a7,'target':_0x1ce544,'relation':_0x3499fd,'weight':_0x6c66b2}),!![];return![];}export function getRelatedNodes(_0x5335fa,_0x6750d6=0x1){const _0x5ada3e=_0x408395,_0x268288=[],_0x2a1e41=[{'id':_0x5335fa,'depth':0x0}],_0x2661ca=new Set([_0x5335fa]);while(_0x2a1e41[_0x5ada3e(0x16d)]>0x0){const {id:_0x3b7013,depth:_0x30e0f8}=_0x2a1e41['shift']();if(_0x30e0f8>=_0x6750d6)continue;const _0x382838=graphData['edges'][_0x5ada3e(0x15d)](_0x41a618=>_0x41a618[_0x5ada3e(0x156)]===_0x3b7013);for(const _0x22be89 of _0x382838){if(!_0x2661ca[_0x5ada3e(0x152)](_0x22be89[_0x5ada3e(0x153)])){_0x2661ca['add'](_0x22be89[_0x5ada3e(0x153)]);const _0x357470=graphData[_0x5ada3e(0x150)][_0x5ada3e(0x161)](_0x24ad26=>_0x24ad26['id']===_0x22be89['target']);_0x357470&&(_0x268288[_0x5ada3e(0x16b)]({'node':_0x357470,'relation':_0x22be89[_0x5ada3e(0x173)],'direction':_0x5ada3e(0x171),'depth':_0x30e0f8+0x1}),_0x2a1e41[_0x5ada3e(0x16b)]({'id':_0x22be89[_0x5ada3e(0x153)],'depth':_0x30e0f8+0x1}));}}const _0x447720=graphData[_0x5ada3e(0x158)]['filter'](_0x403c4e=>_0x403c4e[_0x5ada3e(0x153)]===_0x3b7013);for(const _0x3e7b7e of _0x447720){if(!_0x2661ca[_0x5ada3e(0x152)](_0x3e7b7e['source'])){_0x2661ca[_0x5ada3e(0x17d)](_0x3e7b7e[_0x5ada3e(0x156)]);const _0x3d60ba=graphData['nodes'][_0x5ada3e(0x161)](_0x13bacf=>_0x13bacf['id']===_0x3e7b7e['source']);_0x3d60ba&&(_0x268288['push']({'node':_0x3d60ba,'relation':_0x3e7b7e[_0x5ada3e(0x173)],'direction':'in','depth':_0x30e0f8+0x1}),_0x2a1e41['push']({'id':_0x3e7b7e['source'],'depth':_0x30e0f8+0x1}));}}}return _0x268288;}export async function saveGraph(){const _0x1641ae=_0x408395,_0x3d7410=getContext(),_0x1158fc=getCharacterStableId();if(!_0x1158fc)return;!_0x3d7410['extensionSettings'][_0x1641ae(0x15c)]&&(_0x3d7410[_0x1641ae(0x157)]['relationship_graphs']={}),_0x3d7410[_0x1641ae(0x157)][_0x1641ae(0x15c)][_0x1158fc]=graphData,_0x3d7410[_0x1641ae(0x14f)]();}export async function loadGraph(){const _0x4303df=_0x408395,_0x1262c3=getContext(),_0x5ad913=getCharacterStableId();if(!_0x5ad913)return;_0x1262c3[_0x4303df(0x157)][_0x4303df(0x15c)]&&_0x1262c3[_0x4303df(0x157)][_0x4303df(0x15c)][_0x5ad913]?(graphData=_0x1262c3[_0x4303df(0x157)][_0x4303df(0x15c)][_0x5ad913],console[_0x4303df(0x14d)]('[关系图谱]\x20已加载角色\x20'+_0x5ad913+_0x4303df(0x169)+graphData[_0x4303df(0x150)]['length']+'\x20个节点,\x20'+graphData[_0x4303df(0x158)][_0x4303df(0x16d)]+_0x4303df(0x160))):graphData={'nodes':[],'edges':[]};}const context=getContext();context&&(loadGraph(),document[_0x408395(0x163)]('AMILY2_TABLE_UPDATED',_0x21330b=>{const _0x451019=_0x408395,{tableName:_0x3766d1}=_0x21330b[_0x451019(0x165)];(_0x3766d1['includes']('角色')||_0x3766d1===_0x451019(0x17a)||_0x3766d1[_0x451019(0x177)]('关系')||_0x3766d1==='Relationship')&&(console[_0x451019(0x14d)](_0x451019(0x154)),syncGraphFromTables());}));