Scripts for Kour.io (have fun)
// ==UserScript==
// @name Wolf_ Ultimate menu
// @match *://kour.io/*
// @version 1.3
// @author wolf_
// @description Scripts for Kour.io (have fun)
// @grant GM_setValue
// @grant GM_getValue
// @run-at document-end
// @namespace https://greasyfork.org/users/1598070
// ==/UserScript==
(function() {
'use strict';
let settings = GM_getValue("kourPlusConfigs", {
userPhrases: ["GG!", "well played", "xD", "𝐄𝐀𝐒𝐘"],
lastColor: "#ff0000"
});
const ui = document.createElement('div');
ui.id = "kour-rgb-ui";
document.body.appendChild(ui);
const style = document.createElement('style');
style.innerHTML = `
@keyframes smoothRainbow {
0% { border-color: #ff0000; color: #ff0000; }
33% { border-color: #00ff00; color: #00ff00; }
66% { border-color: #0000ff; color: #0000ff; }
100% { border-color: #ff0000; color: #ff0000; }
}
#kour-rgb-ui {
position: fixed; top: 20px; right: 20px;
background: rgba(10, 10, 10, 0.98);
border: 2px solid #ff0000;
padding: 15px; z-index: 9999999;
border-radius: 12px; width: 270px;
font-family: 'Segoe UI', Tahoma, sans-serif;
animation: smoothRainbow 10s linear infinite;
box-shadow: 0 10px 30px rgba(0,0,0,0.6);
user-select: none;
}
.title-rgb {
text-align: center; font-weight: 900; font-size: 15px;
margin-bottom: 12px;
text-transform: uppercase; letter-spacing: 2px;
cursor: move;
padding: 8px;
background: rgba(255,255,255,0.03);
border-radius: 6px;
animation: smoothRainbow 10s linear infinite;
}
.section-label { font-size: 10px; color: #666; text-transform: uppercase; margin-bottom: 5px; display: block; font-weight: bold; }
.btn-style {
width: 100%; background: #1a1a1a; color: #fff; border: 1px solid #333;
padding: 10px; cursor: pointer; font-weight: bold; border-radius: 6px;
text-transform: uppercase; margin-bottom: 6px; font-size: 12px; transition: 0.2s;
}
.btn-style:hover { background: #333; border-color: #777; }
.fast-red { background: #400 !important; color: #ff4444 !important; border: 1px solid #600 !important; }
.clear-btn { background: #222 !important; color: #888 !important; font-size: 9px !important; margin-top: 5px !important; }
.color-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; background: #111; padding: 8px; border-radius: 6px; border: 1px solid #222; }
#nickColorPicker { border: none; width: 35px; height: 25px; cursor: pointer; background: none; }
.phrase-row { display: flex; gap: 5px; margin-bottom: 5px; }
.del-btn { background: #300; color: #f44; border: 1px solid #500; padding: 5px 10px; cursor: pointer; border-radius: 5px; font-weight: bold; }
#phrase-container { max-height: 160px; overflow-y: auto; margin-top: 10px; border-top: 1px solid #222; padding-top: 10px; }
.footer-rainbow {
font-size: 13px;
text-align: center;
margin-top: 15px;
font-weight: 900;
font-style: italic;
animation: smoothRainbow 10s linear infinite;
}
::-webkit-scrollbar { width: 4px; }
::-webkit-scrollbar-thumb { background: #333; border-radius: 10px; }
`;
document.head.appendChild(style);
function render() {
const savedPos = JSON.parse(localStorage.getItem("kourMenuPos") || '{"top":"20px","left":"auto","right":"20px"}');
ui.style.top = savedPos.top;
ui.style.left = savedPos.left;
ui.style.right = savedPos.right;
ui.innerHTML = `
<div class="title-rgb" id="kour-header">KOUR Ultimate Menu</div>
<span class="section-label">Quick Actions</span>
<button id="fastRedBtn" class="btn-style fast-red">🔴 Fast Red No-Name</button>
<span class="section-label" style="margin-top:10px;">Nickname</span>
<div class="color-row">
<input type="color" id="nickColorPicker" value="${settings.lastColor}">
<span style="font-size:11px; color:#888;">Custom Color</span>
</div>
<button id="setNickBtn" class="btn-style">Apply Nickname</button>
<span class="section-label" style="margin-top:10px;">Phrases</span>
<button id="addPhraseBtn" class="btn-style" style="color:#4f4; border-color:#262;">+ Add Phrase</button>
<div id="phrase-container"></div>
<button id="clearPhrasesBtn" class="btn-style clear-btn">Clear All</button>
<div class="footer-rainbow">Made by Wolf_</div>
<div style="font-size:9px; color:#333; text-align:center; margin-top:5px;">[O] Hide/Show | Drag title to move</div>
`;
const list = ui.querySelector('#phrase-container');
settings.userPhrases.forEach((p, index) => {
const row = document.createElement('div');
row.className = "phrase-row";
const b = document.createElement('button');
b.className = "btn-style"; b.style.marginBottom = "0"; b.innerText = p;
b.onclick = () => {
navigator.clipboard.writeText("ㅤ" + p);
const original = b.innerText;
b.innerText = "COPIED!"; setTimeout(() => b.innerText = original, 800);
};
const d = document.createElement('button');
d.className = "del-btn"; d.innerText = "X";
d.onclick = () => {
settings.userPhrases.splice(index, 1);
GM_setValue("kourPlusConfigs", settings); render();
};
row.appendChild(b); row.appendChild(d); list.appendChild(row);
});
document.getElementById('clearPhrasesBtn').onclick = () => {
if (confirm("Delete all phrases?")) {
settings.userPhrases = []; GM_setValue("kourPlusConfigs", settings); render();
}
};
document.getElementById('fastRedBtn').onclick = () => {
const fastName = "<color=#FF0000>ㅤ</color>";
localStorage.setItem("playerNickname", fastName);
window.unityInstance?.SendMessage("MapScripts", "SetNickname", fastName);
};
document.getElementById('setNickBtn').onclick = () => {
const name = prompt("Nickname:");
if (!name) return;
const color = document.getElementById('nickColorPicker').value;
settings.lastColor = color;
GM_setValue("kourPlusConfigs", settings);
const finalName = `<color=${color}>${name.trim()}</color>`;
localStorage.setItem("playerNickname", finalName);
window.unityInstance?.SendMessage("MapScripts", "SetNickname", finalName);
};
document.getElementById('addPhraseBtn').onclick = () => {
const newPhrase = prompt("New phrase:");
if (newPhrase) {
settings.userPhrases.push(newPhrase.trim());
GM_setValue("kourPlusConfigs", settings); render();
}
};
makeDraggable(ui, document.getElementById("kour-header"));
}
function makeDraggable(element, handle) {
let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
handle.onmousedown = (e) => {
e.preventDefault();
pos3 = e.clientX; pos4 = e.clientY;
document.onmouseup = () => {
document.onmouseup = null;
document.onmousemove = null;
localStorage.setItem("kourMenuPos", JSON.stringify({
top: element.style.top,
left: element.style.left,
right: "auto"
}));
};
document.onmousemove = (e) => {
e.preventDefault();
pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY;
pos3 = e.clientX; pos4 = e.clientY;
let newTop = element.offsetTop - pos2;
let newLeft = element.offsetLeft - pos1;
const padding = 1;
const maxLeft = window.innerWidth - element.offsetWidth - padding;
const maxTop = window.innerHeight - element.offsetHeight - padding;
newTop = Math.max(padding, Math.min(newTop, maxTop));
newLeft = Math.max(padding, Math.min(newLeft, maxLeft));
element.style.top = newTop + "px";
element.style.left = newLeft + "px";
element.style.right = "auto";
};
};
}
render();
setInterval(() => {
const saved = localStorage.getItem("playerNickname");
if (saved && typeof unityInstance !== 'undefined') {
unityInstance.SendMessage("MapScripts", "SetNickname", saved);
}
}, 5000);
document.addEventListener('keydown', (e) => {
if (e.key.toLowerCase() === 'o') ui.style.display = (ui.style.display === 'none') ? 'block' : 'none';
});
})();