// ==UserScript==
// @name Bubble.am+
// @namespace https://discord.gg/p56aQHNU9U
// @version 1.0
// @description Modyfikacja, która dodaje wiele przydatnych funkcji do gry
// @author DD7
// @require https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.min.js
// @match *://bubble.am/*
// @run-at document-start
// @grant none
// ==/UserScript==
const modName = 'plus';
if((location.host === 'bubble.am' && location.pathname === '/') || location.pathname.length > 10) {
window.stop();
document.documentElement.innerHTML = "";
location.href = `http://bubble.am/${modName}${location.hash}`;
}
window.customColor = false;
window.transparentMines = false;
window.noGrid = false;
window.macro = false;
const getColorValue = getCookie("cellsColor");
if(getColorValue === null) setCookie("cellsColor", "rgba(31, 95, 255, 1)", 30);
window.cellsColor = getColorValue;
let splitInterval = null;
let splitSwitch = false;
const keys = {
q: false,
a: false,
s: false,
d: false
}
const styles = `
body.dark-mode ::-webkit-scrollbar {
width: 5px;
height: 5px;
}
body.dark-mode ::-webkit-scrollbar-button {
width: 0px;
height: 0px;
}
body.dark-mode ::-webkit-scrollbar-thumb {
background: #38a2ff;
border: 0px none #ffffff;
border-radius: 50px;
}
body.dark-mode ::-webkit-scrollbar-thumb:hover {
background: #0082f4;
}
body.dark-mode ::-webkit-scrollbar-thumb:active {
background: #005fb2;
}
body.dark-mode ::-webkit-scrollbar-track {
background: #505050;
border: 0px none #ffffff;
border-radius: 50px;
}
body.dark-mode ::-webkit-scrollbar-track:hover {
background: #505050;
}
body.dark-mode ::-webkit-scrollbar-track:active {
background: #505050;
}
body.dark-mode ::-webkit-scrollbar-corner {
background: transparent;
}
body.dark-mode {
color: #EDEDED !important;
}
body.dark-mode .main-panel {
color: #EDEDED !important;
background: #111111;
}
body.dark-mode .form-control {
color: #fff !important;
background: #222222;
border: none !important;
}
body.dark-mode #radio_mode .gm-s {
background: #222222;
border: 1px solid #555555;
}
body.dark-mode .bb-panel {
background: #111111;
}
body.dark-mode .btn-primary {
background-color: #3884FF;
border: none;
}
body.dark-mode .btn-primary:hover {
background-color: #0055DE;
}
body.dark-mode .btn-success {
background-color: #5DFF38;
border: none;
}
body.dark-mode .btn-success:hover {
background-color: #29DE00;
}
body.dark-mode .btn-settings {
background-color: #38B6FF;
border: none;
height: auto;
}
body.dark-mode .btn-settings:hover {
background-color: #008DDE;
}
body.dark-mode .btn-warning {
background-color: #FF9838;
border: none;
}
body.dark-mode .btn-warning:hover {
background-color: #DE6B00;
}
body.dark-mode .btn-danger {
background-color: #FF3838;
border: none;
}
body.dark-mode .btn-danger:hover {
background-color: #DE0000;
}
body.dark-mode .friends-online {
background: #111111;
}
body.dark-mode .bub-table-list {
border: 1px solid #333333;
}
body.dark-mode .table-striped>tbody>tr:nth-child(odd) {
background-color: #161616;
}
body.dark-mode .table-striped>tbody>tr:nth-child(even) {
background-color: #111111 !important;
}
body.dark-mode .table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td {
border: none;
}
body.dark-mode .dropdown-menu {
background: #111111 !important;
}
body.dark-mode .dropdown-menu>li>a {
color: #EDEDED;
}
body.dark-mode .dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus {
color: #EDEDED;
background: #222222;
}
body.dark-mode .table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th {
background: #C89D00 !important;
}
body.dark-mode .nav-tabs>li.active>a, .nav-tabs>li.active>a:hover, .nav-tabs>li.active>a:focus {
color: #EDEDED;
background: #222222;
border: 1px solid transparent;
}
body.dark-mode .nav>li>a:hover, .nav>li>a:focus {
color: #EDEDED;
background: #222222;
border: 1px solid transparent;
}
body.dark-mode .modal-content {
background: #111111;
}
body.dark-mode .panel-default {
border: 1px solid #555555;
}
body.dark-mode .panel-default>.panel-heading {
background: #111111;
border: none;
}
body.dark-mode #tournament-modal .panel-body {
background: #222222;
}
body.dark-mode .tright {
color: #EDEDED;
}
body.dark-mode .modeinfo {
color: #385DFF;
}
body.dark-mode #battle_chat {
background: #111111;
color: #EDEDED;
}
body.dark-mode .close {
color: #EDEDED;
opacity: 1;
}
body.dark-mode #connecting div {
background: #111111 !important;
}
`
function getCookie(name) {
let v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
return v ? v[2] : null;
}
function setCookie(name, value, days) {
const d = new Date;
d.setTime(d.getTime() + 24*60*60*1000*days);
document.cookie = name + "=" + value + ";path=/;expires=" + d.toGMTString();
}
function addStyle(styleString) {
const style = document.createElement("style");
style.textContent = styleString;
document.head.append(style);
}
function getModConfig(cookie) {
cookie = cookie || "mod";
var config = $.cookie(cookie);
if (typeof (config) != "undefined") {
config = atob(config);
return $.parseJSON(config);
}
return false;
}
function setModConfig(option, value, cookie, expires, path) {
if (typeof (option) == "undefined" || typeof (value) == "undefined") {
return false;
}
cookie = cookie || "mod";
expires = expires || 356;
path = path || '/';
config = getModConfig(cookie);
if (config) {
config[option] = value;
} else {
config = {};
config[option] = value;
}
config = JSON.stringify(config);
config = btoa(config);
$.cookie(cookie, config, {
expires: expires,
path: path
});
return true;
}
function restoreModConfig() {
const modConfig = getModConfig();
if(modConfig) {
for(let prop in modConfig) {
if(modConfig.hasOwnProperty(prop)) $("#mod_" + prop).prop("checked", modConfig[prop]).change();
}
}
}
window.setCustomColor = function(a) {
window.customColor = a;
a === true ? $("#colorPanel").show() : $("#colorPanel").hide()
setModConfig("CustomColor", a);
}
window.setTransparentMines = function(a) {
window.transparentMines = a;
setModConfig("TransparentMines", a);
}
window.setNoGrid = function(a) {
window.noGrid = a;
setModConfig("NoGrid", a);
}
window.setMacro = function(a) {
window.macro = a;
setModConfig("Macro", a);
}
window.setDarkMenu = function(a) {
window.darkMenu = a;
a === true ? $("body").addClass("dark-mode") : $("body").removeClass("dark-mode")
setModConfig("DarkMenu", a);
}
function modifyCore(core) {
core = core.replace(/(.*)(m\.color)(.*)/, `
$&
if(h.length > 0 && m.name === h[0].name && !m.f && cellsColor !== undefined && cellsColor !== null && window.customColor === true) {
m.color = window.cellsColor;
}
`)
core = core.replace(/(bb\s\?)(.*)/, `
if(bb) {
a.fillStyle = "#FFFFFF";
a.strokeStyle = "#AAAAAA";
if(this.f && window.transparentMines === true) a.globalAlpha = 0.2;
} else {
a.fillStyle = this.color;
a.strokeStyle = this.color;
if(this.f && window.transparentMines === true) a.globalAlpha = 0.2;
}
`);
core = core.replace(/(.*)(var\sa\s=\sl\s\/\sg)(.+)(\n.*\n.*)/gm, `
if(window.noGrid === false) {
$&
}
`);
return core;
}
function split(times) {
for(let i = 0; i < times; i++) {
setTimeout(function() {
$("body").trigger($.Event("keydown", { keyCode: 32 }));
$("body").trigger($.Event("keyup", { keyCode: 32 }));
}, 50 * i);
}
}
function goTo(x, y) {
x = window.innerWidth / x; y = window.innerHeight / y;
$("canvas").trigger($.Event("mousemove", {clientX: x, clientY: y}));
}
function keydown(e) {
const chat = document.querySelector("#chat_textbox");
if(chat === document.activeElement || !window.macro) return;
const key = e.key;
keys[key] = true;
switch(key) {
case "Shift":
if(splitSwitch) break;
splitSwitch = true;
splitInterval = setInterval(() => {
$("body").trigger($.Event("keydown", { keyCode: 32 }));
$("body").trigger($.Event("keyup", { keyCode: 32 }));
}, 4);
break;
case "1":
split(1);
break;
case "2":
split(2);
break;
case "3":
split(3);
break;
case "4":
split(4);
break;
case "5":
split(5);
break;
case "q":
goTo(3, -0);
break;
case "a":
goTo(-0, 8);
break;
case "s":
goTo(2, 0.6);
break;
case "d":
goTo(0, 5);
break;
}
switch(true) {
case keys["a"] && keys["q"]:
goTo(-0, -0);
break;
case keys["a"] && keys["s"]:
goTo(-0, 0);
break;
case keys["q"] && keys["d"]:
goTo(0, -0);
break;
case keys["s"] && keys["d"]:
goTo(0, 0);
break;
}
}
function keyup(e) {
const chat = document.querySelector("#chat_textbox");
if(chat === document.activeElement || !window.macro) return;
const key = e.key;
keys[e.key] = false;
switch(key) {
case "Shift":
clearInterval(splitInterval);
splitSwitch = false;
break;
}
}
function initMacro() {
document.addEventListener("keydown", keydown);
document.addEventListener("keyup", keyup);
}
function initUI() {
$("#formStd h2").html("Bubble.am+");
$(".settings_checkboxes").append(`
<label>
<input id="mod_Macro" type="checkbox" onchange="setMacro($(this).is(':checked'));"> Makro
</label>
<label>
<input id="mod_TransparentMines" type="checkbox" onchange="setTransparentMines($(this).is(':checked'));"> Przezroczyste miny
</label>
<label>
<input id="mod_NoGrid" type="checkbox" onchange="setNoGrid($(this).is(':checked'));"> Bez siatki
</label>
<label>
<input id="mod_CustomColor" type="checkbox" onchange="setCustomColor($(this).is(':checked'));"> Niestandardowy kolor kulki
</label>
<label>
<input id="mod_DarkMenu" type="checkbox" onchange="setDarkMenu($(this).is(':checked'));"> Ciemna wersja menu
</label>
`);
}
function initStyles() {
addStyle(styles);
$("head").append("<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/nano.min.css'/>");
}
function initColorPicker() {
$('.settings_checkboxes').after(`<div id="colorPanel" style="display: none;"><p style="float: left; line-height: 2.6rem; margin-right: 0.8rem;">Wybierz swój kolor: </p> <div id="colorMod"></div></div>`);
const pickr = Pickr.create({
el: "#colorMod",
theme: "nano",
container: "body",
swatches: null,
default: cellsColor,
components: {
preview: true,
opacity: false,
hue: true,
interaction: {
hex: true,
rgba: true,
hsla: false,
hsva: false,
cmyk: false,
input: true,
clear: false,
save: true
}
}
});
pickr.on("save", (color, instance) => {
cellsColor = color.toRGBA().toString(3);
setCookie("cellsColor", cellsColor);
}).on("change", (color, instance) => {
setCookie("cellsColor", cellsColor);
});
}
function init() {
initMacro();
initUI();
initStyles();
initColorPicker();
}
const request = new XMLHttpRequest();
const url = "http://bubble.am";
request.open("get", url, true);
request.send();
request.onload = function(e) {
const newCore = modifyCore(this.responseText);
document.open();
document.write(newCore);
document.close();
window.onload = function() {
init();
restoreModConfig();
}
}
console.log("Created by DD7");