NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Npc times // @namespace http://tampermonkey.net/ // @version 1.7.3 // @description try to take over the world! // @author Ahab [1735214] // @include *www.torn.com/* // @require https://raw.githubusercontent.com/lostandconfused/test/master/count.js // @require https://gist.githubusercontent.com/BrockA/2625891/raw/9c97aa67ff9c5d56be34a55ad6c18a314e5eb548/waitForKeyElements.js // @require https://raw.githubusercontent.com/craftpip/jquery-confirm/master/dist/jquery-confirm.min.js // @grant GM_addStyle // @grant GM.xmlHttpRequest // @updateURL https://openuserjs.org/meta/Ahab/Npc_times.meta.js // @license MIT // ==/UserScript== var data = {} var settings = {} if(localStorage.lootTimes === undefined){ localStorage.lootTimes = JSON.stringify({}) } if(localStorage.lootSettings === undefined){ localStorage.lootSettings = JSON.stringify({'toLoot':['Duke','Leslie','Jimmy','Fernando','Tiny','Scrooge','Easter Bunny'],'soundAlert':['Duke','Leslie','Jimmy','Fernando','Tiny','Scrooge','Easter Bunny'],'min':2,'sec':40,'lootLevel':["4","5"],'showAll':0,'allLevels':0,'audioAlert':1,'timesAttack':1,'audio':'https://www.torn.com/casino/keno/audio/numberwin1.ogg','update':0,'lootState':1,'apiKey':"Add key"}) settings = JSON.parse(localStorage.lootSettings) data = {} } else{ data = JSON.parse(localStorage.lootTimes); settings = JSON.parse(localStorage.lootSettings) } var loots = ['loot_1','loot_2','loot_3','loot_4','loot_5'] var toLootback = [] var sub = 0 var audioPlayer = document.createElement('audio'); audioPlayer.src = JSON.parse(localStorage.lootSettings)['audio'] audioPlayer.preload = 'auto'; GM_addStyle(` #npcs{ border-radius: 0 0 5px 5px; line-height: 16px; margin-bottom: 10px; } #npcs a{ color: var(--default-blue-color); } #npcs td{ text-align: center; line-height: 12px; flex: 1; padding: 0 9px; color: #444; color: var(--activity-log-table-text-color); font-size: 12px; height: 25px; vertical-align: middle; border-bottom: 0px !important; } #npcs tr{ border-bottom: 0px !important; } .svg-icon{ height: 16px; float: right; margin: 7px; padding-right: 8px; } .svg-icon path, .svg-icon polygon, .svg-icon rect{ fill: #ffffff; } #error{ border-radius: 0 0 5px 5px; line-height: 16px; margin-bottom: 10px; padding: 9px; text-align: center; } .vInput::placeholder { padding: 5px; min-width: 15ch; max-width: 55ch; } .vInput[type="text"] { box-sizing: border-box; padding-left: 5px; min-width: 2ch; max-width: 55ch; } .vCheckbox{ margin-left:5px; } .vLabel{ vertical-align:text-top; } .vInput{ width:25%; margin-left:5px; border-radius:5px; height:22px; } .vButton{ margin:5px; background: transparent linear-gradient(180deg,#CCCCCC 0%,#999999 60%,#666666 100%) 0 0 no-repeat; box-sizing: border-box; border-radius: 5px; font-weight: 700; color: #333; text-shadow: 0 1px 0 #ffffff66; padding: 4px 8px; font-size: 14px; cursor: pointer; } .vButton:hover{ background: transparent linear-gradient(180deg,#E5E5E5 0%,#BBBBBB 60%,#999999 100%) 0 0 no-repeat; color: #333; } .vCon{ padding: 5px; } .vSet{ background-color: #f2f2f2; border-radius: 0 0 5px 5px; } body[class*=jconfirm-no-scroll-] { overflow: hidden !important; } .jconfirm { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 99999999; font-family: inherit; overflow: hidden; } .jconfirm .jconfirm-bg { position: fixed; top: 0; left: 0; right: 0; bottom: 0; -webkit-transition: opacity .4s; transition: opacity .4s; } .jconfirm .jconfirm-bg { position: fixed; top: 0; left: 0; right: 0; bottom: 0; -webkit-transition: opacity .4s; transition: opacity .4s; } .jconfirm .jconfirm-scrollpane { -webkit-perspective: 500px; perspective: 500px; -webkit-perspective-origin: center; perspective-origin: center; width: 100%; height: 100%; } .jconfirm .jconfirm-row { width: 100%; } .jconfirm .jconfirm-cell { display: flex; justify-content: space-around; vertical-align: middle; } .jconfirm .jconfirm-holder { max-height: 100%; padding: 50px 0; } .jconfirm .jconfirm-box-container { -webkit-transition: -webkit-transform; transition: -webkit-transform; transition: transform; transition: transform, -webkit-transform; } .jconfirm .jconfirm-box { background: white; border-radius: 4px; position: relative; outline: none; padding: 15px 15px 0; overflow: hidden; margin-left: auto; margin-right: auto; } .jconfirm .jconfirm-box .jconfirm-buttons button { display: inline-block; padding: 6px 12px; font-size: 14px; font-weight: 400; line-height: 1.42857143; text-align: center; white-space: nowrap; vertical-align: middle; -ms-touch-action: manipulation; touch-action: manipulation; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; border-radius: 4px; min-height: 1em; -webkit-transition: opacity 0.1s ease, background-color 0.1s ease, color 0.1s ease, background 0.1s ease, -webkit-box-shadow 0.1s ease; transition: opacity 0.1s ease, background-color 0.1s ease, color 0.1s ease, background 0.1s ease, -webkit-box-shadow 0.1s ease; transition: opacity 0.1s ease, background-color 0.1s ease, color 0.1s ease, box-shadow 0.1s ease, background 0.1s ease; transition: opacity 0.1s ease, background-color 0.1s ease, color 0.1s ease, box-shadow 0.1s ease, background 0.1s ease, -webkit-box-shadow 0.1s ease; -webkit-tap-highlight-color: transparent; border: none; background-image: none; } .jconfirm .jconfirm-box .jconfirm-buttons { padding-bottom: 11px; text-align: center; } .jconfirm .jconfirm-box .jconfirm-buttons > button { margin-bottom: 4px; margin-left: 2px; margin-right: 2px; } .jconfirm .jconfirm-box .jconfirm-buttons button.btn-default { background-color: #ecf0f1; color: #000; text-shadow: none; -webkit-transition: background .2s; transition: background .2s; } .jconfirm .jconfirm-box .jconfirm-buttons button.btn-default:hover { background-color: #bdc3c7; color: #000; } .jconfirm-content { text-align: center; font-size: 15px; color: #777; padding-bottom: 10px; } .jc-bs3-container{ width: max-content !important; } .jconfirm-bg { background-color: #444; opacity: .2; } `) function getLoot(){ if(sub == 0){ GM.xmlHttpRequest({ method: "GET", headers: {'Cache-Control': 'no-cache'}, url: "https://www.tornstats.com/api/v1/"+JSON.parse(localStorage.lootSettings)['apiKey']+"/loot", onload: function(response){ if(JSON.parse(response.responseText).status == false){ $($('div[class^="content-wrapper"]')[0]).prepend('<div id="timesCont" style="width:'+$('div[class^="content-wrapper"]').css( "width" )+'; margin: 0 auto;"><div id="timesTitle" class="title-black top-round">NPC Loot Times<span id="state"><svg xmlns="http://www.w3.org/2000/svg" class="svg-icon" viewBox="0 0 20 32"><path d="M16 10l-6 6-6-6-4 4 10 10 10-10-4-4z"></path></svg></span></div><div id="error" class="cont-gray">'+JSON.parse(response.responseText).message+'</div><hr id="addedd" class="page-head-delimiter m-top10 m-bottom10"></div>') }else{ settings['update'] = Date.now() localStorage.lootSettings = JSON.stringify(settings) data = JSON.parse(response.responseText); $.each(data, function(npc){ if(!isNaN(npc)){ delete Object.assign(data[npc], {['loot_1']: data[npc]['hosp_out'] })['hosp_out']; } }) localStorage.lootTimes = JSON.stringify(data) $('div[id^="timesCont"]').remove() cd() } } }) } } function disp(toDisp){ $.each(toDisp, function(index, npc){ var id = 0 var cdt = "" $('table[id^="npcs"]')[0].firstChild.insertAdjacentHTML("beforeend",'<tr id="'+data[npc]['name']+'" class="cont-gray"><td class="cont-gray"><a href="https://www.torn.com/profiles.php?XID='+data[npc]['torn_id']+'">'+data[npc]['name']+'</a></td>') $.each(loots, function(index, lootLvl){ if(JSON.parse(localStorage.lootSettings)['allLevels'] == 0){ if(JSON.parse(localStorage.lootSettings)['lootLevel'].includes(lootLvl.split('_')[1])){ id = lootLvl.split('_')[1] cdt = new Date(data[npc][lootLvl]*1000).toLocaleString(Intl.DateTimeFormat().resolvedOptions().locale, {timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone}) $('tr[id^="'+data[npc]['name']+'"]')[0].insertAdjacentHTML("beforeend",'<td data-level="'+id+'">Loot '+lootLvl.split('_')[1]+': <div data-countdown="'+cdt+'" style="display: inline;"></div></td> ') } } else if(JSON.parse(localStorage.lootSettings)['allLevels'] == 1){ id = lootLvl.split('_')[1] cdt = new Date(data[npc][lootLvl]*1000).toLocaleString(Intl.DateTimeFormat().resolvedOptions().locale, {timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone}) $('tr[id^="'+data[npc]['name']+'"]')[0].insertAdjacentHTML("beforeend",'<td data-level="'+id+'">Loot '+lootLvl.split('_')[1]+': <div data-countdown="'+cdt+'" style="display: inline;"></div></td> ') } }) }) } function cd(){ $($('div[class^="content-wrapper"]')[0]).prepend('<div id="timesCont" style="width:'+$('div[class^="content-wrapper"]').css( "width" )+'; margin: 0 auto;"><div id="timesTitle" class="title-black top-round">NPC Loot Times<span id="state"><svg xmlns="http://www.w3.org/2000/svg" class="svg-icon" viewBox="0 0 20 32"><path d="M16 10l-6 6-6-6-4 4 10 10 10-10-4-4z"></path></svg></span></div><table id="npcs" class="cont-gray" style="width:100%"><tbody></tbody></table><hr id="addedd" class="page-head-delimiter m-top10 m-bottom10"></div>') var toDisp = [] if(window.location.href.split("/")[4] == 'mymaps'){ $('div[id*="timesCont"]').css({'float': 'right'}) } if(window.location.href.split("/")[4] == 'mapeditor'){ $('div[id*="timesCont"]').css({'float': ''}) } $.each(data, function(npc){ if(JSON.parse(localStorage.lootSettings)['showAll'] == 0){ if(!isNaN(npc) && JSON.parse(localStorage.lootSettings)['toLoot'].includes(data[npc]['name'])){ toDisp.push(npc) } } else if(!isNaN(npc)){ toDisp.push(npc) } }) disp(toDisp) $('[data-countdown]').each(function() { var $this = $(this), finalDate = $(this).data('countdown'); $this.countd(finalDate, function(event) { $this.html(event.strftime('%H:%M:%S')); }).on('finish.countd', function() { $(this)[0].parentElement.remove() $($('table[id^="npcs"]')[0].children[0].childNodes).each(function() { if($(this)[0].children.length == 1){ $('tr[id^="'+$(this)[0].id+'"]')[0].insertAdjacentHTML("beforeend",'<td>Loot 5 Ready</td>') } }) }).on('update.countd', function(event) { if(event.offset.seconds == JSON.parse(localStorage.lootSettings)['sec'] && event.offset.minutes == JSON.parse(localStorage.lootSettings)['min'] && event.offset.hours == 0 && JSON.parse(localStorage.lootSettings)['soundAlert'].includes($(this)[0].parentElement.parentElement.id) && JSON.parse(localStorage.lootSettings)['lootLevel'].includes($(this)[0].parentNode.attributes[0].value) && $('div[class*="travel-agency-travelling"]').length == 0 && $('div[class*="travel-agency-market"]').length == 0 && sub == 0){ var name = $(this)[0].parentElement.parentElement.id var ll = $(this)[0].parentNode.attributes[0].value var y = $($(this)[0].parentElement.parentElement).find('a')[0].href.split('=')[1] if(JSON.parse(localStorage.lootSettings)['audioAlert'] == 1){ audioPlayer.play(); //audioPlayer.onended = function() {if(confirm(name+' Ready to attack at level '+ll)) document.location = 'https://www.torn.com/loader.php?sid=attack&user2ID='+y;} audioPlayer.onended = function() {$.confirm({ title: false, autoClose: 'Ignore|20000', content: name+' ready to attack at level '+ll, buttons: { Attack: { keys: ['enter'], action: function () {window.open('https://www.torn.com/loader.php?sid=attack&user2ID='+y) } }, Ignore: function () { }, } }); } } else{ //if(confirm(name+' Ready to attack at level '+ll)) document.location = 'https://www.torn.com/loader.php?sid=attack&user2ID='+y; $.confirm({ title: false, autoClose: 'Ignore|20000', content: name+' ready to attack at level '+ll, buttons: { Attack: { keys: ['enter'], action: function () {window.open('https://www.torn.com/loader.php?sid=attack&user2ID='+y) } }, Ignore: function () { }, } }); } } }); }); $('tr[id^="Duke"]').find('a').attr('title','Rheinmetall MG 3 (Primary)<br>Homemade Pocket Shotgun (Secondary)<br>Madball (Melee)<br>Nail Bomb (Temporary)<br>Classic Fedora<br>Pinstripe Suit Trousers<br>Duster'); $('tr[id^="Leslie"]').find('a').attr('title','Nock Gun (Primary)<br>Beretta Pico (Secondary)<br>Riding Crop (Melee)<br>Sand (Temporary)<br>Black Oxfords<br>Sweatpants<br>String Vest'); $('tr[id^="Jimmy"]').find('a').attr('title','Bread Knife (Melee)<br>Concussion Grenade (Temporary)<br>Ripped Jeans<br>Lawyer Business Card<br>Bag of Sherbert<br>Jawbreaker<br>Pixie Sticks'); $('tr[id^="Fernando"]').find('a').attr('title','Poison Umbrella (Melee)<br>Bandit Mask<br>Feathery Hotel Coupon'); $('tr[id^="Tiny"]').find('a').attr('title','Sledgehammer (Melee)<br>Energy Cans (Munster, Red Cow, Taurine)<br>Six Pack of Energy Drink<br>Dumbbells<br>Boxing Gloves'); $('tr[id^="Scrooge"]').find('a').attr('title',"Snow Cannon (Primary)<br>Diamond Icicle (Melee)<br>Snowball (Temporary)<br>Scrooge's Boots<br>Scrooge's Gloves<br>Scrooge's Hat<br>Scrooge's Topcoat<br>Scrooge's Trousers"); $('tr[id^="Easter Bunny"]').find('a').attr('title','Egg-Propelled Launcher (Primary)<br>Frying Pan (Melee)<br>Bunny Suit<br>Ski Mask<br>Bunny Nose<br>Goodie Bag<br>Rabbit Foot'); $('div[id^="timesTitle"]').on('click', function(event) { icon() }) $('table[id^="npcs"]').find('tr').on('click', function(event) { if(JSON.parse(localStorage.lootSettings)['timesAttack'] == 1){ document.location = 'https://www.torn.com/loader.php?sid=attack&user2ID='+$(this).find('a')[0].href.split('=')[1] }else{ document.location = $(this).find('a')[0].href } }) if(JSON.parse(localStorage.lootSettings)['lootState'] == 0){ icon() } } function icon(){ $('table[id*="npcs"]').toggle() if($('span[id*="state"]')[0].id == 'state'){ $('span[id*="state"]')[0].innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" class="svg-icon" viewBox="0 0 14 32"><path d="M4 6l-4 4 6 6-6 6 4 4 10-10L4 6z"></path></svg>' $('span[id*="state"]')[0].id = 'state1' settings['lootState'] = 0 localStorage.lootSettings = JSON.stringify(settings) } else{ $('span[id*="state"]')[0].innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" class="svg-icon" viewBox="0 0 20 32"><path d="M16 10l-6 6-6-6-4 4 10 10 10-10-4-4z"></path></svg>' $('span[id*="state"]')[0].id = 'state' settings['lootState'] = 1 localStorage.lootSettings = JSON.stringify(settings) } } function addSettings(){ $('div[class^="preferences-container"]').append("<div class='title-black top-round' id='settingsHead' style='margin-top: 5px;'>NPC times Settings</div>").append("<div id='settingsCont' class='vSet cont-gray'></div>") $('#settingsCont').append(` <div class="vCon"><label for="apiKey" class="vLabel"> API key</label><input type="text" id="apiKey" class="vInput"/></input></div> <div class="vCon"><label for="toLoot" class="vLabel"> NPC/s to display</label><input type="text" id="toLoot" class="vInput"/></input></div> <div class="vCon"><label for="soundAlert" class="vLabel"> NPC/s to alert on</label><input type="text" id="soundAlert" class="vInput"/></input></div> <div class="vCon"><label for="lootLevel" class="vLabel"> Levels to alert on</label><input type="text" id="lootLevel" class="vInput"/></input></div> <div class="vCon"><label for="min" class="vLabel"> Minute to alert on</label><input type="text" id="min" class="vInput"/></input></div> <div class="vCon"><label for="sec" class="vLabel"> Second to alert on</label><input type="text" id="sec" class="vInput"/></input></div> <div class="vCon"><label for="audio" class="vLabel"> Audio for alert</label><input type="text" id="audio" class="vInput"/></input></div> <div class="vCon"><label for="showAll" class="vLabel"> Show all NPCs</label><input type="checkbox" id="showAll" class="vCheckbox"></input></div> <div class="vCon"><label for="allLevels" class="vLabel"> Show all loot levels</label><input type="checkbox" id="allLevels" class="vCheckbox"></input></div> <div class="vCon"><label for="audioAlert" class="vLabel"> Audio alert</label><input type="checkbox" id="audioAlert" class="vCheckbox"></input></div> <div class="vCon"><label for="timesAttack" class="vLabel"> NPC row links to attack page</label><input type="checkbox" id="timesAttack" class="vCheckbox"></input></div> <div class="vCon"><input id="sValue" name="sLink" type="submit" class="vButton" value="Submit"></input><input id="resetSettings" name="sLink" type="submit" class="vButton" value="Reset"></input></div> `) $.each($('input[class*="vInput"]'), function(){ $(this).css('width',JSON.stringify(JSON.parse(localStorage.lootSettings)[$(this)[0].id]).replace(/\[/g, '').replace(/\]/g, '').replace(/"/g, '').length+2+'ch') $(this).val(JSON.stringify(JSON.parse(localStorage.lootSettings)[$(this)[0].id]).replace(/\[/g, '').replace(/\]/g, '').replace(/"/g, '')) }) $('input[id="min"],input[id="sec"]').keypress(function (e) { if (String.fromCharCode(e.keyCode).match(/[^0-9]/g)) return false; }) $('input[class*="vInput"]').on('input', function(){ this.style.width=this.value.length+2+'ch' if(this.id == 'apiKey' || this.id == 'sec' || this.id == 'min' || this.id == 'audio'){ if(this.id == 'apiKey' || this.id == 'audio'){ settings[this.id] = this.value localStorage.lootSettings = JSON.stringify(settings) } else{ settings[this.id] = parseInt(this.value) localStorage.lootSettings = JSON.stringify(settings) } } else if(this.id == 'toLoot' || this.id == 'soundAlert' || this.id == 'lootLevel'){ settings[this.id] = this.value.split(',') localStorage.lootSettings = JSON.stringify(settings) } }) $.each($('div[class*="vCon"] input[type*="checkbox"]'), function(){ if(JSON.parse(localStorage.lootSettings)[$(this)[0].id] == 1){ $(this).prop('checked', true) } }) $('div[class*="vCon"] input[type*="checkbox"]').on('click', function(){ if($("input[id="+$(this)[0].id+"]:checked").length == 0){ settings[$(this)[0].id] = 0 localStorage.lootSettings = JSON.stringify(settings) }else{ settings[$(this)[0].id] = 1 localStorage.lootSettings = JSON.stringify(settings) } }) $('input[id*="sValue"]').on('click', function(){ if(parseInt(JSON.parse(localStorage.lootSettings)['update'])+600000 < Date.now()){ $('div[id^="timesCont"]').remove() getLoot() loop() } else{ $('div[id^="timesCont"]').remove() cd() loop() } }) $('input[id*="resetSettings"]').on('click', function(){ localStorage.lootSettings = JSON.stringify({'toLoot':['Duke','Leslie','Jimmy','Fernando','Tiny','Scrooge','Easter Bunny'],'soundAlert':['Duke','Leslie','Jimmy','Fernando','Tiny','Scrooge','Easter Bunny'],'min':2,'sec':40,'lootLevel':["4","5"],'showAll':0,'allLevels':0,'audioAlert':1,'timesAttack':1,'audio':'https://www.torn.com/casino/keno/audio/numberwin1.ogg','update':0,'lootState':1,'apiKey':"Add key"}) }) } if(window.location.href.split('/')[3].split('.')[0] === 'preferences'){ addSettings() } function loop(){ setInterval(function(){ getLoot() }, 600000); } function start(){ if(parseInt(JSON.parse(localStorage.lootSettings)['update'])+600000 < Date.now()){ getLoot() loop() } else{ cd() loop() } } document.addEventListener('visibilitychange', function (event) { if (document.hidden) { sub = 1 } else { sub = 0 } }); waitForKeyElements("#mainContainer", start);