- // ==UserScript==
- // @name Sploop.io All Skins Unlocked
- // @author Murka
- // @description Unlocks ALL skins in the game! Select any skins you want!
- // @icon https://sploop.io/img/ui/favicon.png
- // @version 0.2
- // @match *://sploop.io/*
- // @run-at document-start
- // @grant none
- // @noframes
- // @license MIT
- // @namespace https://greasyfork.org/users/919633
- // ==/UserScript==
- /* jshint esversion:8 */
-
- /*
- Author: Murka
- Github: https://github.com/Murka007
- Discord: https://discord.gg/sG9cyfGPj5
- Greasyfork: https://greasyfork.org/en/users/919633
-
- Description:
- - Your not purchased skins will not be shown in the `SKINS` tab
- - You can select any skins you want by using `SHOP` tab
- - It is impossible to make selected skins to show everyone
- - Script can stop working after update, if you will have any issues, report about it in my DISCORD
- */
-
- (function() {
- "use strict";
-
- const log = console.log;
-
- function createHook(target, prop, setter) {
- if (!window.hooks) {
- window.hooks = {
- setter: [],
- getter: []
- };
- }
- window.hooks.setter.push(setter);
-
- const symbol = Symbol(prop);
- Object.defineProperty(target, prop, {
- get() {
- return this[symbol];
- },
- set(value) {
- for (const setter of window.hooks.setter) {
- setter(this, symbol, value);
- }
- },
- configurable: true
- })
- }
-
- function inGame() {
- const homepage = document.querySelector("#homepage");
- return homepage && homepage.style.display !== "flex";
- }
-
- function sleep(ms) {
- return new Promise(resolve => setTimeout(resolve, ms));
- }
-
- const storage = {
- get(key) {
- const value = localStorage.getItem(key);
- return value === null ? null : JSON.parse(value);
- },
- set(key, value) {
- localStorage.setItem(key, JSON.stringify(value));
- }
- };
-
- // it might change in the next update
- // jn - skin
- // jo - accessory
- // jq - back
-
- const INDEX = {
- SKIN: 16,
- ACCESSORY: 17,
- BACK: 19
- };
-
- const KEY = {
- SKIN: null,
- ACCESSORY: null,
- BACK: null
- };
-
- function defineProperty(target, prop, value) {
- Object.defineProperty(target, prop, {
- get() {
- return value;
- },
- set() {
- return true;
- },
- configurable: true,
- writeable: false
- })
- }
-
- // Dragon skin, Mask accessory and Dragon Wings by Default, why not?
- const settings = (function() {
- function createSettings() {
- const settings = {};
- settings.skin = 27;
- settings.accessory = 30;
- settings.back = 2;
- return settings;
- }
-
- const defaultSettings = createSettings();
- const settings = Object.assign({}, defaultSettings, storage.get("selectedSkins"));
- for (const key in settings) {
- if (!defaultSettings.hasOwnProperty(key)) {
- delete settings[key];
- }
- }
-
- storage.set("selectedSkins", settings);
- return settings;
- })();
-
- const myPlayer = {
- id: null,
- data: null
- };
-
- window.WebSocket = new Proxy(WebSocket, {
- construct(target, args) {
- const socket = new target(...args);
- socket.addEventListener("message", function(event) {
- try {
- const data = JSON.parse(event.data);
- if (data[0] === 35) {
- myPlayer.id = data[1];
- }
- } catch(err) {}
- })
- return socket;
- }
- })
-
- function getDefault() {
- return {
- skin: storage.get("skin") || 0,
- accessory: storage.get("accessory") || 0,
- back: storage.get("back") || 0
- };
- }
-
- createHook(Object.prototype, "i", async function(that, symbol, value) {
- that[symbol] = value;
- if (myPlayer.id === value) {
- myPlayer.data = that;
- await sleep(0);
-
- const skinData = storage.get("selectedSkins");
- const Default = getDefault();
-
- const keys = Object.keys(that);
- if (!KEY.SKIN) KEY.SKIN = keys[INDEX.SKIN];
- if (!KEY.ACCESSORY) KEY.ACCESSORY = keys[INDEX.ACCESSORY];
- if (!KEY.BACK) KEY.BACK = keys[INDEX.BACK];
-
- const current = {
- skin: that[KEY.SKIN] || 0,
- accessory: that[KEY.ACCESSORY] || 0,
- back: that[KEY.BACK] || 0
- };
-
- // Skin will not change if you are not logged into your account
- // And also you can't even select any skins without account, except default one
- defineProperty(that, KEY.SKIN, skinData.skin || Default.skin);
- defineProperty(that, KEY.ACCESSORY, skinData.accessory || Default.accessory);
- defineProperty(that, KEY.BACK, skinData.back || Default.back);
- }
- });
-
- // We need to reset our skins on death/change server
- function resetSkins() {
- if (myPlayer.data === null) return;
- const { skin, accessory, back } = getDefault();
- defineProperty(myPlayer.data, KEY.SKIN, skin);
- defineProperty(myPlayer.data, KEY.ACCESSORY, accessory);
- defineProperty(myPlayer.data, KEY.BACK, back);
- }
-
- window.addEventListener("load", function() {
-
- const changeServer = document.querySelector("#change-server");
- const mainContent = document.querySelector("#main-content");
- const homepage = document.querySelector("#homepage");
-
- // Attach click event handler to make users select their skins
- new MutationObserver(mutations => {
- for (const mutation of mutations) {
- for (const node of mutation.addedNodes) {
- try {
- if (node.classList.contains("skins-line")) {
- for (const button of node.children) {
- button.addEventListener("click", function() {
- const [ match, type, id ] = button.src.match(/(skin|accessory|back)(\d+)/);
- settings[type] = Number(id);
- storage.set("selectedSkins", settings);
- })
- }
- }
- } catch(err){}
- }
- }
- }).observe(mainContent, { childList: true, subtree: true });
-
- // Reset myPlayer if user has changed server
- changeServer.addEventListener("click", resetSkins);
-
- // Also reset if player died
- new MutationObserver(mutations => {
- for (const mutation of mutations) {
- if (mutation.target.style.display === "flex") {
- resetSkins();
- }
- }
- }).observe(homepage, { attributes: true, attributeFilter: ["style"] });
- })
-
- })();