Sploop.io All Skins Unlocked

Unlocks ALL skins in the game! Select any skins you want!

安装此脚本?
作者推荐脚本

您可能也喜欢Dsync Client [Sploop.io]

安装此脚本
  1. // ==UserScript==
  2. // @name Sploop.io All Skins Unlocked
  3. // @author Murka
  4. // @description Unlocks ALL skins in the game! Select any skins you want!
  5. // @icon https://sploop.io/img/ui/favicon.png
  6. // @version 0.2
  7. // @match *://sploop.io/*
  8. // @run-at document-start
  9. // @grant none
  10. // @noframes
  11. // @license MIT
  12. // @namespace https://greasyfork.org/users/919633
  13. // ==/UserScript==
  14. /* jshint esversion:8 */
  15.  
  16. /*
  17. Author: Murka
  18. Github: https://github.com/Murka007
  19. Discord: https://discord.gg/sG9cyfGPj5
  20. Greasyfork: https://greasyfork.org/en/users/919633
  21.  
  22. Description:
  23. - Your not purchased skins will not be shown in the `SKINS` tab
  24. - You can select any skins you want by using `SHOP` tab
  25. - It is impossible to make selected skins to show everyone
  26. - Script can stop working after update, if you will have any issues, report about it in my DISCORD
  27. */
  28.  
  29. (function() {
  30. "use strict";
  31.  
  32. const log = console.log;
  33.  
  34. function createHook(target, prop, setter) {
  35. if (!window.hooks) {
  36. window.hooks = {
  37. setter: [],
  38. getter: []
  39. };
  40. }
  41. window.hooks.setter.push(setter);
  42.  
  43. const symbol = Symbol(prop);
  44. Object.defineProperty(target, prop, {
  45. get() {
  46. return this[symbol];
  47. },
  48. set(value) {
  49. for (const setter of window.hooks.setter) {
  50. setter(this, symbol, value);
  51. }
  52. },
  53. configurable: true
  54. })
  55. }
  56.  
  57. function inGame() {
  58. const homepage = document.querySelector("#homepage");
  59. return homepage && homepage.style.display !== "flex";
  60. }
  61.  
  62. function sleep(ms) {
  63. return new Promise(resolve => setTimeout(resolve, ms));
  64. }
  65.  
  66. const storage = {
  67. get(key) {
  68. const value = localStorage.getItem(key);
  69. return value === null ? null : JSON.parse(value);
  70. },
  71. set(key, value) {
  72. localStorage.setItem(key, JSON.stringify(value));
  73. }
  74. };
  75.  
  76. // it might change in the next update
  77. // jn - skin
  78. // jo - accessory
  79. // jq - back
  80.  
  81. const INDEX = {
  82. SKIN: 16,
  83. ACCESSORY: 17,
  84. BACK: 19
  85. };
  86.  
  87. const KEY = {
  88. SKIN: null,
  89. ACCESSORY: null,
  90. BACK: null
  91. };
  92.  
  93. function defineProperty(target, prop, value) {
  94. Object.defineProperty(target, prop, {
  95. get() {
  96. return value;
  97. },
  98. set() {
  99. return true;
  100. },
  101. configurable: true,
  102. writeable: false
  103. })
  104. }
  105.  
  106. // Dragon skin, Mask accessory and Dragon Wings by Default, why not?
  107. const settings = (function() {
  108. function createSettings() {
  109. const settings = {};
  110. settings.skin = 27;
  111. settings.accessory = 30;
  112. settings.back = 2;
  113. return settings;
  114. }
  115.  
  116. const defaultSettings = createSettings();
  117. const settings = Object.assign({}, defaultSettings, storage.get("selectedSkins"));
  118. for (const key in settings) {
  119. if (!defaultSettings.hasOwnProperty(key)) {
  120. delete settings[key];
  121. }
  122. }
  123.  
  124. storage.set("selectedSkins", settings);
  125. return settings;
  126. })();
  127.  
  128. const myPlayer = {
  129. id: null,
  130. data: null
  131. };
  132.  
  133. window.WebSocket = new Proxy(WebSocket, {
  134. construct(target, args) {
  135. const socket = new target(...args);
  136. socket.addEventListener("message", function(event) {
  137. try {
  138. const data = JSON.parse(event.data);
  139. if (data[0] === 35) {
  140. myPlayer.id = data[1];
  141. }
  142. } catch(err) {}
  143. })
  144. return socket;
  145. }
  146. })
  147.  
  148. function getDefault() {
  149. return {
  150. skin: storage.get("skin") || 0,
  151. accessory: storage.get("accessory") || 0,
  152. back: storage.get("back") || 0
  153. };
  154. }
  155.  
  156. createHook(Object.prototype, "i", async function(that, symbol, value) {
  157. that[symbol] = value;
  158. if (myPlayer.id === value) {
  159. myPlayer.data = that;
  160. await sleep(0);
  161.  
  162. const skinData = storage.get("selectedSkins");
  163. const Default = getDefault();
  164.  
  165. const keys = Object.keys(that);
  166. if (!KEY.SKIN) KEY.SKIN = keys[INDEX.SKIN];
  167. if (!KEY.ACCESSORY) KEY.ACCESSORY = keys[INDEX.ACCESSORY];
  168. if (!KEY.BACK) KEY.BACK = keys[INDEX.BACK];
  169.  
  170. const current = {
  171. skin: that[KEY.SKIN] || 0,
  172. accessory: that[KEY.ACCESSORY] || 0,
  173. back: that[KEY.BACK] || 0
  174. };
  175.  
  176. // Skin will not change if you are not logged into your account
  177. // And also you can't even select any skins without account, except default one
  178. defineProperty(that, KEY.SKIN, skinData.skin || Default.skin);
  179. defineProperty(that, KEY.ACCESSORY, skinData.accessory || Default.accessory);
  180. defineProperty(that, KEY.BACK, skinData.back || Default.back);
  181. }
  182. });
  183.  
  184. // We need to reset our skins on death/change server
  185. function resetSkins() {
  186. if (myPlayer.data === null) return;
  187. const { skin, accessory, back } = getDefault();
  188. defineProperty(myPlayer.data, KEY.SKIN, skin);
  189. defineProperty(myPlayer.data, KEY.ACCESSORY, accessory);
  190. defineProperty(myPlayer.data, KEY.BACK, back);
  191. }
  192.  
  193. window.addEventListener("load", function() {
  194.  
  195. const changeServer = document.querySelector("#change-server");
  196. const mainContent = document.querySelector("#main-content");
  197. const homepage = document.querySelector("#homepage");
  198.  
  199. // Attach click event handler to make users select their skins
  200. new MutationObserver(mutations => {
  201. for (const mutation of mutations) {
  202. for (const node of mutation.addedNodes) {
  203. try {
  204. if (node.classList.contains("skins-line")) {
  205. for (const button of node.children) {
  206. button.addEventListener("click", function() {
  207. const [ match, type, id ] = button.src.match(/(skin|accessory|back)(\d+)/);
  208. settings[type] = Number(id);
  209. storage.set("selectedSkins", settings);
  210. })
  211. }
  212. }
  213. } catch(err){}
  214. }
  215. }
  216. }).observe(mainContent, { childList: true, subtree: true });
  217.  
  218. // Reset myPlayer if user has changed server
  219. changeServer.addEventListener("click", resetSkins);
  220.  
  221. // Also reset if player died
  222. new MutationObserver(mutations => {
  223. for (const mutation of mutations) {
  224. if (mutation.target.style.display === "flex") {
  225. resetSkins();
  226. }
  227. }
  228. }).observe(homepage, { attributes: true, attributeFilter: ["style"] });
  229. })
  230.  
  231. })();