risum 모듈 — RISU modules[] — 기능 확장
조회 835 · 2026-07-04
캐시 타이머 5분 캐시 사용자를 위한 도구 클로드는 5분 캐싱에 입력 대비 1.25배 , 1시간 캐싱에 2배 의 가격이 책정됩니다. 이 타이머로 당신의 통장을 지키세요! 300s 150s 30s 새로고침을 해도 편집 버튼을 눌러도 시간이 초기화되지 않습니다 채팅을 입력해 타이머를 켜세요! 다운로드
{
"name": "⏱️캐시 타이머",
"description": "",
"lorebook": [],
"regex": [
{
"comment": "캐시 타이머",
"type": "editdisplay",
"in": "<CACHETIMER>([\\\\s\\\\S]*)$",
"out": "$1",
"flag": "g",
"ableFlag": true
}
],
"trigger": [
{
"lowLevelAccess": "true",
"comment": "",
"type": "start",
"conditions": [],
"effect": [
{
"type": "triggerlua",
"code": "local TOTAL = 300\n\nfunction onOutput(triggerId)\n -- 봇이 응답할 때마다 시작 시각을 새로 저장 → 매 턴 타이머 리셋\n setState(triggerId, \"ct_start\", os.time())\nend\n\nlistenEdit(\"editDisplay\", function(triggerId, data)\n local startTime = getState(triggerId, \"ct_start\")\n if not startTime then return data end\n local elapsed = os.time() - startTime\n local remaining = TOTAL - elapsed\n local fullChat = getFullChat(triggerId)\n if not fullChat or #fullChat == 0 then return data end\n local lastMsg = fullChat[#fullChat]\n if not lastMsg or lastMsg.role ~= \"char\" then return data end\n local lastData = lastMsg.data or \"\"\n if lastData == \"\" then return data end\n local checkLen = math.min(50, #lastData, #data)\n if checkLen <= 0 or data:sub(1, checkLen) ~= lastData:sub(1, checkLen) then\n return data\n end\n -- 0초 도달: 타이머 표시 없이 반환\n if remaining <= 0 then\n return data\n end\n local delay = tostring(elapsed)\n local dur = tostring(TOTAL)\n\n -- 숫자 카운터 키프레임\n local secs = {}\n for e = 0, TOTAL do\n secs[#secs + 1] = string.format(\"%.4f\", e / TOTAL * 100) .. \"%{--t:\" .. (TOTAL - e) .. \"}\"\n end\n\n -- 펄스(깜빡임) 키프레임: 0~80% 정적, 마지막 20%에서 점점 빠르게 깜빡임 (1.0s → 0.3s)\n -- 전체 길이 애니메이션 + animation-delay 로 처리하므로 재렌더링 없이 CSS 시점만으로 켜짐\n local pulseSecs = {\"0%,80%{border-color:rgba(255,255,255,0.1);background:rgba(30,30,50,0.9)}\"}\n local ZONE = TOTAL * 0.20\n local zoneStart = TOTAL - ZONE\n local pt = 0\n local red = true\n while true do\n local rem = ZONE - pt\n if rem < 0 then break end\n local half = (0.3 + (rem / ZONE) * 0.7) / 2\n pt = pt + half\n if pt > ZONE then break end\n local pct = (zoneStart + pt) / TOTAL * 100\n if red then\n pulseSecs[#pulseSecs + 1] = string.format(\"%.4f%%{border-color:#f44336;background:rgba(60,20,20,0.9)}\", pct)\n else\n pulseSecs[#pulseSecs + 1] = string.format(\"%.4f%%{border-color:rgba(255,255,255,0.1);background:rgba(30,30,50,0.9)}\", pct)\n end\n red = not red\n end\n pulseSecs[#pulseSecs + 1] = \"100%{border-color:#f44336;background:rgba(60,20,20,0.9)}\"\n local pulseKF = \"@keyframes ctPulse{\" .. table.concat(pulseSecs) .. \"}\"\n\n return data .. [[\n<CACHETIMER>\n<style>\n@property --t{syntax:\"<integer>\";initial-value:0;inherits:false}\n@keyframes ctDrain{from{width:100%}to{width:0%}}\n@keyframes ctColor{0%,60%{background:#4CAF50}75%{background:#FF9800}85%,100%{background:#f44336}}\n@keyframes ctNum{]] .. table.concat(secs) .. [[}\n]] .. pulseKF .. [[\n.ctwrap{margin:12px 0 0;padding:6px 10px;border-radius:8px;border:1px solid rgba(255,255,255,0.1);background:rgba(30,30,50,0.9);animation:ctPulse ]] .. dur .. [[s linear forwards;animation-delay:-]] .. delay .. [[s}\n.cttrack{position:relative;width:100%;height:22px;background:rgba(255,255,255,0.1);border-radius:4px;overflow:hidden}\n.ctb{position:absolute;left:0;top:0;height:100%;width:100%;border-radius:4px;overflow:hidden;animation:ctDrain ]] .. dur .. [[s linear forwards,ctColor ]] .. dur .. [[s linear forwards;animation-delay:-]] .. delay .. [[s,-]] .. delay .. [[s}\n.ctb::after{content:counter(ct) \"s\";counter-reset:ct var(--t);position:absolute;left:8px;top:0;height:100%;display:flex;align-items:center;white-space:nowrap;font-size:11px;font-weight:bold;font-family:monospace;color:rgba(255,255,255,0.95);animation:ctNum ]] .. dur .. [[s step-end forwards;animation-delay:-]] .. delay .. [[s}\n</style>\n<div class=\"ctwrap\">\n<div class=\"cttrack\">\n<div class=\"ctb\"></div>\n</div>\n</div>\n]]\nend)\n\n"
}
]
}
],
"lowLevelAccess": true,
"hideIcon": false,
"backgroundEmbedding": "",
"assets": [],
"customModuleToggle": "",
"id": "78f54555-714e-4042-917d-dfbf475d249b",
"icon": "assets/b949bb4af9b39db09a0d3b3c0b6f67e62c5d55c72381ce474af19b205dc87b8e.png",
"namespace": "",
"cjs": "",
"enabled": true,
"__mmAssetFolders__": null
}