// ==UserScript==
// @name rpg测试
// @namespace http://tampermonkey.net/
// @version 0.4
// @license GPL
// @description 配合酒馆游玩
// @author 从前跟你一样
// @grant unsafeWindow
// @match *://*/*
// @require https://code.jquery.com/jquery-3.4.1.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/js-yaml.min.js
// @connect vagrantup.com
// @grant unsafeWindow
// @grant GM_xmlhttpRequest
// @connect sd则此处换成你的电脑域名ip、不需要带端口。
// @connect *
// @connect 192.168.10.2
// @connect 127.0.0.1
// @connect novelai.net
// @match *://*/*
// @description Save user settings
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
(function() {
'use strict';
let rpgster="";
let rpg={};
// 添加点击事件监听器到您的按钮或元素上
$(document).ready(function() {
rpgster= setInterval(addNewElement, 2000);
});
// 定义默认设置
const defaultSettings = {
say:"测试",
key:"测试"
};
let settings = {};
for (const [key, defaultValue] of Object.entries(defaultSettings)) {
settings[key] = GM_getValue(key, defaultValue);
// 如果没有读取到值,就使用默认值并保存
if (settings[key] === defaultValue) {
GM_setValue(key, defaultValue);
}
}
function addNewElement() {
const targetElement = document.querySelector('#option_toggle_AN');
if (targetElement) {
clearInterval(rpgster);
const newElement = document.createElement('a');
newElement.id = 'option_toggle_AN3';
const icon = document.createElement('i');
icon.className = 'fa-lg fa-solid fa-note-sticky';
newElement.appendChild(icon);
const span = document.createElement('span');
span.setAttribute('data-i18n', "打开设置");
span.textContent = '打开rpg工具';
newElement.appendChild(span);
// return true; // 表示操作成功完成
targetElement.parentNode.insertBefore(newElement, targetElement.nextSibling);
console.log("New element added successfully");
document.getElementById('option_toggle_AN3').addEventListener('click', showSettingsPanel);
}
}
function createrpgSettingsPanel() {
const panel = document.createElement('div');
panel.id = 'rpgsettings-panel';
panel.style.position = 'absolute';
panel.style.top = '50%';
panel.style.left = '50%';
panel.style.transform = 'translate(-50%, -50%)';
panel.style.backgroundColor = 'black'; // 设置背景为黑色
panel.style.color = 'white';// 设置字体为白色
panel.style.padding = '20px';
panel.style.border = '1px solid white';// 设置边框为白色
panel.style.zIndex = '10000';
panel.style.display = 'none';
panel.style.overflowY = 'auto';
panel.style.maxHeight = '80vh';
panel.innerHTML += `
<style>
#rpgsettings-panel input, #settings-panel select {
background-color: #444;
color: white;
background-color: black;
border: none;
padding: 5px;
margin: 5px 0;
}
#rpgsettings-panel button {
background-color: #444;
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
}
#rpgsettings-panel button:hover {
background-color: #555;
}
</style>
`;
panel.innerHTML = `
<h2>设置面板</h2>
<br><br>
<label>说明:<input type="text" id="say" value="${settings.say}"></label><br>
<label>秘钥:<input type="text" id="key" value="${settings.key}"></label><br>
<button id="save-AESEword">加密世界书</button>
<button id="save-AESDword">解密世界书</button><br>
<button id="save-AESErole">加密角色栏</button>
<button id="save-AESDrole">解密角色栏</button><br>
<button id="testbu">测试按钮</button><br>
<button id="close-rpgsettings">关闭</button>
<a id="visit-website-link" href="https://asgdd1kjanhq.sg.larksuite.com/wiki/I5e5wz7BDiVouJk5DQBlDwcJgAg?from=from_copylink" target="_blank">帮助</a>
<a id="visit-website-link" href="https://discord.com/channels/1134557553011998840/1264813484437409813/1264813484437409813" target="_blank">dc讨论</a>
<a id="visit-website-link">BY从前我跟你一样</a>
`;
const style = document.createElement('style');
style.textContent = `
#rpgsettings-panel input {
background-color: black !important;
color: white;
border: none;
padding: 5px;
margin: 5px 0;
}
#rpgsettings-panel input, #settings-panel select {
background-color: #444;
color: white;
background-color: black;
border: none;
padding: 5px;
margin: 5px 0;
}
#rpgsettings-panel button {
background-color: #444;
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
}
#rpgsettings-panel button:hover {
background-color: #555;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .4s;
border-radius: 34px;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background-color: #2196F3;
}
input:checked + .slider:before {
transform: translateX(26px);
}
`;
document.body.appendChild(panel);
document.head.appendChild(style);
document.getElementById('save-AESEword').addEventListener('click', aesEword);
document.getElementById('save-AESDword').addEventListener('click', aesDword);
document.getElementById('save-AESErole').addEventListener('click', aesErole);
document.getElementById('save-AESDrole').addEventListener('click', aesDrole);
document.getElementById('testbu').addEventListener('click', testbu);
document.getElementById('close-rpgsettings').addEventListener('click', hideSettingsPanel);
// 添加滑块切换事件监听器
return panel;
}
// 定义加密函数
function aesEncrypt(plaintext, key, iv) {
const encrypted = CryptoJS.AES.encrypt(plaintext, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
// 定义解密函数
function aesDecrypt(ciphertext, key, iv) {
const decrypted = CryptoJS.AES.decrypt(ciphertext, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
let txt= "";
try {
txt= decrypted.toString(CryptoJS.enc.Utf8);
} catch (e) {
throw e;
}
return txt
}
const secretIv = '1234567890123456';
function aesEword() {
const key = document.getElementById("key");
let secretKey= key.value
// 使用 querySelectorAll 查找所有匹配的元素
const elements = document.querySelectorAll('[data-i18n="[placeholder]What this keyword should mean to the AI, sent verbatim"]');
// 遍历找到的元素
let p=false;
if(!(elements.length > 0)){
alert("未找到加密文本")
return;
}
elements.forEach(element => {
// 打印元素的 placeholder 属性值
if(p){
return;
}
if(element.value==""){
return;
}
if(isEncrypted(removeExplanation(element.value))){
alert("已经加密")
p=true;
return;
}
let aesEtxt ="";
try {
aesEtxt = aesEncrypt(element.value, secretKey, secretIv);
} catch (e) {
alert("加密出错")
p=true;
return ;
}
element.value=addExplanation(aesEtxt,document.getElementById("say").value);
element.dispatchEvent(new Event('input'));
});
if(!p){
saveSettings()
alert("加密成功")
}
}
function aesErole() {
const key = document.getElementById("key");
let secretKey= key.value
const element2 = document.getElementById("description_textarea");
const element3 = document.getElementById("firstmessage_textarea");
// 使用 querySelectorAll 查找所有匹配的元素
if(!element2||!element3){
alert("未找到加密文本")
return;
}
if(element2.value !=""){
if(isEncrypted(removeExplanation(element2.value))){
alert("已经加密")
}else{
let aesEtxt ="";
try {
aesEtxt = aesEncrypt(element2.value, secretKey, secretIv);
} catch (e) {
alert("加密出错")
return ;
}
element2.value=addExplanation(aesEtxt,document.getElementById("say").value);
element2.dispatchEvent(new Event('input'));
}
}
if(element3.value !=""){
if(isEncrypted(removeExplanation(element3.value))){
alert("已经加密")
}else{
let aesEtxt ="";
try {
aesEtxt = aesEncrypt(element3.value, secretKey, secretIv);
} catch (e) {
alert("加密出错")
return ;
}
element3.value=addExplanation(aesEtxt,document.getElementById("say").value);
element3.dispatchEvent(new Event('input'));
}
}
saveSettings()
alert("加密成功")
}
function aesDword() {
const txt = document.getElementById("key");
let secretKey= txt.value
const elements = document.querySelectorAll('[data-i18n="[placeholder]What this keyword should mean to the AI, sent verbatim"]');
let p=false;
if(!(elements.length > 0)){
alert("未找到加密文本")
return;
}
elements.forEach (element => {
// 打印元素的 placeholder 属性值
if(element.value==""){
return;
}
let value= removeExplanation(element.value);
if(!isEncrypted(value)){
p=true;
return;
}
try {
element.value= aesDecrypt(value, secretKey, secretIv);
} catch (e) {
if(p){
return;
}
alert("秘钥错误")
p=true;
return ;
}
element.dispatchEvent(new Event('input'));
console.log(element.value);
});
alert("解密成功")
}
function aesDrole() {
const key = document.getElementById("key");
let secretKey= key.value
const element2 = document.getElementById("description_textarea");
const element3 = document.getElementById("firstmessage_textarea");
// 使用 querySelectorAll 查找所有匹配的元素
if(!element2||!element3){
alert("未找到解密文本")
return;
}
if(element2.value !=""){
let value=removeExplanation(element2.value);
if(!isEncrypted(value)){
}else{
let aesDtxt ="";
try {
aesDtxt = aesDecrypt(value, secretKey, secretIv);
} catch (e) {
alert("秘钥错误")
return ;
}
element2.value=aesDtxt
element2.dispatchEvent(new Event('input'));
}
}
if(element3.value !=""){
let value=removeExplanation(element3.value);
if(!isEncrypted(value)){
}else{
let aesDtxt ="";
try {
aesDtxt = aesDecrypt(value, secretKey, secretIv);
} catch (e) {
alert("秘钥错误")
return ;
}
element3.value=aesDtxt
element3.dispatchEvent(new Event('input'));
}
}
alert("解密成功")
}
function isEncrypted(str) {
// 检查字符串是否只包含 Base64 字符
const base64Regex = /^[A-Za-z0-9+/=]+$/;
if (!base64Regex.test(str)) {
return false;
}
// 检查字符串长度是否为 4 的倍数
if (str.length % 4 !== 0) {
return false;
}
return true;
}
function saveSettings() {
for (const key of Object.keys(defaultSettings)) {
const element = document.getElementById(key);
if (element) {
settings[key] = element.value;
GM_setValue(key, element.value);
}
}
console.log('rpgSettings saved');
// hideSettingsPanel();
}
function closeSettings() {
hideSettingsPanel();
}
function showSettingsPanel() {
for (const key of Object.keys(defaultSettings)) {
const element = document.getElementById(key);
if (element) {
settings[key] = element.value;
GM_setValue(key, element.value);
}
}
console.log('Settings saved:', settings);
const panel = document.getElementById('rpgsettings-panel');
if (!panel) {
createrpgSettingsPanel();
}
document.getElementById('rpgsettings-panel').style.display = 'block';
}
function hideSettingsPanel() {
document.getElementById('rpgsettings-panel').style.display = 'none';
}
// Your code here...
// 函数1:在字符串中添加<说明>标签
function addExplanation(str, explanation) {
return "<说明>" + explanation + "</说明>"+str;
}
// 函数2:去除字符串中的<说明>标签及其内容
function removeExplanation(str) {
return str.replace(/<说明>.*?<\/说明>/g, "");
}
function testbu(){
sent();
}
const style2 = document.createElement('style');
style2.textContent = `
.tavern-chat {
width: 100%;
max-width: 100%; /* 设置最大宽度,防止在大屏幕下过宽 */
margin: 0 auto; /* 水平居中对齐 */
border: 2px solid #b79f62; /* 设置边框样式 */
box-sizing: border-box; /* 将边框和内边距包含在元素的宽高内 */
padding: 20px; /* 添加内边距,避免内容紧贴边框 */
}
.chat-box {
height: 400px;
overflow-y: auto; /* 当内容超出高度时显示垂直滚动条 */
margin-bottom: 20px;
}
.data-panel {
display: flex;
justify-content: space-around; /* 均匀分布每个子元素 */
flex-wrap: wrap; /* 当宽度不足时自动换行 */
}
.data-panel > div {
flex: 1; /* 每个子元素平分剩余宽度 */
min-width: 200px; /* 设置最小宽度,防止在小屏幕下过窄 */
padding: 10px;
}
`
document.head.appendChild(style2);
$(document).ready(function() {
});
function load(){
const elements = document.querySelectorAll('[data-i18n="[placeholder]What this keyword should mean to the AI, sent verbatim"]');
let p=false;
if(!(elements.length > 0)){
alert("未找到加密文本")
return;
}
elements.forEach (element => {
let tx=element.value;
let name="";
const regex = /^--- #(.*)/;
const match = tx.match(regex);
if (match) {
name = match[1].trim();
console.log(name);
} else {
console.log("No match found.");
}
try {
const data = jsyaml.load(tx);
console.log("data.",data);
if(!data){
return;
}
// let keys = Object.keys(data);
for (var key in data) {
if(key=="角色"){
for (var key2 in data["角色"]) {
if(key2.includes('json')){
let zdsx=JSON.parse(data["角色"][key2]);
data["角色"][key2]=zdsx;
}
}
}
if(key.includes('json')){
let keyjson=JSON.parse(data[key]);
data[key]=keyjson;
}
}
rpg[name]=[element,data]
// if(keys.includes('分类')&&data['分类']=='用户'){
// console.log("战斗属性.",data["角色"]['战斗属性json']);
// let zdsx=JSON.parse(data["角色"]['战斗属性json']);
// console.log("zdsx.",zdsx);
// zdsx["人物简介"]=zdsx["人物简介"]+"1234"
// let zdsxtx= JSON.stringify(zdsx, null, 2);
// zdsxtx=`${zdsxtx.replace(/\n/g, '\n ')}`;
// data["角色"]['战斗属性json']=zdsxtx;
// let jsdata=jsyaml.dump(data,{ lineWidth: -1 });
// jsdata="--- #"+name+"\n"+jsdata
// element.value=jsdata;
// }
} catch (e) {
console.error(e);
}
})
console.log("rpg属性.",rpg);
}
function sent(){
// ID of the target textarea
var textareaId = 'send_textarea';
// Get the textarea element
var textarea = document.getElementById(textareaId);
var send_but = document.getElementById("send_but");
send_but.addEventListener('click', function(event) {
console.log('Element clicked');
textarea.value="11111"+textarea.value;
})
const mesTextElements = document.getElementsByClassName('mes_text');
const lastMesText = mesTextElements[mesTextElements.length - 1];
let html='<div class="tavern-chat"><!-- 文字显示框 --><div class="chat-box"><!-- AI生成的文字内容 --><p>AI: 欢迎来到酒馆,勇敢的冒险者!有什么需要我帮忙的吗?</p><p>AI: 我们这里有各种美酒佳肴,还有许多有趣的冒险任务等着你!</p></div><!-- 数据展示界面 --><div class="data-panel"><div class="character-info"><span>角色名: [User]</span><span>等级: 5</span><span>金币: 500</span></div><div class="quest-info"><h4>当前任务</h4><ul><li>讨伐哥布林王 (进行中)</li><li>收集10个野猪皮 (已完成)</li></ul></div><div class="inventory-info"><h4>背包</h4><ul><li>治疗药水 x5</li><li>中级法力药剂 x3</li><li>铁剑 x1</li></ul></div></div></div>';
const style2 = document.createElement('style');
let html2= `<div id="container">
<div id="character-info">
<div class="image-container">
<img src="https://files.catbox.moe/7sdift.jpeg" alt="角色照片">
</div>
<div class="info-box">
<p><span id="name">张三</span></p>
<div class="progress-bar">
<label>性别:</label>
<label>男</label>
</div>
<div class="health-container">
<label>血量:</label>
<div class="health-bar">
<div class="fill" style="width: 75%;">
</div>
</div>
</div>
<div class="mana-container">
<label>蓝量:</label>
<div class="mana-bar">
<div class="mana" style="width: 75%;">
</div>
</div>
</div>
<div class="progress-bar">
<label>攻击力:</label>
<label>4</label>
</div>
<div class="progress-bar">
<label>防御力:</label>
<label>5</label>
</div>
<div class="progress-bar">
<label>经验值:</label>
<progress id="xp" value="6500" max="10000"></progress>
</div>
</div>
</div>
<div id="buttons">
<button id="inventory">背包</button>
<button id="character">人物</button>
<button id="quests">任务</button>
</div>
<div id="other-character">
<div class="image-container">
<img src="https://files.catbox.moe/7sdift.jpeg" alt="其他角色照片">
</div>
<div class="info-box">
<p><span id="other-name">李四</span>
<div class="progress-bar">
<label>性别:</label>
<label>女</label>
</div>
<div class="progress-bar">
<label>种族:</label>
<label>精灵</label>
</div>
<div class="progress-bar">
<label>好感度:</label>
<progress id="affinity" value="80" max="100"></progress>
</div>
</div>
</div>
<div id="other-buttons">
<button id="shop">商店</button>
<button id="quest">任务</button>
<button id="gift">赠送</button>
</div>
</div>
`
let html3=generatePage();
style2.textContent = `
.health-container {
display: flex;
align-items: center;
gap: 10px;
}
label {
flex-shrink: 0;
}
.mana-container {
display: flex;
align-items: center;
gap: 10px;
}
#container {
font-family: Arial, sans-serif;
background-color: #222;
padding: 5px;
max-width:1024px;
margin: 0 auto;
color: #fff;
}
#character-info, #other-character {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.image-container {
width: 80%;
height: 50%;
border-radius: 5px;
overflow: hidden;
margin-right: 3px;
}
.image-container img {
width: 100%;
height: 100%;
object-fit: cover;
}
.info-box {
flex: 0.2;
padding: 5px;
background-color: #333;
border-radius: 5px;
}
/* 调整进度条样式,使其更加紧致 */
.health-bar {
width: 30%; /* 血条的总宽度 */
height: 10px; /* 血条的高度 */
background-color: #444; /* 血条的背景色 */
border-radius: 5px; /* 圆角效果 */
overflow: hidden; /* 超出部分隐藏 */
}
.mana-bar {
width: 30%; /* 血条的总宽度 */
height: 10px; /* 血条的高度 */
background-color: #444; /* 血条的背景色 */
border-radius: 5px; /* 圆角效果 */
overflow: hidden; /* 超出部分隐藏 */
}
.fill {
height: 100%; /* 填充部分的高度与血条一致 */
background-color: red; /* 填充部分的颜色为红色 */
transition: width 0.5s; /* 动画效果,宽度变化时平滑过渡 */
}
.mana {
height: 100%; /* 填充部分的高度与血条一致 */
background-color: blue; /* 填充部分的颜色为红色 */
transition: width 0.5s; /* 动画效果,宽度变化时平滑过渡 */
}
.progress-bar label {
margin-right: 1px;
width: 20px;
}
progress {
flex: 0.2;
height: 10px;
appearance: none;
border-radius: 2px;
overflow: hidden;
}
progress::-webkit-progress-bar {
background-color: #444;
}
progress::-webkit-progress-value {
background-color: #4CAF50;
}
#buttons, #other-buttons {
display: flex;
justify-content: center;
padding: 5px 0;
}
button {
padding: 5px 10px;
margin: 0 5px;
font-size: 13px;
border: none;
background-color: #4CAF50;
color: white;
border-radius: 2px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}`
document.head.appendChild(style2);
lastMesText.innerHTML=lastMesText.innerHTML+html3;
}
//--------------------------------------------------
// 主角色数据
const mainCharacter = {
name: "张三",
gender: "男",
health: 30,
mana: 75,
attack: 4,
defense: 5,
xp: 6500,
image: "https://files.catbox.moe/7sdift.jpeg"
};
// 其他角色数组
const otherCharacters = [
{
name: "李四",
gender: "女",
race: "精灵",
affinity: 80,
image: "https://files.catbox.moe/k95smk.png"
},
{
name: "王五",
gender: "男",
race: "人类",
affinity: 60,
image: "https://files.catbox.moe/k95smk.png"
}
// 可以添加更多角色...
];
function generateMainCharacterHTML(character) {
return `
<div id="character-info">
<div class="image-container">
<img src="${character.image}" alt="角色照片">
</div>
<div class="info-box">
<p><span id="name">${character.name}</span></p>
<div class="progress-bar">
<label>性别:</label>
<label>${character.gender}</label>
</div>
<div class="health-container">
<label>血量:</label>
<div class="health-bar">
<div class="fill" style="width: ${character.health}%;"></div>
</div>
</div>
<div class="mana-container">
<label>蓝量:</label>
<div class="mana-bar">
<div class="mana" style="width: ${character.mana}%;"></div>
</div>
</div>
<div class="progress-bar">
<label>攻击力:</label>
<label>${character.attack}</label>
</div>
<div class="progress-bar">
<label>防御力:</label>
<label>${character.defense}</label>
</div>
<div class="progress-bar">
<label>经验值:</label>
<progress id="xp" value="${character.xp}" max="100"></progress>
</div>
</div>
</div>
<div id="buttons">
<button id="inventory">背包</button>
<button id="character">人物</button>
<button id="quests">任务</button>
</div>
`;
}
function generateOtherCharacterHTML(character) {
return `
<img src="${character.image}" alt="角色照片">
<div id="character-info">
<div class="image-container">
<img src="${character.image}" alt="其他角色照片">
</div>
<div class="info-box">
<p><span class="other-name">${character.name}</span></p>
<div class="progress-bar">
<label>性别:</label>
<label>${character.gender}</label>
</div>
<div class="progress-bar">
<label>种族:</label>
<label>${character.race}</label>
</div>
<div class="progress-bar">
<label>好感度:</label>
<progress class="affinity" value="${character.affinity}" max="100"></progress>
</div>
</div>
</div>
<div id="other-buttons">
<button id="${character.name}_shop">商店</button>
<button id="${character.name}_quest">任务</button>
<button id="${character.name}_gift">赠送</button>
</div>
`;
}
function generatePage() {
// 生成主角色HTML
var mainHTML = generateMainCharacterHTML(mainCharacter);
// 生成其他角色HTML
const otherCharactersHTML = otherCharacters.map(generateOtherCharacterHTML).join('');
// 添加其他角色的按钮
return mainHTML+otherCharactersHTML
}
})();