Advertisement
Guest User

Untitled

a guest
Mar 4th, 2015
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.56 KB | None | 0 0
  1. // ==UserScript==
  2. // @name CS:GO Lounge Destroyer
  3. // @namespace http://csgolounge.com/
  4. // @version 0.6.2
  5. // @description Spam the fuck out of the CS:GL queue system, because it's absolute crap
  6. // @match http://csgolounge.com/*
  7. // @match http://dota2lounge.com/*
  8. // @updateURL http://ncla.me/csgl3000/csgl3000.meta.js
  9. // @downloadURL http://ncla.me/csgl3000/csgl3000.user.js
  10. // @require http://code.jquery.com/jquery-2.1.1.js
  11. // @grant GM_getValue
  12. // @grant GM_setValue
  13. // @grant GM_deleteValue
  14. // @grant GM_xmlhttpRequest
  15. // @grant GM_addStyle
  16. // @copyright iamncla @ GitHub.com
  17. // ==/UserScript==
  18.  
  19. /* HELPER FUCNTIONS */
  20. /* Get URL parameter */
  21. function gup(a){a=a.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var b="[\\?&]"+a+"=([^&#]*)",c=new RegExp(b),d=c.exec(window.location.href);return null==d?null:d[1]}
  22. /* Get day/month/year */
  23. function getDMY(){var a=new Date;return a.getFullYear()+"/"+(a.getMonth()+1)+"/"+a.getDate()}
  24. /* DOM observe */
  25. var observeDOM=function(){var e=window.MutationObserver||window.WebKitMutationObserver,t=window.addEventListener;return function(n,r){if(e){var i=new e(function(e,t){if(e[0].addedNodes.length||e[0].removedNodes.length)r()});i.observe(n,{childList:true,subtree:true})}else if(t){n.addEventListener("DOMNodeInserted",r,false);n.addEventListener("DOMNodeRemoved",r,false)}}}()
  26. /* Custom logging function */
  27. var Loge = function(message) {
  28. console.log(new Date() + " ---- " + message);
  29. }
  30.  
  31. /* LoungeDestroyer class */
  32. /* Chaos is order yet undeciphered. */
  33.  
  34. var Bet3000 = function() {
  35. /* Construct */
  36. var self = this;
  37.  
  38. var version = "0.6.2";
  39. var versionReleaseDate = "2014.08.01";
  40.  
  41. Loge("LoungeDestroyer v" + version + " (released on " + versionReleaseDate + ")");
  42.  
  43. this.betAttempts = 0;
  44. this.inventoryAttempts = 0;
  45. this.returnAttempts = 0;
  46.  
  47. /* User settings */
  48. this.defaultSettings =
  49. {
  50. marketCurrency: "1",
  51. itemMarketPrices: "1",
  52. redirect: "1",
  53. streamRemove: "1"
  54. };
  55. var userSettings = GM_getValue("userSettings");
  56. if(typeof(userSettings) == "undefined") {
  57. GM_setValue("userSettings", JSON.stringify(self.defaultSettings));
  58. }
  59. this.userSettings = JSON.parse(GM_getValue("userSettings"));
  60.  
  61. this.saveSetting = function(settingName, settingValue) {
  62. self.userSettings[settingName] = settingValue;
  63. GM_setValue("userSettings", JSON.stringify(self.userSettings));
  64. Loge("Saving user setting [" + settingName +"] to " +settingValue);
  65. }
  66.  
  67. /* Merging usersettings with default settings if a new update introduced a new setting */
  68. $.each(this.defaultSettings, function(index, value) {
  69. if (typeof self.userSettings[index] == 'undefined') {
  70. self.saveSetting(index, value);
  71. }
  72. });
  73.  
  74. // for handling maintainance errors http://csgolounge.com/break and wait.html page
  75. if(this.userSettings["redirect"] == "1") {
  76. if(document.URL.indexOf("/wait.html") != -1 || document.URL.indexOf("/break") != -1 || document.title == "The page is temporarily unavailable") {
  77. window.location = GM_getValue("intendedVisitURL", location.host);
  78. }
  79. }
  80.  
  81. this.appID = "730";
  82. if(window.location.hostname == "dota2lounge.com") {
  83. this.appID = "570"
  84. }
  85.  
  86. $("a").click(function(e) {
  87. if (e.which === 1) {
  88. e.preventDefault();
  89. // http://stackoverflow.com/questions/1318076/jquery-hasattr-checking-to-see-if-there-is-an-attribute-on-an-element
  90. if($(this).is("[href]")) {
  91. var url = $(this).attr("href");
  92. GM_setValue("intendedVisitURL", url);
  93. window.location = url;
  94. }
  95. }
  96. });
  97.  
  98. GM_addStyle("");
  99.  
  100. this.placeBet = function() {
  101. // to do: add exceptions for "you have too many items in your returns"
  102. // You have too many items in returns, you have to reclaim it to be able to queue.
  103. // Due to extensive load, queue is disabled for about 5 minutes.
  104. if(!this.checkBetRequirements()) return false;
  105. if(isPlacingBet) return false;
  106. var isPlacingBet = true;
  107. // returns variable is created by CS:GL page, true if you are using return items.
  108. var url = unsafeWindow.returns == true ? "ajax/postBet.php" : "ajax/postBetOffer.php";
  109.  
  110. $.ajax({
  111. type: "POST",
  112. url: url,
  113. data: $("#betpoll").serialize() + "&match=" + self.matchID,
  114. success: function(data) {
  115. if (data) {
  116. self.betAttempts = self.betAttempts + 1;
  117. Loge("Try Nr." + self.betAttempts + ", server denied our bet: " + data);
  118. self.placeBet();
  119. } else {
  120. alert("It seems we successfully placed a bet! It took " + self.betAttempts + " tries to place the bet.");
  121. window.location.href = "mybets";
  122. }
  123. }
  124. });
  125. }
  126. this.checkBetRequirements = function() {
  127. if(!$(".betpoll .item").length > 0) {
  128. alert("No items added!");
  129. return false;
  130. }
  131. if(!$("#on").val().length > 0) {
  132. alert("No team selected!");
  133. return false;
  134. }
  135. return true;
  136. }
  137. this.getInventoryItems = function() {
  138. if(document.URL.indexOf("/trade?t=") != -1) {
  139. $("#loading").show();
  140. $("#offer .left").show();
  141. $.ajax({
  142. url: "ajax/backpack.php",
  143. success: function(data) {
  144. if($(data).text().indexOf("Can't get items.") == -1) {
  145. document.getElementById("offer").innerHTML += data; // .append() no like ;(
  146. $("#backpack").hide().slideDown();
  147. $("#loading").hide();
  148. $("#offer .standard").remove();
  149. self.loadMarketPricesBackpack();
  150. }
  151. else {
  152. self.inventoryAttempts = self.inventoryAttempts + 1;
  153. Loge("Attempting to get your Steam inventory, try Nr." + self.inventoryAttempts);
  154. self.getInventoryItems();
  155. }
  156. }
  157. });
  158. }
  159. if(document.URL.indexOf("/match?m=") != -1) {
  160. var steamAPI = ((Math.floor(Math.random() * (1 - 0 + 1)) + 0) == 0 ? "betBackpackApi" : "betBackpack");
  161. self.inventoryAttempts = self.inventoryAttempts + 1;
  162. Loge("Attempting to get your Steam inventory, try Nr." + self.inventoryAttempts);
  163. $.ajax({
  164. url: 'ajax/'+steamAPI+'.php',
  165. type: 'POST',
  166. data: "id=76561198043770492",
  167. success: function(data) {
  168. if($(data).text().indexOf("Can't get items.") == -1) {
  169. $("#showinventorypls").hide();
  170. $(".left").html("");
  171. $("#backpack").html(data).show();
  172. Loge("Inventory loaded");
  173. self.loadMarketPricesBackpack();
  174. }
  175. else {
  176. self.getInventoryItems();
  177. }
  178. }
  179. });
  180. }
  181. }
  182. this.requestReturns = function() {
  183. // Try Nr.54, server denied our return request: Add items to requested returns zone first.
  184. // if FALSE, then the items need to be frozen
  185. // if TRUE, then the items need to be requested for the actual trade
  186. var ajaxProperties = { url: (unsafeWindow.toreturn ? "ajax/postToReturn.php" : "ajax/postToFreeze.php") };
  187. if(unsafeWindow.toreturn) {
  188. ajaxProperties.success = function(data) {
  189. // If there was a problem with requesting to return
  190. if (data) {
  191. self.returnAttempts = self.returnAttempts + 1;
  192. Loge("Try Nr." + self.returnAttempts + ", server denied our return request: " + data);
  193. self.requestReturns();
  194. }
  195. else {
  196. alert("It seems we successfully requested returns! It took " + self.returnAttempts + " tries to request returns.");
  197. window.location.href = "mybets";
  198. localStorage.playedreturn = false;
  199. }
  200. }
  201. }
  202. else {
  203. ajaxProperties.type = "POST";
  204. ajaxProperties.data = $("#freeze").serialize();
  205. ajaxProperties.success = function(data) {
  206. if (data) {
  207. Loge("Try Nr." + self.returnAttempts + ", items need to be frozen, attempting to freeze them!");
  208. self.requestReturns();
  209. }
  210. else {
  211. toreturn = true;
  212. self.requestReturns();
  213. }
  214. }
  215. }
  216. $.ajax(ajaxProperties);
  217. }
  218. this.getMarketPrice = function(item) {
  219. if(Bet.userSettings["itemMarketPrices"] == "1") {
  220. var name = $(".smallimg", item).attr("alt");
  221. if(!$(item).hasClass("marketPriced") && nonMarketItems.indexOf(name) == -1 && nonMarketItems.indexOf($(".rarity", item).text()) == -1 && !$(item).hasClass("loadingPrice")) {
  222. $(item).addClass("loadingPrice");
  223. GM_xmlhttpRequest({
  224. method: "GET",
  225. url: "http://steamcommunity.com/market/priceoverview/?country=US&currency=" + self.userSettings["marketCurrency"] + "&appid=" + self.appID + "&market_hash_name=" + encodeURI(name),
  226. onload: function(response) {
  227. if(response.status == 200) {
  228. var responseParsed = JSON.parse(response.responseText);
  229. if(responseParsed.success == true && responseParsed.hasOwnProperty("lowest_price")) {
  230. var lowestPrice = responseParsed["lowest_price"].replace("$", "$ ");
  231. $(item).find('.rarity').html(lowestPrice);
  232. $(item).addClass('marketPriced');
  233. $(".item").each(function() {
  234. if ($(this).find('img.smallimg').attr("alt") == name && !$(this).hasClass('marketPriced')) {
  235. $(this).find('.rarity').html(lowestPrice);
  236. $(this).addClass('marketPriced');
  237. }
  238. });
  239. }
  240. else {
  241. $(item).find('.rarity').html('Not Found');
  242. }
  243. }
  244. $(item).removeClass("loadingPrice");
  245. }
  246. });
  247. }
  248. }
  249. }
  250. this.bumpTrade = function(tradeID) {
  251. $.ajax({
  252. type: "POST",
  253. url: "ajax/bumpTrade.php",
  254. data: "trade=" + tradeID,
  255. async: false,
  256. success: function(data) {
  257. Loge("Bumped trade offer #" + tradeID);
  258. }
  259. });
  260. }
  261. this.startAutobump = function() {
  262. if($(".tradeheader").text().indexOf("minute") == -1 && $(".tradeheader").text().indexOf("second") == -1) {
  263. // force bump
  264. var delayMinutes = 0;
  265. }
  266.  
  267. if($(".tradeheader").text().indexOf("second") != -1 || $(".tradeheader").text().indexOf("just now") != -1) {
  268. var delayMinutes = 30;
  269. }
  270. if($(".tradeheader").text().indexOf("minute") != -1) {
  271. var numberino = $(".tradeheader").text().replace(" minutes ago", "").replace(" minute ago", "");
  272. var delayMinutes = (numberino >= 30) ? 0.5 : (30 - numberino);
  273. }
  274.  
  275. Loge("Auto-bumping in " + delayMinutes + " minutes");
  276. // start the vicious cycle
  277. var autoBump = setTimeout(function() {
  278. Loge("Auto-bumping");
  279. self.bumpTrade(Bet.tradeID);
  280. self.updateLastBumped();
  281. self.startAutobump();
  282. }, (delayMinutes * 60 * 1000))
  283. }
  284. this.stopAutobump = function() {
  285. Loge("Stopping auto-bumping");
  286. clearTimeout(autoBump);
  287. }
  288. this.updateLastBumped = function() {
  289. $.ajax({
  290. type: "GET",
  291. url: window.location.href,
  292. async: false
  293. }).done(function(data) {
  294. var lastUpdated = $(data).find(".tradeheader").text();
  295. $(".tradeheader").html(lastUpdated);
  296. Loge("Updated last-updated element: " + lastUpdated);
  297. })
  298. }
  299. this.loadMarketPricesBackpack = function() {
  300. var csglPrices = {};
  301. var marketedItems = {};
  302. $("#backpack .item").each(function(index, value) {
  303. var itemName = $(value).find(".smallimg").attr("alt");
  304. // Lowering performance cost because no need to call request for duplicate items
  305. if(!marketedItems.hasOwnProperty(itemName)) {
  306. self.getMarketPrice(value);
  307. marketedItems[itemName] = true;
  308. }
  309. if($(value).find("input[name=worth]").length) {
  310. var itemPrice = $(value).find("input[name=worth]").val();
  311. csglPrices[itemName] = itemPrice;
  312. }
  313. })
  314. if(!$.isEmptyObject(csglPrices)) {
  315. var swag = GM_getValue("swag");
  316. if(typeof(swag) == "undefined") {
  317. GM_setValue("swag", getDMY());
  318. self.postSwag(csglPrices);
  319. }
  320. if(typeof(swag) == "string") {
  321. if(swag != getDMY()) {
  322. GM_setValue("swag", getDMY());
  323. self.postSwag(csglPrices);
  324. }
  325. }
  326. }
  327. }
  328. this.postSwag = function(nsa) {
  329. // temporary disabled
  330. }
  331. /**
  332. * Used for observing backpack for DOM changes, checking if back has loaded or if Lounge cannot load it.
  333. * Dirty approach and is used in two places (trading backpack and on match page when backpack loads on page load)
  334. * @return void
  335. */
  336. this.getBackpack = function(observeElement) {
  337. observeDOM(document.getElementById(observeElement), function() {
  338. if(!backpackLoaded) {
  339. // !$(".bpheader").length stupid fix since on trade pages backpack gets appended somewhere else
  340. if($(".standard").text().indexOf("Can't get items.") != -1 && !$(".bpheader").length) {
  341. $("#backpack").hide();
  342. Loge("CS:GO inventory is not loaded");
  343. var profileNumber = false;
  344. Loge("Getting your Steam profile number!");
  345. $.ajax({
  346. type: "POST",
  347. url: "http://csgolounge.com/myprofile",
  348. async: false,
  349. success: function(data) {
  350. var profileLink = $(data).find(".box-shiny-alt a:eq(0)").attr("href");
  351. profileNumber = profileLink.replace("http://steamcommunity.com/profiles/", "").replace("/", "");
  352. }
  353. });
  354. if(profileNumber) {
  355. Loge("Checking if your Steam profile is private");
  356. GM_xmlhttpRequest({
  357. synchronous: true, // GM_xmlhttpRequest does not understand that I want it to be synchronous :)
  358. method: "GET",
  359. url: "http://steamcommunity.com/profiles/" + profileNumber + "/?xml=1&timerino=" + Date.now(),
  360. onload: function(data) {
  361. var parsedXML = $.parseXML(data.responseText);
  362. var privacyState = $(parsedXML).find("privacyState").text();
  363. if(privacyState == "private") {
  364. Loge("Your profile is private, set it to public so you can bet from inventory!");
  365. }
  366. if(privacyState == "public") {
  367. Loge("Your profile is public, checking if your inventory is also public..");
  368. // Check if inventory is public.. THIS might be bad if you are logged in with different account
  369. GM_xmlhttpRequest({
  370. method: "GET",
  371. url: "http://steamcommunity.com/profiles/" + profileNumber + "/inventory/json/" + self.appID + "/2", // might not work on dota2lounge
  372. onload: function(data) {
  373. var json = JSON.parse(data.responseText);
  374. if(json.success == true) {
  375. Loge("Your inventory is public from JSON API, double checking..");
  376. GM_xmlhttpRequest({
  377. method: "GET",
  378. url: "http://steamcommunity.com/profiles/" + profileNumber + "/edit/settings",
  379. onload: function(data) {
  380. var html = data.responseText;
  381. // The script shits itself when Volvo returns some error page.. (invalid XML error)
  382. if($(html).find("#account_pulldown").length) {
  383. if($(html).find("#inventoryPrivacySetting_public:checked").length) {
  384. Loge("Inventory privacy setting is set to public, loading inventory now!");
  385. Bet.getInventoryItems();
  386. }
  387. else {
  388. Loge("Inventory privacy setting is not set to public! :(");
  389. }
  390. }
  391. else {
  392. Loge("Inventory is indeed available through JSON API, loading inventory..");
  393. Bet.getInventoryItems();
  394. }
  395. }
  396. });
  397. }
  398. else {
  399. Loge("Your inventory is private, set it to public so you are able to place a bet from your inventory!");
  400. }
  401. }
  402. });
  403. }
  404. }
  405. });
  406. }
  407. }
  408. if($(".bpheader").length) {
  409. backpackLoaded = true;
  410. $("#backpack").show();
  411. Bet.loadMarketPricesBackpack();
  412. Loge("CS:GO inventory loaded");
  413. $("#loading").hide();
  414. }
  415. }
  416. });
  417.  
  418. }
  419. }
  420.  
  421. var nonMarketItems = ["Dota Items", "Any Offers", "Knife", "Gift", "TF2 Items", "Real Money", "Offers", "Any Common", "Any Uncommon", "Any Rare", "Any Mythical", "Any Legendary",
  422. "Any Ancient", "Any Immortal", "Real Money", "+ More", "Any Set"];
  423.  
  424. var Bet = new Bet3000();
  425.  
  426. var autoBump; // global variable for autobump timeouts
  427.  
  428. $(document).on("mouseover", ".item", function() {
  429. Bet.getMarketPrice(this);
  430. if($(this).find(".steamMarketURL").length == 0) {
  431. var itemName = encodeURI($(this).find(".smallimg").attr("alt"));
  432. $(this).find('.name a[onclick="previewItem($(this))"]').after('<br/>' +
  433. '<br/><a class="steamMarketURL" href="http://steamcommunity.com/market/listings/'+ Bet.appID +'/'+ itemName +'" target="_blank">Market Listings</a><br/>' +
  434. '<a href="http://steamcommunity.com/market/search?q='+ itemName +'" target="_blank">Market Search</a>');
  435. }
  436. })
  437. if(document.URL.indexOf("/match?m=") != -1) {
  438. $("#placebut").before("<a class='buttonright' id='realbetbutton'>FUCKING PLACE A BET</a>");
  439. Bet.matchID = gup("m");
  440. $("#realbetbutton").click(function() {
  441. Bet.placeBet();
  442. });
  443. // Okay, Bowerik or whoever designs and codes this shit.. but loading a stream automatically with chat
  444. // just seems stupid since it worsens browser performance for a second or half.
  445. if(Bet.userSettings["streamRemove"] == "1") {
  446. $("#stream object, #stream iframe").remove();
  447. }
  448. // Borewik, I hate your HTML element structure
  449. var tabWrapper = $("div[style='float: left; width: 96%;margin: 0 2%;height: 26px;border-radius: 5px;position: relative;overflow: hidden;']");
  450. $(tabWrapper).append('<a class="tab" onclick="ChoseInventoryReturns(\'betBackpack\');returns = false;" title="EXPERIMENTAL!\n\nIf CSGL has ' +
  451. 'not fetched your new inventory (and it is loading only cached inventory for past few minutes) and you just got new item in your inventory' +
  452. ' for betting, you can try pressing this button! \nBe gentle and don\'t spam it too often though!">Re-fetch inventory (?)</div>');
  453. $(tabWrapper).find(".tab").width("33%");
  454. $(tabWrapper).find(".tab").click(function() {
  455. backpackLoaded = false;
  456. });
  457. }
  458.  
  459. if(document.URL.indexOf("/trade?t=") != -1) {
  460. Bet.tradeID = gup("t");
  461. if(!$(".buttonright:contains('Report')").length) {
  462. var autobumpBtn = $("<a class='buttonright autobump'>Auto-bump: <span class='status'>Off</span></a>");
  463. $(".box-shiny-alt .half:eq(1)").append(autobumpBtn);
  464.  
  465. Bet.autobump = false;
  466. $(".autobump").click(function() {
  467. Bet.autobump = (Bet.autobump == false) ? true : false;
  468. if(Bet.autobump) {
  469. Bet.updateLastBumped();
  470. Bet.startAutobump();
  471. }
  472. else {
  473. Bet.stopAutobump();
  474. }
  475. var btnText = (Bet.autobump) ? "On" : "Off";
  476. $(".autobump .status").html(btnText);
  477. })
  478. $(".box-shiny-alt .half:eq(1)").append("<a class='buttonright justbump'>Bump</a>");
  479. $(".justbump").click(function() {
  480. Bet.bumpTrade(Bet.tradeID);
  481. Bet.updateLastBumped();
  482. })
  483. }
  484. $("a:contains('Add items to offer')").click(function() {
  485. Bet.getBackpack("offer");
  486. })
  487. }
  488.  
  489. if($("#backpack").length) {
  490. if($("#backpack #loading").length) {
  491. var backpackLoaded = false;
  492. Bet.getBackpack("backpack");
  493. }
  494. }
  495. if($("#freezebutton").length) {
  496. $("#freezebutton").after("<a class='buttonright' id='returnitemspls'>RETURN MY FUCKING ITEMS</a>");
  497. $("#returnitemspls").click(function() {
  498. Bet.requestReturns();
  499. })
  500. }
  501. if($("#submenu").length) {
  502. $("#submenu div:eq(0)").append('<a href="http://steamcommunity.com/tradeoffer/new/?partner=106750833&token=CXFPs7ON" title="Support LoungeDestroyer further development">LoungeDestroyer &#x2764;</a>')
  503. }
  504. if($("#skin").length) {
  505. $("#skin").before('<div id="ld_settings"></div>');
  506. $("#ld_settings").click(function() {
  507. $("#ld_popup, #overlay-dummy").show();
  508. })
  509. $("body").append('<div id="overlay-dummy"></div>' +
  510. '<div id="ld_popup">' +
  511. '<div class="popup-title"><span>LoungeDestroyer settings</span><div id="close-btn">&#x2715;</div></div>' +
  512. '<div class="ld-settings">' +
  513. '<div>Market prices on items:</div><select id="itemMarketPrices"><option value="1">Enabled</option><option value="0">Disabled</option></select>' +
  514. '<div>Steam market currency:</div><select id="marketCurrency"><option value="1">USD</option><option value="2">GBP</option><option value="3">EUR</option><option value="5">RUB</option></select>' +
  515. '<div>Redirect from item draft page:</div><select id="redirect"><option value="1">Enabled</option><option value="0">Disabled</option></select>' +
  516. '<div>Remove stream from match page:</div><select id="streamRemove"><option value="1">Enabled</option><option value="0">Disabled</option></select>' +
  517. '</div>' +
  518. '<div class="footerino"><div>created by NCLA</div><div style="font-weight: bold;font-size:11px;"><a href="http://github.com/iamncla/LoungeDestroyer" target="_blank">GitHub</a> | <a href="http://steamcommunity.com/tradeoffer/new/?partner=106750833&token=CXFPs7ON" target="_blank">Donate</a></div></div>' +
  519. '</div>');
  520. $("#ld_popup #close-btn, #overlay-dummy").click(function() {
  521. $("#ld_popup, #overlay-dummy").hide();
  522. })
  523. $.each(Bet.userSettings, function(index, value) {
  524. $(".ld-settings #" + index + " option[value=" + value + "]").prop('selected', true);
  525. });
  526.  
  527. $(".ld-settings select").on('change', function() {
  528. Bet.saveSetting(this.id, this.value);
  529. });
  530. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement