diff --git a/CharacterWorldBook/src/cwb_utils.js b/CharacterWorldBook/src/cwb_utils.js index 000f895..690796e 100644 --- a/CharacterWorldBook/src/cwb_utils.js +++ b/CharacterWorldBook/src/cwb_utils.js @@ -1 +1,166 @@ -const _0x38c295=_0x4996;(function(_0x2379d5,_0x3b247a){const _0x3ffd16=_0x4996,_0x1451c5=_0x2379d5();while(!![]){try{const _0x3e8606=parseInt(_0x3ffd16(0x141))/0x1*(parseInt(_0x3ffd16(0x131))/0x2)+-parseInt(_0x3ffd16(0x151))/0x3*(parseInt(_0x3ffd16(0x143))/0x4)+parseInt(_0x3ffd16(0x138))/0x5+parseInt(_0x3ffd16(0x142))/0x6+parseInt(_0x3ffd16(0x136))/0x7+parseInt(_0x3ffd16(0x146))/0x8*(parseInt(_0x3ffd16(0x133))/0x9)+parseInt(_0x3ffd16(0x158))/0xa*(-parseInt(_0x3ffd16(0x140))/0xb);if(_0x3e8606===_0x3b247a)break;else _0x1451c5['push'](_0x1451c5['shift']());}catch(_0x1b32fd){_0x1451c5['push'](_0x1451c5['shift']());}}}(_0x1549,0x22a34));function _0x4996(_0xd6cad5,_0x535f66){const _0x15498d=_0x1549();return _0x4996=function(_0x4996a1,_0x4d2986){_0x4996a1=_0x4996a1-0x12f;let _0x2a8a22=_0x15498d[_0x4996a1];return _0x2a8a22;},_0x4996(_0xd6cad5,_0x535f66);}const DEBUG_MODE=!![],SCRIPT_ID_PREFIX=_0x38c295(0x148);export function logDebug(..._0x195e75){const _0x78f1c2=_0x38c295;DEBUG_MODE&&console[_0x78f1c2(0x149)]('['+SCRIPT_ID_PREFIX+']',..._0x195e75);}export function logError(..._0xa9201a){console['error']('['+SCRIPT_ID_PREFIX+']',..._0xa9201a);}export function isCwbEnabled(){const _0x5d1fc6=_0x38c295;try{const _0x1adfe7=JSON[_0x5d1fc6(0x14f)](localStorage[_0x5d1fc6(0x159)](_0x5d1fc6(0x13d))||'{}');if(_0x1adfe7[_0x5d1fc6(0x155)]!==undefined)return _0x1adfe7[_0x5d1fc6(0x155)]===!![];const _0x58cc23=localStorage[_0x5d1fc6(0x159)](_0x5d1fc6(0x14b));if(_0x58cc23){const _0x4a7ebc=JSON[_0x5d1fc6(0x14f)](_0x58cc23);if(_0x4a7ebc?.[_0x5d1fc6(0x155)]!==undefined)return _0x4a7ebc[_0x5d1fc6(0x155)]===!![];}return!![];}catch(_0x4313de){return console[_0x5d1fc6(0x134)](_0x5d1fc6(0x13a),_0x4313de),!![];}}export function checkCwbEnabled(_0xf3ff4a='操作'){const _0x2b1478=_0x38c295;if(!isCwbEnabled())return console[_0x2b1478(0x149)]('['+SCRIPT_ID_PREFIX+']\x20'+_0xf3ff4a+'被跳过\x20-\x20CharacterWorldBook总开关已关闭'),![];return!![];}export function showToastr(_0x2ab4ee,_0x5849b6,_0x663368={}){const _0x39b1a9=_0x38c295;if(!isCwbEnabled())return;window[_0x39b1a9(0x14c)]?(window[_0x39b1a9(0x14c)]['clear'](),window['toastr'][_0x2ab4ee](_0x5849b6,_0x39b1a9(0x137),_0x663368)):logDebug(_0x39b1a9(0x15a)+_0x2ab4ee+'):\x20'+_0x5849b6);}function _0x1549(){const _0x556ba4=['cwb_boolean_settings_override','max','test','5724070tKaHcb','258DOyUvN','612336dNleve','232AtInHR','call','match','8xjPbsr','isArray','CWB','log','includes','extensions_settings_ST-Amily2-Chat-Optimisation','toastr','\x0a[--Amily2::CHAR_END--]','[--Amily2::CHAR_START--]\x0a','parse','hasOwnProperty','11226KEcRws','split','map','unknown_chat_source','cwb_master_enabled','object','filter','10AqRsCy','getItem','Toastr\x20(','forEach','prototype','1052yhndcO','trim','2438532yFrnEz','error',''','1103074vqsqoZ','角色世界书','1064940WbgcVO','length','[CWB]\x20Error\x20reading\x20master\x20switch\x20state:','replace','string'];_0x1549=function(){return _0x556ba4;};return _0x1549();}export function escapeHtml(_0x478b0e){const _0x1c1d17=_0x38c295;if(typeof _0x478b0e!==_0x1c1d17(0x13c))return'';return _0x478b0e[_0x1c1d17(0x13b)](/&/g,'&')['replace'](//g,'>')['replace'](/"/g,'\x22')['replace'](/'/g,_0x1c1d17(0x135));}export function cleanChatName(_0x52de28){const _0x1e52ab=_0x38c295;if(!_0x52de28||typeof _0x52de28!==_0x1e52ab(0x13c))return _0x1e52ab(0x154);let _0x4f5583=_0x52de28;if(_0x52de28[_0x1e52ab(0x14a)]('/')||_0x52de28[_0x1e52ab(0x14a)]('\x5c')){const _0x1201ba=_0x52de28['split'](/[\\/]/);_0x4f5583=_0x1201ba[_0x1201ba[_0x1e52ab(0x139)]-0x1];}return _0x4f5583[_0x1e52ab(0x13b)](/\.jsonl$/,'')[_0x1e52ab(0x13b)](/\.json$/,'');}export function compareVersions(_0x1076b2,_0x3e0dea){const _0x2d3335=_0x38c295,_0x4a0322=String(_0x1076b2)[_0x2d3335(0x152)]('.')[_0x2d3335(0x153)](Number),_0x3ca967=String(_0x3e0dea)[_0x2d3335(0x152)]('.')[_0x2d3335(0x153)](Number);for(let _0xa41569=0x0;_0xa41569_0x9e1f93)return 0x1;if(_0x44b8c0<_0x9e1f93)return-0x1;}return 0x0;}export function parseCustomFormat(_0x53ab0b){const _0x1c8852=_0x38c295,_0x265bf9={};if(typeof _0x53ab0b!==_0x1c8852(0x13c))return _0x265bf9;const _0x4e0c7b=_0x53ab0b[_0x1c8852(0x145)](/\[--Amily2::CHAR_START--\]([\s\S]*?)\[--Amily2::CHAR_END--\]/);if(!_0x4e0c7b||!_0x4e0c7b[0x1])return _0x265bf9;const _0x342192=_0x4e0c7b[0x1],_0x12eba0=(_0x26b008,_0x4580d9,_0x4e7136)=>{const _0xef770b=_0x1c8852,_0x3c3e76=_0x4580d9[_0xef770b(0x152)]('.');let _0x40a0db=_0x26b008;for(let _0x5c49fd=0x0;_0x5c49fd<_0x3c3e76['length']-0x1;_0x5c49fd++){const _0x2283bb=_0x3c3e76[_0x5c49fd],_0x400a83=_0x3c3e76[_0x5c49fd+0x1],_0x5ae114=/^\d+$/[_0xef770b(0x13f)](_0x400a83);!_0x40a0db[_0x2283bb]&&(_0x40a0db[_0x2283bb]=_0x5ae114?[]:{}),_0x40a0db=_0x40a0db[_0x2283bb];}const _0x35e568=_0x3c3e76[_0x3c3e76[_0xef770b(0x139)]-0x1];/^\d+$/[_0xef770b(0x13f)](_0x35e568)&&Array['isArray'](_0x40a0db)?_0x40a0db[parseInt(_0x35e568,0xa)]=_0x4e7136:_0x40a0db[_0x35e568]=_0x4e7136;},_0x5e994f=_0x342192[_0x1c8852(0x152)]('\x0a')[_0x1c8852(0x157)](_0x843880=>_0x843880[_0x1c8852(0x132)]()!=='');return _0x5e994f[_0x1c8852(0x12f)](_0x3c7e74=>{const _0x27a6b3=_0x1c8852,_0x544c6f=_0x3c7e74['match'](/^\[{1,2}(.*?)\]{1,2}:([\s\S]*)$/);if(_0x544c6f){const _0x2f5e8b=_0x544c6f[0x1],_0x45271e=_0x544c6f[0x2][_0x27a6b3(0x132)]();_0x12eba0(_0x265bf9,_0x2f5e8b,_0x45271e);}}),_0x265bf9;}function buildCustomFormatRecursive(_0x4b3004,_0x35c1fa=''){const _0x7d17d9=_0x38c295;let _0x108b43='';for(const _0x12bb5c in _0x4b3004){if(Object[_0x7d17d9(0x130)][_0x7d17d9(0x150)][_0x7d17d9(0x144)](_0x4b3004,_0x12bb5c)){const _0x255cd5=_0x35c1fa?_0x35c1fa+'.'+_0x12bb5c:_0x12bb5c,_0x115a84=_0x4b3004[_0x12bb5c];if(_0x115a84===null||_0x115a84===undefined)continue;if(typeof _0x115a84==='object'&&!Array[_0x7d17d9(0x147)](_0x115a84))_0x108b43+=buildCustomFormatRecursive(_0x115a84,_0x255cd5);else Array[_0x7d17d9(0x147)](_0x115a84)?_0x115a84[_0x7d17d9(0x139)]>0x0&&typeof _0x115a84[0x0]===_0x7d17d9(0x156)&&_0x115a84[0x0]!==null?_0x115a84['forEach']((_0x167804,_0x46eedf)=>{_0x108b43+=buildCustomFormatRecursive(_0x167804,_0x255cd5+'.'+_0x46eedf);}):_0x115a84[_0x7d17d9(0x12f)]((_0x425283,_0x6020b5)=>{_0x108b43+='['+_0x255cd5+'.'+_0x6020b5+']:'+_0x425283+'\x0a';}):_0x108b43+='['+_0x255cd5+']:'+_0x115a84+'\x0a';}}return _0x108b43;}export function buildCustomFormat(_0x40e36c){const _0x3af960=_0x38c295;let _0x44c89a=buildCustomFormatRecursive(_0x40e36c);return _0x44c89a=_0x44c89a[_0x3af960(0x152)]('\x0a')[_0x3af960(0x157)](_0x2fb3e9=>_0x2fb3e9[_0x3af960(0x145)](/^\[.*?]:.+/))['join']('\x0a'),_0x3af960(0x14e)+_0x44c89a['trim']()+_0x3af960(0x14d);} +const DEBUG_MODE = true; +const SCRIPT_ID_PREFIX = 'CWB'; + + +export function logDebug(...args) { + if (DEBUG_MODE) { + console.log(`[${SCRIPT_ID_PREFIX}]`, ...args); + } +} + +export function logError(...args) { + console.error(`[${SCRIPT_ID_PREFIX}]`, ...args); +} + +export function isCwbEnabled() { + try { + const overrides = JSON.parse(localStorage.getItem('cwb_boolean_settings_override') || '{}'); + if (overrides.cwb_master_enabled !== undefined) { + return overrides.cwb_master_enabled === true; + } + + const settingsString = localStorage.getItem('extensions_settings_ST-Amily2-Chat-Optimisation'); + if (settingsString) { + const settings = JSON.parse(settingsString); + if (settings?.cwb_master_enabled !== undefined) { + return settings.cwb_master_enabled === true; + } + } + + return true; + } catch (error) { + console.error('[CWB] Error reading master switch state:', error); + return true; + } +} + +export function checkCwbEnabled(operation = '操作') { + if (!isCwbEnabled()) { + console.log(`[${SCRIPT_ID_PREFIX}] ${operation}被跳过 - CharacterWorldBook总开关已关闭`); + return false; + } + return true; +} + +export function showToastr(type, message, options = {}) { + if (!isCwbEnabled()) { + return; + } + if (window.toastr) { + window.toastr.clear(); + window.toastr[type](message, `角色世界书`, options); + } else { + logDebug(`Toastr (${type}): ${message}`); + } +} + +export function escapeHtml(unsafe) { + if (typeof unsafe !== 'string') return ''; + return unsafe.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, '''); +} + +export function cleanChatName(fileName) { + if (!fileName || typeof fileName !== 'string') return 'unknown_chat_source'; + let cleanedName = fileName; + if (fileName.includes('/') || fileName.includes('\\')) { + const parts = fileName.split(/[\\/]/); + cleanedName = parts[parts.length - 1]; + } + return cleanedName.replace(/\.jsonl$/, '').replace(/\.json$/, ''); +} + +export function compareVersions(v1, v2) { + const parts1 = String(v1).split('.').map(Number); + const parts2 = String(v2).split('.').map(Number); + for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) { + const p1 = parts1[i] || 0; + const p2 = parts2[i] || 0; + if (p1 > p2) return 1; + if (p1 < p2) return -1; + } + return 0; +} + +export function parseCustomFormat(text) { + const data = {}; + if (typeof text !== 'string') return data; + + const coreDataMatch = text.match(/\[--Amily2::CHAR_START--\]([\s\S]*?)\[--Amily2::CHAR_END--\]/); + if (!coreDataMatch || !coreDataMatch[1]) { + return data; + } + const coreData = coreDataMatch[1]; + + const setNestedValue = (obj, path, value) => { + const keys = path.split('.'); + let current = obj; + for (let i = 0; i < keys.length - 1; i++) { + const key = keys[i]; + const nextKey = keys[i + 1]; + const isNextKeyNumeric = /^\d+$/.test(nextKey); + if (!current[key]) { + current[key] = isNextKeyNumeric ? [] : {}; + } + + if (typeof current[key] !== 'object' || current[key] === null) { + logError(`Path conflict in worldbook entry for path: ${path}. Expected object/array at key '${key}', but found ${typeof current[key]}.`); + return; + } + + current = current[key]; + } + const finalKey = keys[keys.length - 1]; + if (/^\d+$/.test(finalKey) && Array.isArray(current)) { + current[parseInt(finalKey, 10)] = value; + } else if (typeof current === 'object' && !Array.isArray(current)) { + current[finalKey] = value; + } + }; + + const lines = coreData.split('\n').filter(line => line.trim() !== ''); + lines.forEach(line => { + const match = line.match(/^\[{1,2}(.*?)\]{1,2}:([\s\S]*)$/); + if (match) { + const path = match[1]; + const value = match[2].trim(); + setNestedValue(data, path, value); + } + }); + + return data; +} + +function buildCustomFormatRecursive(obj, prefix = '') { + let result = ''; + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + const newPrefix = prefix ? `${prefix}.${key}` : key; + const value = obj[key]; + + if (value === null || value === undefined) continue; + + if (typeof value === 'object' && !Array.isArray(value)) { + result += buildCustomFormatRecursive(value, newPrefix); + } else if (Array.isArray(value)) { + if (value.length > 0 && typeof value[0] === 'object' && value[0] !== null) { + value.forEach((item, index) => { + result += buildCustomFormatRecursive(item, `${newPrefix}.${index}`); + }); + } else { + value.forEach((item, index) => { + result += `[${newPrefix}.${index}]:${item}\n`; + }); + } + } else { + result += `[${newPrefix}]:${value}\n`; + } + } + } + return result; +} + +export function buildCustomFormat(data) { + let content = buildCustomFormatRecursive(data); + content = content.split('\n').filter(line => line.match(/^\[.*?]:.+/)).join('\n'); + return `[--Amily2::CHAR_START--]\n${content.trim()}\n[--Amily2::CHAR_END--]`; +}