moPsEk - CSGO MTSL 2 MOD MENU

moPsEk for CSGO MTSL Version 2

目前为 2022-07-03 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name moPsEk - CSGO MTSL 2 MOD MENU
  3. // @namespace https://github.com/mopsfl/moPsEk
  4. // @description moPsEk for CSGO MTSL Version 2
  5. // @author mopsfl
  6. // @version 0.0.7
  7. // @license MIT
  8. // @match *://csgo.mtsl.dk/
  9. // @match *://csgo.mtsl.dk/esr/
  10. // @icon https://github.com/mopsfl/moPsEk/raw/main/assets/bulldog--v2.png%202x.png
  11. // @run-at document-start
  12. // @grant GM_setValue
  13. // @grant GM_getValue
  14. // @grant GM_setClipboard
  15. // @grant GM_download
  16. // @grant window.onurlchange
  17. // ==/UserScript==
  18.  
  19. (function () {
  20. 'use strict';
  21.  
  22. let user = {
  23. money: 240,
  24. tickets: 0,
  25. tokens: 0,
  26. xp: 0,
  27. stats: { creation: new Date().getTime() },
  28. inventory: [],
  29. upgrades: {},
  30. achievements: {},
  31. achievements_collected: {},
  32. luckyWheelWins: [],
  33. upgrades: {
  34. maxClick: null,
  35. minClick: null,
  36. passiveIncome: null,
  37. offlineIncome: null,
  38. offlineBank: null,
  39. missionGeneration: null
  40. },
  41. }, temp_inventory = []
  42.  
  43. //DATA MANAGMENT
  44. let achievements={first:{name:"First time's a charm",description:"Open your first case",requirements:[{objective:"opened_cases",amount:1}],rewards:[{type:"money",amount:210}]},case10:{name:"Getting Started",description:"Open your first 10 cases",requirements:[{objective:"opened_cases",amount:10}],rewards:[{type:"money",amount:350}]},case100:{name:"100th time's a charm",description:"Open 100 cases",requirements:[{objective:"opened_cases",amount:100}],rewards:[{type:"money",amount:1e3}]},case1000:{name:"To much freetime...",description:"Open 1000 cases",requirements:[{objective:"opened_cases",amount:1e3}],rewards:[{type:"money",amount:2500}]},unluckyoutcomes:{name:"Unlucky outcomes",description:"Open a few military specs",requirements:[{objective:"opened_rarities_2",amount:10}],rewards:[{type:"money",amount:800}]},covert:{name:"Covert",description:"Open a covert",requirements:[{objective:"opened_rarities_5",amount:1}],rewards:[{type:"money",amount:2500}]},sharpandpointy:{name:"Sharp and pointy",description:"Open a knife (or glove)",requirements:[{objective:"opened_rarities_6",amount:1}],rewards:[{type:"money",amount:500}]},sharpandpointy2:{name:"Sharp and pointy II",description:"Open 10 knives (or gloves)",requirements:[{objective:"opened_rarities_6",amount:10}],rewards:[{type:"money",amount:2500}]},sharpandpointy3:{name:"Sharp and pointy III",description:"Open 100 knives (or gloves)",requirements:[{objective:"opened_rarities_6",amount:100}],rewards:[{type:"money",amount:12500}]},sharpandpointy4:{name:"Sharp and pointy Master",description:"Open 1000 knives (or gloves)",requirements:[{objective:"opened_rarities_6",amount:1e3}],rewards:[{type:"money",amount:2e5}]},clicker1:{name:"Clicker I",description:"Click 100 times",requirements:[{objective:"clicks",amount:100}],rewards:[{type:"money",amount:1200}]},clicker2:{name:"Clicker II",description:"Click 1000 times",requirements:[{objective:"clicks",amount:1e3}],rewards:[{type:"money",amount:4e3}]},clicker3:{name:"Clicker III",description:"Click 8000 times",requirements:[{objective:"clicks",amount:8e3}],rewards:[{type:"money",amount:1e4}]},clicker4:{name:"Clicker IV",description:"Click 25000 times",requirements:[{objective:"clicks",amount:25e3}],rewards:[{type:"money",amount:25e3}]},clicker5:{name:"Clicker Master",description:"Click 100000 times",requirements:[{objective:"clicks",amount:1e5}],rewards:[{type:"money",amount:5e4}]},seller:{name:"Seller",description:"Sell your first skin",requirements:[{objective:"skin_sold",amount:1}],rewards:[{type:"money",amount:100}]},seller2:{name:"Cheapsies",description:"Sell your first 100 skins",requirements:[{objective:"skin_sold",amount:100}],rewards:[{type:"money",amount:750}]},seller3:{name:"Trusted Seller",description:"Sell 1000 skins",requirements:[{objective:"skin_sold",amount:1e3}],rewards:[{type:"money",amount:2500}]},seller4:{name:"Market Leader",description:"Sell 10000 skins",requirements:[{objective:"skin_sold",amount:1e4}],rewards:[{type:"money",amount:8e3}]},profit:{name:"Profit",description:"Sell a skin, which goes for more than 10 €",requirements:[{objective:"skin_sold_gt10",amount:1}],rewards:[{type:"money",amount:500}]},profits:{name:"Profits",description:"Sell 100 skins, where each goes for more than 10 €",requirements:[{objective:"skin_sold_gt10",amount:100}],rewards:[{type:"money",amount:5e3}]},undergrounddeals:{name:"Underground Deals",description:"Sell a covert",requirements:[{objective:"skin_sold_r5",amount:1}],rewards:[{type:"money",amount:1500}]},contraband:{name:"Contraband",description:"Sell a knife (or glove)",requirements:[{objective:"skin_sold_r6",amount:1}],rewards:[{type:"money",amount:2e3}]},gains:{name:"Gains",description:"Sell a skin, worth more than 50 €",requirements:[{objective:"skin_sold_gt50",amount:1}],rewards:[{type:"money",amount:3500}]},raresales:{name:"Rare Sales",description:"Sell a skin worth more than 250 €",requirements:[{objective:"skin_sold_gt250",amount:1}],rewards:[{type:"money",amount:6e3}]},raresales2:{name:"Rare Sales II",description:"Sell 10 skins, where each is worth more than 250 €",requirements:[{objective:"skin_sold_gt250",amount:10}],rewards:[{type:"money",amount:1e4}]},raresales3:{name:"Rare Sales Master",description:"Sell 50 skins, where each is worth more than 250 €",requirements:[{objective:"skin_sold_gt250",amount:50}],rewards:[{type:"money",amount:2e4}]},winnertakesall:{name:"Winner Takes All!",description:"Win your first jackpot",requirements:[{objective:"win_jackpot",amount:1}],rewards:[{type:"money",amount:1e3}]},winnertakesall2:{name:"Winner Takes All! II",description:"Win 5 jackpots",requirements:[{objective:"win_jackpot",amount:5}],rewards:[{type:"money",amount:2500}]},winnertakesall3:{name:"Winner Takes All! III",description:"Win 10 jackpots",requirements:[{objective:"win_jackpot",amount:10}],rewards:[{type:"money",amount:5e3}]},winnertakesall4:{name:"Winner Takes All! IV",description:"Win 25 jackpots",requirements:[{objective:"win_jackpot",amount:25}],rewards:[{type:"money",amount:1e4}]},winnertakesall5:{name:"Winner Takes All! Master",description:"Win 100 jackpots",requirements:[{objective:"win_jackpot",amount:100}],rewards:[{type:"money",amount:5e4}]},againstallodds:{name:"Against all odds",description:"Win the jackpot with an odd below 2,5%",requirements:[{objective:"win_jackpot_low",amount:1}],rewards:[{type:"money",amount:2500}]},expectedoutcome:{name:"Expected Outcome",description:"Win the jackpot with an odd over 35%",requirements:[{objective:"win_jackpot_big",amount:1}],rewards:[{type:"money",amount:1250}]},biggestloser:{name:"The Biggest Loser",description:"Lose the jackpot with an odd over 35%",requirements:[{objective:"lose_jackpot_big",amount:1}],rewards:[{type:"money",amount:2500}]},intenseroll:{name:"Intense Roll",description:"Lose the jackpot, when the indicator lands right beside you",requirements:[{objective:"lose_jackpot_close",amount:1}],rewards:[{type:"money",amount:1e3}]},worthatry:{name:"Worth a try",description:"Lose your first jackpot",requirements:[{objective:"lose_jackpot",amount:1}],rewards:[{type:"money",amount:200}]},worthatry2:{name:"Worth a try? II",description:"Lose 50 jackpots",requirements:[{objective:"lose_jackpot",amount:50}],rewards:[{type:"money",amount:2500}]},worthatry3:{name:"Worth a try III",description:"Lose 100 jackpots",requirements:[{objective:"lose_jackpot",amount:100}],rewards:[{type:"money",amount:3500}]},worthatry4:{name:"Worth a try Master",description:"Lose 200 jackpots",requirements:[{objective:"lose_jackpot",amount:200}],rewards:[{type:"money",amount:5e3}]},cashout:{name:"Cash Out I",description:"Cash out over 2x in Crash",requirements:[{objective:"cashout_2x",amount:1}],rewards:[{type:"money",amount:200}]},cashout2:{name:"Cash Out II",description:"Cash out over 3x in Crash",requirements:[{objective:"cashout_3x",amount:1}],rewards:[{type:"money",amount:400}]},cashout3:{name:"Cash Out III",description:"Cash out over 4x in Crash",requirements:[{objective:"cashout_4x",amount:1}],rewards:[{type:"money",amount:800}]},cashout4:{name:"Cash Out IV",description:"Cash out over 5x in Crash",requirements:[{objective:"cashout_5x",amount:1}],rewards:[{type:"money",amount:1600}]},cashout5:{name:"Cash Out Master",description:"Cash out over 10x in Crash",requirements:[{objective:"cashout_10x",amount:1}],rewards:[{type:"money",amount:3600}]},diamondhands:{name:"Diamond Hands",description:"Cash out over 100x in Crash",requirements:[{objective:"cashout_100x",amount:1}],rewards:[{type:"money",amount:5e4}]},regrettable:{name:"Easily Regrettable",description:"Lose your bet to a crash over 100x",requirements:[{objective:"crash_bet_100x",amount:1}],rewards:[{type:"money",amount:5e3}]},riskedit:{name:"Should have risked it",description:"Cash out under 2x in a Crash over 100x",requirements:[{objective:"crash_low_bet_100x",amount:1}],rewards:[{type:"money",amount:500}]},reachlevel1:{name:"The beginning",description:"Reach level one",requirements:[{objectiveType:"calculatedUserStat",objective:"level",amount:1}],rewards:[{type:"money",amount:800}]},reachlevel5:{name:"Getting Started",description:"Reach level five",requirements:[{objectiveType:"calculatedUserStat",objective:"level",amount:5}],rewards:[{type:"money",amount:2500}]},reachlevel10:{name:"Passioned Player",description:"Reach level ten",requirements:[{objectiveType:"calculatedUserStat",objective:"level",amount:10}],rewards:[{type:"money",amount:5e3}]},reachlevel20:{name:"Addicted Player",description:"Reach level twenty",requirements:[{objectiveType:"calculatedUserStat",objective:"level",amount:20}],rewards:[{type:"money",amount:1e4}]},reachlevel30:{name:"Getting old no?",description:"Reach level thirty",requirements:[{objectiveType:"calculatedUserStat",objective:"level",amount:30}],rewards:[{type:"money",amount:5e4}]},reachlevel40:{name:"Professionel Timekiller",description:"Reach level forty",requirements:[{objectiveType:"calculatedUserStat",objective:"level",amount:40}],rewards:[{type:"money",amount:1e5}]},wincoinflip:{name:"Great Teller",description:"Win a coinflip",requirements:[{objective:"total_coinflips_won",amount:1}],rewards:[{type:"money",amount:200}]},losecoinflip:{name:"Bad Teller",description:"Lose a coinflip",requirements:[{objective:"total_coinflips_lost",amount:1}],rewards:[{type:"money",amount:100}]},win10coinflip:{name:"So easy it's getting boring",description:"Win 10 coinflips",requirements:[{objective:"total_coinflips_won",amount:10}],rewards:[{type:"money",amount:500}]},lose10coinflip:{name:"Next time I will try CT",description:"Lose 10 coinflips",requirements:[{objective:"total_coinflips_lost",amount:10}],rewards:[{type:"money",amount:300}]},win100coinflip:{name:"Routine Flips",description:"Win 100 coinflips",requirements:[{objective:"total_coinflips_won",amount:100}],rewards:[{type:"money",amount:2500}]},lose100coinflip:{name:"But it's fun anyway",description:"Lose 100 coinflips",requirements:[{objective:"total_coinflips_lost",amount:100}],rewards:[{type:"money",amount:1500}]},win500coinflip:{name:"Master Coin Flipper",description:"Win 500 coinflips",requirements:[{objective:"total_coinflips_won",amount:500}],rewards:[{type:"money",amount:5e3}]},flipsforwhat:{name:"100 Flips for what",description:"Do 100 coinflips",requirements:[{objective:"total_coinflips",amount:100}],rewards:[{type:"money",amount:2500}]},flipathousand:{name:"Flip a thousand",description:"Do 1000 coinflips",requirements:[{objective:"total_coinflips",amount:1e3}],rewards:[{type:"money",amount:1e4}]},winmines:{name:"Bomb detector",description:"Win a game of mines",requirements:[{objective:"total_mines_won",amount:1}],rewards:[{type:"money",amount:100}]},losemines:{name:"The unlucky bomb detector",description:"Lose a game of mines, and get blown to pieces.",requirements:[{objective:"total_mines_lost",amount:1}],rewards:[{type:"money",amount:50}]},win50mines:{name:"Picked for the job",description:"Prove your bomb clearing skills, and win 50 games of mines.",requirements:[{objective:"total_mines_won",amount:50}],rewards:[{type:"money",amount:400}]},win1000mines:{name:"Bomb Master",description:"Win 1000 games of mines",requirements:[{objective:"total_mines_won",amount:1e3}],rewards:[{type:"money",amount:1e4}]},winminesmo20x:{name:"X-Ray Vision",description:"Win a game of mines, with a multiplier over 20x",requirements:[{objective:"total_mines_won_mo20",amount:1}],rewards:[{type:"money",amount:1e3}]},winminesmo20x2:{name:"Gut Feeling",description:"Win 10 games of mines, each with a multiplier over 20x",requirements:[{objective:"total_mines_won_mo20",amount:10}],rewards:[{type:"money",amount:1e4}]},winminesmo20x3:{name:"Extreme skills or luck?",description:"Win 100 games of mines, each with a multiplier over 20x",requirements:[{objective:"total_mines_won_mo20",amount:100}],rewards:[{type:"money",amount:1e5}]},bigbets:{name:"Big Bets",description:"Win a coin flip with a bet over 1000 €",requirements:[{objective:"total_coinflips_won_bet1000",amount:1}],rewards:[{type:"money",amount:1e4}]},biglosses:{name:"Big Losses",description:"Lose a coin flip with a bet over 1000 €",requirements:[{objective:"total_coinflips_lost_bet1000",amount:1}],rewards:[{type:"money",amount:2500}]},bigbets2:{name:"Biggest Bets",description:"Win a coin flip with a bet over 10000 €",requirements:[{objective:"total_coinflips_won_bet10000",amount:1}],rewards:[{type:"money",amount:8e4}]},biglosses2:{name:"Biggest Losses",description:"Lose a coin flip with a bet over 10000 €",requirements:[{objective:"total_coinflips_lost_bet10000",amount:1}],rewards:[{type:"money",amount:15e3}]},missions1:{name:"First Assignment",description:"Finish a mission",requirements:[{objective:"missions_finished",amount:1}],rewards:[{type:"money",amount:1500}]},missions2:{name:"Primary Contact",description:"Finish 20 missions",requirements:[{objective:"missions_finished",amount:10}],rewards:[{type:"money",amount:7500}]},missions3:{name:"Honest Work",description:"Finish 100 missions",requirements:[{objective:"missions_finished",amount:100}],rewards:[{type:"money",amount:15e3}]},missions4:{name:"Mission Impossible",description:"Finish 1000 missions",requirements:[{objective:"missions_finished",amount:1e3}],rewards:[{type:"money",amount:1e6}]},collector1:{name:"Beginner Collector",description:"Collect 50 skins",requirements:[{objective:"skins_discovered",amount:50}],rewards:[{type:"money",amount:400}]},collector2:{name:"Growing Collection",description:"Collect 100 skins",requirements:[{objective:"skins_discovered",amount:100}],rewards:[{type:"money",amount:1e3}]},collector3:{name:"Diverse Collector",description:"Collect 250 skins",requirements:[{objective:"skins_discovered",amount:250}],rewards:[{type:"money",amount:2e3}]},collector4:{name:"Private Collector",description:"Collect 500 skins",requirements:[{objective:"skins_discovered",amount:500}],rewards:[{type:"money",amount:5e3}]},collector5:{name:"Renown Collector",description:"Collect 750 skins",requirements:[{objective:"skins_discovered",amount:750}],rewards:[{type:"money",amount:5e4}]},collector6:{name:"The Millionaires Collection",description:"Collect 1000 skins",requirements:[{objective:"skins_discovered",amount:1e3}],rewards:[{type:"money",amount:1e5}]},collector7:{name:"The Billionaires Collection",description:"Collect 1250 skins",requirements:[{objective:"skins_discovered",amount:1250}],rewards:[{type:"money",amount:25e4}]},collector8:{name:"Near-Perfect Collection",description:"Collect 1500 skins",requirements:[{objective:"skins_discovered",amount:1500}],rewards:[{type:"money",amount:25e5}]},collection_complete:{name:"Collection Complete",description:"Collect 1635 skins",requirements:[{objective:"skins_discovered",amount:1635}],rewards:[{type:"money",amount:1e7}]}},S={"=":"0","!":"1","?":"2",$:"3","%":"4","&":"5","/":"6","\\":"7","-":"8","+":"9"},w=Object.keys(S).join(""),v={0:"=",1:"!",2:"?",3:"$",4:"%",5:"&",6:"/",7:"\\",8:"-",9:"+"};function getUser(){return JSON.parse(y(localStorage.localsave))}function f(e){return decodeURIComponent(e.split("").map((function(e){return"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)})).join(""))}function y(e){let t=[],o="";for(let n=0;n<e.length;n++){let i=e[n];i.match(/[A-Z]/)||w.includes(i)?(o+=w.includes(i)?S[i]:i.toLowerCase(),t.push(parseInt(o,36)),o=""):o+=i}let n,i={},r=String.fromCharCode(t[0]),s=r,a=[r],m=256;for(let e=1;e<t.length;e++){let o=t[e];n=o<256?String.fromCharCode(t[e]):i[o]?i[o]:s+r,a.push(n),r=n[0],i[m]=s+r,m++,s=n}return f(a.join(""))}function m(e){return encodeURIComponent(e).replace(/%([0-9A-F]{2})/g,(function(e,t){return String.fromCharCode("0x"+t)}))}function h(e){let t,o={},n=((e=m(e))+"").split(""),i=[],r=n[0],s=256;for(let e=1;e<n.length;e++)t=n[e],null!=o[r+t]?r+=t:(i.push(r.length>1?o[r]:r.charCodeAt(0)),o[r+t]=s,s++,r=t);return i.push(r.length>1?o[r]:r.charCodeAt(0)),i.map((e=>{let t=e.toString(36);return t.substring(0,t.length-1)+(t[t.length-1].match(/[0-9]/)?v[t[t.length-1]]:t[t.length-1].toUpperCase())})).join("")}function c_mmid(e){for(var t="",o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",n=o.length,i=0;i<e;i++)t+=o.charAt(Math.floor(Math.random()*n));return t}let ic=0,liit=0;var itemNames=["bravo","breakout","brokenfang","cs20","csgoweapon","csgoweapon2","csgoweapon3","falchion","fracture","gamma","horizon","huntsman","phoenix","prisma","prisma2","spectrum","spectrum2","winteroffensive","snakebite","gamma2","clutch","chroma","chroma2","chroma3","shadow","collections/assault","collections/aztec","collections/dust","collections/inferno","collections/militia","collections/nuke","collections/office","collections/vertigo","vanguard","revolver","wildfire","glove","hydra","dangerzone","shatteredweb","collections/risingsun","collections/stmarc","collections/overpass","collections/norse","collections/mirage","collections/cobblestone","collections/havoc","collections/godsandmonsters","collections/alpha","collections/ancient","collections/baggage","collections/bank","collections/cache","collections/canals","collections/chopshop","collections/control","collections/dust2","collections/dust22021","collections/inferno2018","collections/italy","collections/lake","collections/mirage2021","collections/nuke2018","collections/safehouse","collections/train","collections/train2021","collections/vertigo2021","riptide","doppler-phases/phases","esports2013","esports2013winter","esports2014summer","dreamsandnightmares"];function uuidv4(){return([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,(e=>(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16)))}
  45. let loadedAchievements = 0;
  46.  
  47. //FUNCTIONS
  48. function getSaveDataString() {
  49. const a = h(JSON.stringify(user));
  50. return a;
  51. }
  52.  
  53. function save(r) {
  54. localStorage['moPsEk_' + localStorage._moPsEk_uuid] = getSaveDataString();
  55. localStorage['moPsEk_' + localStorage._moPsEk_uuid + "_tempInv"] = JSON.stringify(temp_inventory);
  56. if (r) return location.reload();
  57. }
  58.  
  59. function log(message, color) {
  60. console.info(`%c${ message }`, `background-color:black;padding:5px;border-left:solid 4px ${ color };color:white`);
  61. }
  62.  
  63. function dlFile(e, t, n) {
  64. if (!(e ?? t ?? n)) return log('Could not create file. (Missing attr)', 'red');
  65. var d = document.createElement('a');
  66. d.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(n)), d.setAttribute('download', `${ e }.${ t }`), d.style.display = 'none', document.body.appendChild(d), d.click(), document.body.removeChild(d);
  67. }
  68.  
  69. function byteToSize(e) {
  70. var t = e;
  71. return t < 1024 ? t + 'B' : t < 1048576 ? (t / 1024).toFixed(2) + 'KB' : t < 1073741824 ? (t / 1024 * 1024).toFixed(2) + 'MB' : t < 1099511627776 ? (t / 1024 * 1024 * 1024).toFixed(2) + 'GB' : (t / 1024 * 1024 * 1024 * 1024).toFixed(2) + 'TB';
  72. }
  73.  
  74. function wipeData(){
  75. localStorage.clear()
  76. return save(true)
  77. }
  78.  
  79. function nf(msg,t,c){
  80. if(msg == null) return;
  81. let notif = document.createElement("div")
  82. let notifs = document.querySelector(".notifications")
  83. if(!(notif||notifs)) return log("Unable to create notification","red")
  84. notifs.classList.remove("hide")
  85.  
  86. notif.classList.add("notification")
  87. notif.innerHTML = `<div class="notification-message"><span style="${c?'color:'+c||'inherit':''}">${!t?"moPsEk: ":""}${msg}</span></div><div class="notification-close"></div>`
  88.  
  89. notif.querySelector(".notification-close").onclick = () => { notif.remove() }
  90.  
  91. notifs.appendChild(notif)
  92. }
  93.  
  94. function parseNumbers(string) {
  95. string = string.toString()
  96. return string.replace(/\D/gm,"")
  97. }
  98.  
  99. function setData(d){
  100. if(!d||d==null) return;
  101.  
  102. const a = {
  103. money:d.money,
  104. xp:d.xp,
  105. tokens:d.tokens,
  106. tickets:d.tickets,
  107. achievements: d.achievements,
  108. upgrades: d.upgrades,
  109. }, inv = JSON.parse(localStorage['moPsEk_' + localStorage._moPsEk_uuid + "_tempInv"])
  110.  
  111. temp_inventory = inv
  112. temp_inventory.forEach(item => {
  113. user.inventory.push(item)
  114. }); localStorage['moPsEk_' + localStorage._moPsEk_uuid + "_tempInv"] = JSON.stringify([])
  115. temp_inventory = []
  116.  
  117. Object.keys(a.achievements).forEach(achievement => {
  118. user.achievements[achievement] = true
  119. })
  120.  
  121. Object.keys(a.upgrades).forEach(upgrade => {
  122. user.upgrades[upgrade] = a.upgrades[upgrade]
  123. })
  124.  
  125. Object.keys(a).forEach(k => {
  126. if(!['money','xp','tokens','tickets'].includes(k)) return;
  127. user[k]=a[k]
  128. log(`Set ${k} to ${a[k]}`,"green")
  129. })
  130.  
  131. console.log(user, a)
  132.  
  133. /*Object.keys(a).forEach(b => {
  134. console.log(`${b} : ${a[b]}`)
  135. if(!a[b]||a[b]==null) return;
  136. user[b]=a[b]
  137. localStorage.localsave = getSaveDataString(user)
  138. })*/
  139.  
  140. localStorage.localsave = getSaveDataString(user)
  141. }
  142.  
  143. //MAIN
  144.  
  145. user = getUser();
  146.  
  147. function initMenu() {
  148. const btnClone = document.querySelector('#nav>button').cloneNode(true);
  149. const pageClone = document.querySelector('.page').cloneNode(true);
  150.  
  151. let n = document.createElement('span');
  152. n.classList.add('_tooltip')
  153. n.style = 'position: absolute;z-index: 9999;background-color: #333;border: 2px solid #555;min-width: 15px;padding: 4px;border-radius: 3px;max-width: 250px;word-break: break-word;font-family: "Roboto", sans-serif;'
  154.  
  155. document.onmousemove = t => {
  156. n.style.left = t.clientX - n.offsetWidth + 'px'
  157. n.style.top = t.clientY - n.offsetHeight + 'px'
  158. }
  159.  
  160. document.querySelector('#nav').style.overflow = "scroll"
  161. document.querySelector('#nav').style.scrollbarWidth = "none"
  162.  
  163. pageClone.classList.add('mm');
  164. pageClone.innerHTML = `
  165. <h1><img src="https://github.com/mopsfl/moPsEk/raw/main/assets/bulldog--v2.png%202x.png" style="width: 45px;height: auto;" loading="lazy"></img> moPsEk</h1>
  166. <h1 style="font-size:20px;border-bottom:solid 1px gray"><img src="https://github.com/mopsfl/moPsEk/raw/main/assets/icons8-wrench-100.png" style="width: 17px;height: auto;" loading="lazy"></img> General <span style="font-size:10px; color: #888">Too high values can result in a bugged display. (But still counts)</span></h1>
  167. <div class="upgrade">
  168. <div class="upgrade-title">Set Money<span data-info='Will refresh your page!' style="position: absolute;height: 15px;width: 15px;background: #333;border-radius: 1ex;margin-left: 5px;padding: 1px;"><img style="width: 100%;height: auto;/*! text-align: center;" src='https://raw.githubusercontent.com/mopsfl/moPsEk/main/assets/icons8-exclamation-mark-90.png' alt='!'></img></span></div>
  169. <div class="upgrade-desc">Changes your current money.</div>
  170. <div style="position: absolute;top: 14px;right: 0;">
  171. <button class="button" style="float: right;position: static;" data-mm_sm>Set</button><input class="input" placeholder="Money" style="float: right;" data-mm_smi>
  172. </div>
  173. </div>
  174. <div class="upgrade">
  175. <div class="upgrade-title">Set XP<span data-info='Will refresh your page!' style="position: absolute;height: 15px;width: 15px;background: #333;border-radius: 1ex;margin-left: 5px;padding: 1px;"><img style="width: 100%;height: auto;/*! text-align: center;" src='https://raw.githubusercontent.com/mopsfl/moPsEk/main/assets/icons8-exclamation-mark-90.png' alt='!'></img></span></div>
  176. <div class="upgrade-desc">Changes your current XP.</div>
  177. <div style="position: absolute;top: 14px;right: 0;">
  178. <button class="button" style="float: right;position: static;" data-mm_sxp>Set</button><input class="input" placeholder="XP" style="float: right;" data-mm_sxpi>
  179. </div>
  180. </div>
  181. <div class="upgrade">
  182. <div class="upgrade-title">Set Tokens<span data-info='Will refresh your page!' style="position: absolute;height: 15px;width: 15px;background: #333;border-radius: 1ex;margin-left: 5px;padding: 1px;"><img style="width: 100%;height: auto;/*! text-align: center;" src='https://raw.githubusercontent.com/mopsfl/moPsEk/main/assets/icons8-exclamation-mark-90.png' alt='!'></img></span></div>
  183. <div class="upgrade-desc">Changes your current tokens.</div>
  184. <div style="position: absolute;top: 14px;right: 0;">
  185. <button class="button" style="float: right;position: static;" data-mm_stks>Set</button><input class="input" placeholder="Tokens" style="float: right;" data-mm_stksi>
  186. </div>
  187. </div>
  188. <div class="upgrade">
  189. <div class="upgrade-title">Set Tickets<span data-info='Will refresh your page!' style="position: absolute;height: 15px;width: 15px;background: #333;border-radius: 1ex;margin-left: 5px;padding: 1px;"><img style="width: 100%;height: auto;/*! text-align: center;" src='https://raw.githubusercontent.com/mopsfl/moPsEk/main/assets/icons8-exclamation-mark-90.png' alt='!'></img></span></div>
  190. <div class="upgrade-desc">Changes your tickets.</div>
  191. <div style="position: absolute;top: 14px;right: 0;">
  192. <button class="button" style="float: right;position: static;" data-mm_stk>Set</button><input class="input" placeholder="Tickets" style="float: right;" data-mm_stki>
  193. </div>
  194. </div>
  195. <div class="upgrade">
  196. <div class="upgrade-title">Set Money per Click<span data-info='Will refresh your page!' style="position: absolute;height: 15px;width: 15px;background: #333;border-radius: 1ex;margin-left: 5px;padding: 1px;"><img style="width: 100%;height: auto;/*! text-align: center;" src='https://raw.githubusercontent.com/mopsfl/moPsEk/main/assets/icons8-exclamation-mark-90.png' alt='!'></img></span></div>
  197. <div class="upgrade-desc">Changes the amount of money you get per click.</div>
  198. <div style="position: absolute;top: 14px;right: 0;">
  199. <button class="button" style="float: right;position: static;" data-mm_mpc>Set</button><input class="input" placeholder="Min" style="float: right;" data-mm_mpcmi><input class="input" placeholder="Max" style="float: right;" data-mm_mpcxi>
  200. </div>
  201. </div>
  202. <div class="upgrade">
  203. <div class="upgrade-title">Set Passive income <span data-info='Will refresh your page!' style="position: absolute;height: 15px;width: 15px;background: #333;border-radius: 1ex;margin-left: 5px;padding: 1px;"><img style="width: 100%;height: auto;/*! text-align: center;" src='https://raw.githubusercontent.com/mopsfl/moPsEk/main/assets/icons8-exclamation-mark-90.png' alt='!'></img></span></div>
  204. <div class="upgrade-desc">Unlocks and finishes all achievements.</div>
  205. <div style="position: absolute;top: 14px;right: 0;">
  206. <button class="button" style="float: right;position: static;" data-mm_spin>Set</button><input class="input" placeholder="Passive Income" style="float: right;" data-mm_pini>
  207. </div>
  208. </div>
  209. <div class="upgrade">
  210. <div class="upgrade-title">Set Offline income <span data-info='Will refresh your page!' style="position: absolute;height: 15px;width: 15px;background: #333;border-radius: 1ex;margin-left: 5px;padding: 1px;"><img style="width: 100%;height: auto;/*! text-align: center;" src='https://raw.githubusercontent.com/mopsfl/moPsEk/main/assets/icons8-exclamation-mark-90.png' alt='!'></img></span></div>
  211. <div class="upgrade-desc">Changes the amount of the offline income.</div>
  212. <div style="position: absolute;top: 14px;right: 0;">
  213. <button class="button" style="float: right;position: static;" data-mm_soin>Set</button><input class="input" placeholder="Offline Income" style="float: right;" data-mm_oini>
  214. </div>
  215. </div>
  216. <div class="upgrade">
  217. <div class="upgrade-title">Give all items<span data-info='Will refresh your page & might cause lags or slow down the page.' style="position: absolute;height: 15px;width: 15px;background: #333;border-radius: 1ex;margin-left: 5px;padding: 1px;"><img style="width: 100%;height: auto;/*! text-align: center;" src='https://raw.githubusercontent.com/mopsfl/moPsEk/main/assets/icons8-exclamation-mark-90.png' alt='!'></img></span></div>
  218. <div class="upgrade-desc">Gives you every item (Knives, Skins, Cases, ...).</div>
  219. <div style="position: absolute;top: 14px;right: 0;">
  220. <button class="button" style="float: right;position: static;" data-mm_gait>Give</button>
  221. </div>
  222. </div>
  223. <div class="upgrade">
  224. <div class="upgrade-title">Give all achievements <span data-info='Will refresh your page!' style="position: absolute;height: 15px;width: 15px;background: #333;border-radius: 1ex;margin-left: 5px;padding: 1px;"><img style="width: 100%;height: auto;/*! text-align: center;" src='https://raw.githubusercontent.com/mopsfl/moPsEk/main/assets/icons8-exclamation-mark-90.png' alt='!'></img></span></div>
  225. <div class="upgrade-desc">Unlocks and finishes all achievements.</div>
  226. <div style="position: absolute;top: 14px;right: 0;">
  227. <button class="button" style="float: right;position: static;" data-mm_gaac>Give</button>
  228. </div>
  229. </div>
  230. <h1 style="font-size:20px;border-bottom:solid 1px gray"><img src="https://github.com/mopsfl/moPsEk/raw/main/assets/icons8-cloud-folder-90.png" style="width: 17px;height: auto;" loading="lazy"></img> Data Managment</h1>
  231. <div class="upgrade">
  232. <div class="upgrade-title">Export Data</div>
  233. <div class="upgrade-desc">Export your current client data.</div>
  234. <div style="position: absolute;top: 14px;right: 0;">
  235. <button class="button" style="float: right;position: static;" data-mm_excd_en>Encoded</button>
  236. <button class="button" style="float: right;position: static;" data-mm_excd_rw>Raw</button>
  237. </div>
  238. </div>
  239. <div class="upgrade">
  240. <div class="upgrade-title">Import Data</div>
  241. <div class="upgrade-desc">Import your saved client data.</div>
  242. <div style="position: absolute;top: 14px;right: 0;">
  243. <button class="button" style="float: right;position: static;" data-mm_imd_en>Import</button>
  244. </div>
  245. </div>
  246. <div class="upgrade">
  247. <div class="upgrade-title">Create backup</div>
  248. <div class="upgrade-desc">Creates a backup of your current data.</div>
  249. <div style="position: absolute;top: 14px;right: 0;">
  250. <button class="button" style="float: right;position: static;" data-mm_cbup>Create</button>
  251. </div>
  252. </div>
  253. <div class="upgrade">
  254. <div class="upgrade-title">Load backup</div>
  255. <div class="upgrade-desc">Loads your recent created backup.</div>
  256. <div style="position: absolute;top: 14px;right: 0;">
  257. <button class="button" style="float: right;position: static;" data-mm_delbup>Load</button>
  258. </div>
  259. </div>
  260. <div class="upgrade">
  261. <div class="upgrade-title">Wipe Data <span data-info='Will open/close seperate tabs! Be sure popups are allowed. If it doesnt work, do it again.' style="position: absolute;height: 15px;width: 15px;background: #333;border-radius: 1ex;margin-left: 5px;padding: 1px;"><img style="width: 100%;height: auto;/*! text-align: center;" src='https://raw.githubusercontent.com/mopsfl/moPsEk/main/assets/icons8-exclamation-mark-90.png' alt='!'></img></span></div>
  262. <div class="upgrade-desc">Wipes all your game data.</div>
  263. <div style="position: absolute;top: 14px;right: 0;">
  264. <button class="button red" style="float: right;position: static;" data-mm_wipd>Wipe</button>
  265. </div>
  266. </div>
  267. <h1 style="font-size:20px;border-bottom:solid 1px gray"><img src="https://github.com/mopsfl/moPsEk/raw/main/assets/bulldog--v2.png%202x.png" style="width: 17px;height: auto;" loading="lazy"></img> moPsEk</h1>
  268. <div class="upgrade">
  269. <p class="upgrade-desc">Script Version<span style="float:right">v.${GM_info.script.version}</span></p>
  270. </div>
  271. <div class="upgrade">
  272. <p class="upgrade-desc">Author <span style="float:right; user-select:text">${GM_info.script.author}</span></p>
  273. </div>
  274. <div class="upgrade">
  275. <p class="upgrade-desc">Automatic Update<span style="float:right; user-select:text">${GM_info.script.options.check_for_updates == true ? "Yes" : "No" }</span></p>
  276. </div>
  277. <div class="upgrade">
  278. <p class="upgrade-desc">Client UUID <span style="float:right; user-select:text">${localStorage._moPsEk_uuid}</span></p>
  279. </div>
  280. `;
  281.  
  282. document.querySelector('#nav').appendChild(btnClone);
  283. document.querySelector('#pages').appendChild(pageClone);
  284. btnClone.innerHTML = '<img src="https://github.com/mopsfl/moPsEk/raw/main/assets/bulldog--v2.png%202x.png"></img> moPsEk';
  285. btnClone.onclick = () => {
  286. document.querySelectorAll('.page').forEach(e => e.classList.remove('show'));
  287. pageClone.classList.add('show');
  288. };
  289.  
  290. pageClone.querySelectorAll('[data-info]').forEach(t => {
  291. const e = t.attributes['data-info'].nodeValue;
  292. t.onmouseenter = t => {
  293. document.body.appendChild(n)
  294. n.innerText = e;
  295. }
  296. t.onmouseleave = t => {
  297. document.body.removeChild(n)
  298. n.innerText = '';
  299. };
  300. });
  301.  
  302. //OPTIONS
  303. const options = {
  304. setMoney: {
  305. input: document.querySelector('[data-mm_smi]'),
  306. btn: document.querySelector('[data-mm_sm]')
  307. },
  308. setXP: {
  309. input: document.querySelector('[data-mm_sxpi]'),
  310. btn: document.querySelector('[data-mm_sxp]')
  311. },
  312. setTokens: {
  313. input: document.querySelector('[data-mm_stksi]'),
  314. btn: document.querySelector('[data-mm_stks]')
  315. },
  316. setTickets: {
  317. input: document.querySelector('[data-mm_stki]'),
  318. btn: document.querySelector('[data-mm_stk]')
  319. },
  320. giveAllItems: {
  321. btn: document.querySelector('[data-mm_gait]')
  322. },
  323. exportData: {
  324. btn: document.querySelector('[data-mm_excd_en]'),
  325. btn2: document.querySelector('[data-mm_excd_rw]'),
  326. },
  327. importData: {
  328. btn: document.querySelector('[data-mm_imd_en]'),
  329. },
  330. wipeData: {
  331. btn: document.querySelector('[data-mm_wipd]'),
  332. },
  333. createBackup: {
  334. btn: document.querySelector('[data-mm_cbup]'),
  335. },
  336. loadBackup: {
  337. btn: document.querySelector('[data-mm_delbup]'),
  338. },
  339. giveAllAchievements: {
  340. btn: document.querySelector('[data-mm_gaac]')
  341. },
  342. setMoneyPerClick: {
  343. btn: document.querySelector('[data-mm_mpc]'),
  344. min: document.querySelector('[data-mm_mpcmi]'),
  345. max: document.querySelector('[data-mm_mpcxi]'),
  346. },
  347. setPassiveIncome: {
  348. btn: document.querySelector('[data-mm_spin]'),
  349. input: document.querySelector('[data-mm_pini]'),
  350. },
  351. setOfflineIncome: {
  352. btn: document.querySelector('[data-mm_soin]'),
  353. input: document.querySelector('[data-mm_oini]'),
  354. }
  355. };
  356.  
  357. //SET MONEY
  358. options.setMoney.btn.onclick = () => {
  359. if (!isNaN(options.setMoney.input) || options.setMoney.input == '') return;
  360. const value = parseInt(options.setMoney.input.value) * 100;
  361. const valid = parseNumbers(value)!='' ? true : false
  362. if(!valid){
  363. log("Unable to parse numbers for min|max","red")
  364. nf("This input is invalid.",null,"red")
  365. return
  366. };
  367. user.money = value;
  368. log(`Set money to ${ value }.`, 'green');
  369. return save(true);
  370. };
  371.  
  372. //SET XP
  373. options.setXP.btn.onclick = () => {
  374. const value = parseInt(options.setXP.input.value.replace(/\D/g,''));
  375. const valid = parseNumbers(value)!='' ? true : false
  376. if(!valid){
  377. log("Unable to parse numbers for min|max","red")
  378. nf("This input is invalid.",null,"red")
  379. return
  380. };
  381. user.xp = value;
  382. log(`Set xp to ${ value }.`, 'green');
  383. return save(true);
  384. };
  385.  
  386. //SET TOKENS
  387. options.setTokens.btn.onclick = () => {
  388. const value = parseInt(options.setTokens.input.value.replace(/\D/g,''));
  389. const valid = parseNumbers(value)!='' ? true : false
  390. if(!valid){
  391. log("Unable to parse numbers for min|max","red")
  392. nf("This input is invalid.",null,"red")
  393. return
  394. };
  395. user.tokens = value;
  396. log(`Set tokens to ${ value }.`, 'green');
  397. return save(true);
  398. };
  399.  
  400. //SET TICKETS
  401. options.setTickets.btn.onclick = () => {
  402. const value = parseInt(options.setTickets.input.value.replace(/\D/g,''));
  403. const valid = parseNumbers(value)!='' ? true : false
  404. if(!valid){
  405. log("Unable to parse numbers for min|max","red")
  406. nf("This input is invalid.",null,"red")
  407. return
  408. };
  409. user.tickets = value;
  410. log(`Set tickets to ${ value }.`, 'green');
  411. return save(true);
  412. };
  413.  
  414. //GIVE ALL ITEMS
  415. options.giveAllItems.btn.onclick = () => {
  416. ic=0
  417. liit = 0;
  418. nf("Fetching all packages. This may take a few seconds. (Page will refresh after It's finished)")
  419. itemNames.forEach(name => {
  420. ++ic;
  421. fetch(`https://csgo.mtsl.dk/data/items/${name}.json?v=15`).then(res => res.json()).then(data => {
  422. ++liit;
  423. Object.keys(data).forEach(async item => {
  424. await temp_inventory.push(item)
  425. })
  426. log(`Fetching package : '${name}'.`, "yellow")
  427. if(liit == itemNames.length){
  428. log(`Successfully fetched all packages.`, "green")
  429. nf("Successfully fetched all packages.")
  430. save(true)
  431. }
  432. })
  433. })
  434.  
  435. log(`Fetching ${ic} packages.`, "yellow")
  436. };
  437.  
  438. //EXPORT DATA
  439. options.exportData.btn.onclick = () => {
  440. const data = getSaveDataString(getUser())
  441. if(!data) return log("Unable to encode current client data", "red");
  442.  
  443. return dlFile(`mtslData_${localStorage._moPsEk_uuid}.encoded`, "txt", data)
  444. };
  445. options.exportData.btn2.onclick = () => {
  446. const data = getUser()
  447. if(!data) {
  448. log("Unable to get current client data", "red");
  449. nf(`Unable to get current client data.`,null,"red")
  450. return
  451. }
  452.  
  453. return dlFile(`mtslData_${localStorage._moPsEk_uuid}.raw`, "txt", JSON.stringify(data,null,2))
  454. };
  455.  
  456. //IMPORT DATA
  457. options.importData.btn.onclick = () => {
  458. var input = document.createElement('input');
  459. input.type = 'file';
  460. input.click();
  461.  
  462. input.onchange = (e) => {
  463. var reader = new FileReader();
  464. var file = input.files[0]
  465.  
  466. reader.onload = function(){
  467. var text = reader.result
  468. if(!text) return log(`Unable to get file text from '${file.name}'`, "red")
  469. console.log(text)
  470. console.log(file)
  471. log(`Loaded file '${input.files[0].name}' with an size of ${byteToSize(file.size)}`,"green")
  472.  
  473. try {
  474. let json = JSON.parse(text);
  475. user = json
  476. log("Imported raw data.", "green")
  477. nf(`Data imported sucessfully!`)
  478. save(true)
  479. } catch(e){
  480. try {
  481. let json = JSON.parse(y(text))
  482. user = json
  483. log("Imported encoded data.", "green")
  484. nf(`Data imported sucessfully!`)
  485. save(true)
  486. } catch(e){
  487. log("Unable to decode data file.", "red")
  488. nf(`Unable to decode data file!`,null,"red")
  489. }
  490. }
  491. };
  492. reader.readAsText(file);
  493. }
  494. };
  495.  
  496. //WIPE DATA
  497. options.wipeData.btn.onclick = () => {
  498. window.open("/esr")
  499. window.close()
  500. GM_setValue(`moPsEk.wipeData`, true)
  501. }
  502.  
  503. //CREATE BACKUP
  504. options.createBackup.btn.onclick = () => {
  505. const data = getSaveDataString(getUser())
  506. if(!data) return log("Unable to get current local data", "red")
  507.  
  508. GM_setValue(`moPsEk_${localStorage._moPsEk_uuid}.backup`, data)
  509. nf(`Sucessfully created local backup.`)
  510. return log("Sucessfully created local backup.","green")
  511. }
  512.  
  513. //LOAD BACKUP
  514. options.loadBackup.btn.onclick = () => {
  515. const data = GM_getValue(`moPsEk_${localStorage._moPsEk_uuid}.backup`)
  516. if(!data) return log("Unable to get current backup data", "red")
  517.  
  518. localStorage['moPsEk_' + localStorage._moPsEk_uuid] = data;
  519.  
  520. nf(`Sucessfully loaded local backup!`)
  521. log("Sucessfully loaded local backup.","green")
  522. return save(true)
  523. }
  524.  
  525. //GIVE ALL ACHIEVMENTS
  526. options.giveAllAchievements.btn.onclick = () => {
  527. loadedAchievements = 0;
  528. const data = getSaveDataString(getUser())
  529. if(!data) return log("Unable to get current local data", "red")
  530.  
  531. nf("Loading all achievements. (Page will refresh after It's finished)")
  532. log(`Loading ${Object.keys(achievements).length} achievements.`,"yellow")
  533. console.log(Object.keys(achievements))
  534.  
  535. Object.keys(achievements).forEach(achievement => {
  536. ++loadedAchievements;
  537. log(achievement,"yellow")
  538. user.achievements[achievement] = true
  539. if(loadedAchievements == Object.keys(achievements).length){
  540. nf("All achievements given successfully.")
  541. log("All achievements loaded successfully.","green")
  542. console.log(user)
  543. save(true)
  544. }
  545. })
  546. }
  547.  
  548. //MONEY PER CLICK
  549. options.setMoneyPerClick.btn.onclick = () => {
  550. const data = getSaveDataString(getUser())
  551. if(!data) return log("Unable to get current local data", "red")
  552. let min = options.setMoneyPerClick.min.value.replace(/\D/g,'')
  553. let max = options.setMoneyPerClick.max.value.replace(/\D/g,'')
  554. //const valid = parseInt(Number(min)??Number(max)) ? true : false
  555. const valid = (parseNumbers(min)||parseNumbers(max))!='' ? true : false
  556. if(!valid){
  557. log("Unable to parse numbers for min|max","red")
  558. nf("This input is invalid.",null,"red")
  559. return
  560. };
  561. log(`Set clicks per second to [${min} - ${min}]`, "green")
  562.  
  563. user.upgrades.minClick = parseInt(min)*100
  564. user.upgrades.maxClick = parseInt(max)*100
  565. return save(true)
  566. }
  567.  
  568. //SET PASSIVE INCOME
  569. options.setPassiveIncome.btn.onclick = () => {
  570. const data = getSaveDataString(getUser())
  571. if(!data) return log("Unable to get current local data", "red")
  572. let value = options.setPassiveIncome.input.value.replace(/\D/g,'')
  573. const valid = parseNumbers(value)!='' ? true : false
  574. if(!valid){
  575. log("Unable to parse numbers for min|max","red")
  576. nf("This input is invalid.",null,"red")
  577. return
  578. };
  579. log(`Set passive income to [${value}]`, "green")
  580.  
  581. user.upgrades.passiveIncome = parseInt(value)*100
  582. return save(true)
  583. }
  584.  
  585. options.setOfflineIncome.btn.onclick = (e) => {
  586. const data = getSaveDataString(getUser())
  587. if(!data) return log("Unable to get current local data", "red")
  588. let value = options.setOfflineIncome.input.value.replace(/\D/g,'')
  589. const valid = parseNumbers(value)!='' ? true : false
  590. if(!valid){
  591. log("Unable to parse numbers for offlineIncome","red")
  592. nf("This input is invalid.",null,"red")
  593. return
  594. };
  595. log(`Set offline income to [${value}]`, "green")
  596.  
  597. user.upgrades.offlineIncome = parseInt(value)*100
  598. return save(true)
  599. }
  600.  
  601. //OTHER
  602. log(`moPsEk v.${GM_info.script.version} initalized sucessfully! Client UUID : ${localStorage._moPsEk_uuid}`, 'green');
  603. nf(`moPsEk v.${GM_info.script.version} initalized sucessfully!`,true)
  604. }
  605.  
  606. if(GM_getValue(`moPsEk.wipeData`) == true){
  607. localStorage.clear()
  608. window.open("https://csgo.mtsl.dk/")
  609. GM_setValue(`moPsEk.wipeData`, false)
  610. window.close()
  611. }
  612.  
  613. //SETUP
  614. try {
  615. log(`Initalizing moPsEk v.${GM_info.script.version}`, 'yellow');
  616. if (!localStorage.getItem('_moPsEk_uuid')) {
  617. localStorage.setItem('_moPsEk_uuid', uuidv4());
  618. log('moPsEk client uuid created sucessfully!', 'green');
  619. }
  620. if (!localStorage.getItem('moPsEk_' + localStorage._moPsEk_uuid)) {
  621. localStorage.setItem('moPsEk_' + localStorage._moPsEk_uuid, getSaveDataString(getUser()));
  622. log('moPsEk client savedata created sucessfully!', 'green');
  623. }
  624. if(!localStorage['moPsEk_' + localStorage._moPsEk_uuid + "_tempInv"]){
  625. localStorage['moPsEk_' + localStorage._moPsEk_uuid + "_tempInv"] = JSON.stringify([])
  626. }
  627. //localStorage.localsave = localStorage['moPsEk_' + localStorage._moPsEk_uuid];
  628. setData(JSON.parse(y(localStorage['moPsEk_' + localStorage._moPsEk_uuid])))
  629.  
  630. window.onload = () => {
  631. initMenu()
  632. fetch("https://raw.githubusercontent.com/mopsfl/moPsEk/main/games/csgo.mtsl.dk/compatible_versions.json")
  633. .then(res => res.json())
  634. .then(data => {
  635. let game_version = document.querySelector("#version-version").innerText
  636.  
  637. if(!data.compatible_versions.includes(game_version)){
  638. log("This game version might not be fully compatible with moPsEk.", "red")
  639. alert("moPsEk Info\n\nThis game version might not be fully compatible with moPsEk.\nBe sure it's up to date!")
  640. } else log(`Game Version '${game_version}' compatible!`, 'green');
  641.  
  642. if(GM_info.script.options.run_at != "document-start"){
  643. GM_setClipboard("// @run-at document-start")
  644. alert("moPsEk Info\n\n@run-at is not set to 'document-start'\nThis might cause the mod menu to not work correctly.\n\nAdd the string in your clipboard to the script.")
  645. }
  646. })
  647. };
  648. } catch(e){
  649. log("Unable to load moPsEk","red")
  650. log(e, "red")
  651. }
  652. }());