Programming Thread

General off-topic stuffs goes here.
User avatar
Ashan
Posts: 518
Joined: February 15th, 2015, 1:33 am
Location: Saskatchewan
Contact:

Re: Programming Thread

Postby Ashan » August 3rd, 2017, 2:40 pm

Oh, yeah. Java you gotta pass the parameters into your super call too.

I haven't even touched web programming since the course I took in it like 2 years ago, cause I remember debugging that stuff being absolute hell.
Image
► Show Spoiler

User avatar
Alice
⦂☽
Posts: 3908
Joined: December 23rd, 2014, 10:47 pm
Location: Wonderland
Contact:

Re: Programming Thread

Postby Alice » August 3rd, 2017, 3:00 pm

Ashan wrote:Oh, yeah. Java you gotta pass the parameters into your super call too.

In my defense I hadn't really looked into super() before this point. So I was relying on the tutorial being actually accurate which should've been an obvious mistake on my part to begin with. It's legitimately surprising just how common it is for the code in a tutorial to not even work. Years ago I'd bought a C++ For Dummies book and it came with a cd which included the IDE the author used as well as all the source code for the projects. Like 2/3rds of the projects failed to even compile making the entire thing pretty useless. (This was at a point in time I had no internet access too.)
I haven't even touched web programming since the course I took in it like 2 years ago, cause I remember debugging that stuff being absolute hell.

It really depends on the exact issue and setup you're using. If I'd been running my scripts with "use strict"; then it would have simply errored out since there is no Array.Length property, I believe. (Since Array.Length gives an undefined value, I believe that's what would happen. Pretty sure "use strict"; will error out when trying to directly access an undefined value, though typeof value returning undefined would still work.) But I wasn't bothering with that. Usually this isn't a mistake I'd have made to begin with but I was trying to follow the tutorial's naming scheme which threw me off. On top of that this tutorial's authors seem to think that every single thing needs its own script. So rather than the rigidShapes base class being in one file and all its derivative classes such as Rectangle and Circle being in the same script, they each have their own script. So if I had been bothering to make use of "use strict"; I'd have needed to put it into each and every file which is just an annoying hassle.

Though "use strict"; wouldn't have necessarily told me where things were erroring out. It depends on the exact issue. Sometimes it'll tell you what's causing the issue but other times it'll just give a generic error and not even provide a line number. And then there's PHP. PHP just silently fails by default. Whether you get useful error output or not depends entirely on your server setup and whether your server has some form of error handling software.
💙💙💙
Image
Image

User avatar
Ashan
Posts: 518
Joined: February 15th, 2015, 1:33 am
Location: Saskatchewan
Contact:

Re: Programming Thread

Postby Ashan » August 3rd, 2017, 3:19 pm

PHP is a nightmare. For one thing I never figured out how to format it, but errors seem to just be randomly inserted into the source code of the page or something.
In that web programming class I did, our term-long project was making a website that kinda functions like Quora.com, where people can make an account, ask questions, answer them, etc. And by the end of that, mine was an absolute mess. It mostly worked, but it was fairly unstable, and I hate even looking at the source code. Here's an example php file from that.
Image
► Show Spoiler

User avatar
Alice
⦂☽
Posts: 3908
Joined: December 23rd, 2014, 10:47 pm
Location: Wonderland
Contact:

Re: Programming Thread

Postby Alice » August 3rd, 2017, 4:16 pm

Ashan wrote:PHP is a nightmare. For one thing I never figured out how to format it, but errors seem to just be randomly inserted into the source code of the page or something.
In that web programming class I did, our term-long project was making a website that kinda functions like Quora.com, where people can make an account, ask questions, answer them, etc. And by the end of that, mine was an absolute mess. It mostly worked, but it was fairly unstable, and I hate even looking at the source code. Here's an example php file from that.

Yup, that looks about right for php. It can become a real mess if you're not careful. The fact that it expects you to use both php and html in the same file is just asking for issues. It could work if it were more like a <script> tag but it's the exact opposite instead where you've got the whole <?php ?> thing for your php and html is dumped in between those tags. I'd have gone about it slightly differently but it would still have been a mess. Rather than constantly opening and closing php tags I'd have just used one set of php tags and echoed out the html where necessary. Ie:

Code: Select all

<?php if($loggedin) {
    echo '<a href="./form-question.php"><img src="FAB.png" alt="Submit a question" title="Submit a question" id="FAB" /></a>';
} ?>

instead of the

Code: Select all

<?php if($loggedin) : ?>
    <a href="./form-question.php"><img src="FAB.png" alt="Submit a question" title="Submit a question" id="FAB" /></a>
<?php endif; ?>

you have. Still a huge mess but it would help make things a bit more readable for me at least.
💙💙💙
Image
Image


User avatar
Ashan
Posts: 518
Joined: February 15th, 2015, 1:33 am
Location: Saskatchewan
Contact:

Re: Programming Thread

Postby Ashan » August 4th, 2017, 1:37 am

That's probably a much better idea than what I was doing. We were taught like, syntax and stuff but nothing about good practices. So that's why there's so much jumping between php and html. I'm sure a lot of that was because we were taught things in a specific order, and were building on top of the previous stuff we had. So it started with just plain HTML pages with filler info, then we added Javascript/PHP stuff as we went along. So a lot of it was reformatted code from a basic HTML page.
Image
► Show Spoiler

User avatar
chridd
Posts: 213
Joined: December 25th, 2014, 9:20 pm
Location: the internet
Contact:

Re: Programming Thread

Postby chridd » August 4th, 2017, 10:01 am

Alice wrote:It really depends on the exact issue and setup you're using. If I'd been running my scripts with "use strict"; then it would have simply errored out since there is no Array.Length property, I believe. (Since Array.Length gives an undefined value, I believe that's what would happen. Pretty sure "use strict"; will error out when trying to directly access an undefined value, though typeof value returning undefined would still work.)
No. It only affects undefined variables, not undefined properties of objects; accessing an undefined property of an object is never an error. Also, reading from an undefined and undeclared variable is always an error (except in "typeof"), with or without strict mode, so really the only thing strict mode affects regarding undefined things is that something like

Code: Select all

nonexistentVariable = someExpression();

is an error in strict mode, but creates a new global variable otherwise.
(There are also various other effects, like making changing various read-only things errors rather than silently ignored and changing the value of "this" in certain situations.)

User avatar
Alice
⦂☽
Posts: 3908
Joined: December 23rd, 2014, 10:47 pm
Location: Wonderland
Contact:

Re: Programming Thread

Postby Alice » August 4th, 2017, 10:32 am

chridd wrote:No. It only affects undefined variables, not undefined properties of objects; accessing an undefined property of an object is never an error. Also, reading from an undefined and undeclared variable is always an error (except in "typeof"), with or without strict mode, so really the only thing strict mode affects regarding undefined things is that something like

Code: Select all

nonexistentVariable = someExpression();

is an error in strict mode, but creates a new global variable otherwise.
(There are also various other effects, like making changing various read-only things errors rather than silently ignored and changing the value of "this" in certain situations.)

Oh, so "use strict"; actually wouldn't have helped me there either way? I actually was not aware it would treat undefined properties differently than things like undefined variables.
💙💙💙
Image
Image


User avatar
Ashan
Posts: 518
Joined: February 15th, 2015, 1:33 am
Location: Saskatchewan
Contact:

Re: Programming Thread

Postby Ashan » August 5th, 2017, 3:13 am

Today I used Javascript for something useful.

I was filling out a survey for Google Opinion Rewards, and I'm starting a job in September, so that's the info I was filling it out with, but I didn't know some of the info it asked. One of the questions was "how many people work at your place of employment," and I couldn't find that number on the company's website, but they DID have a giant page with the list of all their employees.

So I opened up the page source code, found the id of the container that had all the employees, found the class that was used for containing each individual employee, then ran in the console:

Code: Select all

document.querySelectorAll('#main-div .specific-class').length;

and it spit out the number of employees displayed on that page. I felt like such a badass. :tcool:
Image
► Show Spoiler

User avatar
Alice
⦂☽
Posts: 3908
Joined: December 23rd, 2014, 10:47 pm
Location: Wonderland
Contact:

Re: Programming Thread

Postby Alice » August 7th, 2017, 3:04 pm

https://en.wikipedia.org/wiki/JSFuck

Accidentally stumbled across that while reading some articles about programming history on Wikipedia. That's actually really neat. It's like Brainfuck except in contrast it's considered completely valid Javascript because it exploits quirks of Javascript itself in order to function. From the page's example code:

Code: Select all

alert((![]+[])[+!![]])

does the same as

Code: Select all

alert("a")


I tested it and sure enough, it does function exactly the same as the second chunk of code.
Ashan wrote:Today I used Javascript for something useful.

I was filling out a survey for Google Opinion Rewards, and I'm starting a job in September, so that's the info I was filling it out with, but I didn't know some of the info it asked. One of the questions was "how many people work at your place of employment," and I couldn't find that number on the company's website, but they DID have a giant page with the list of all their employees.

So I opened up the page source code, found the id of the container that had all the employees, found the class that was used for containing each individual employee, then ran in the console:

Code: Select all

document.querySelectorAll('#main-div .specific-class').length;

and it spit out the number of employees displayed on that page. I felt like such a badass. :tcool:

Javascript is commonly considered a shit programming language and it does have some weird quirks that can really get you and doesn't perform well compared to a compiled language such as C++ but it's an incredibly useful language nonetheless. If I had to make any suggestions with your code, I believe that using this would be more performant:

Code: Select all

document.getElementById("main-div").getElementsByClassName("specific-class").length;

Or possibly removing the .getElementById("main-div") altogether if there's no specific-class elements outside that div. .querySelectorAll is very useful (actually functions more or less like jQuery's $() selector) but in my experience it's a lot slower than the more specific selector functions. Though it's probably a total nonissue either way since what you're using it for would only really be noticeable if you were getting into the thousands. And even then it might make a quarter second to half second difference, if even quite that much.
💙💙💙
Image
Image


User avatar
Ashan
Posts: 518
Joined: February 15th, 2015, 1:33 am
Location: Saskatchewan
Contact:

Re: Programming Thread

Postby Ashan » August 7th, 2017, 9:09 pm

Hah, yeah I was literally running it one time and it ended up being roughly 250 elements in the end. It was immediate.

If I was programming for something to be used by a lot of people and/or multiple times, performance might be something to consider but for a one-time command to find info on a page, it's really not an issue.
Image
► Show Spoiler

User avatar
Alice
⦂☽
Posts: 3908
Joined: December 23rd, 2014, 10:47 pm
Location: Wonderland
Contact:

Re: Programming Thread

Postby Alice » August 7th, 2017, 11:03 pm

Been messing with that JSFuck stuff a bit. I did have to read through the documentation on Github for it before I could find a way to get more letters available but so far this is what I've got:

Code: Select all

var out = document.getElementById("out");

//(), [], and +! are the only valid characters

/*
//[]["filter"]["constructor"]("alert(1)")() //Same as below line
//[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]["constructor"]("alert(1)")()
(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]] //string "filter"

V--This stuff was something I was considering attempting to use to get more letters but I don't think they'll work since I can't access them through [][VAL] like I can "filter"--V
(+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+(+!+[])+(+[])+(+[])+(+[]))+[])[+[]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[])[!+[]+!+[]] // string "Intl"
(![]+[])[+!+[]]+(!+[]+[])[+!+[]]+(!+[]+[])[+!+[]]+(![]+[])[+!+[]]+(+[![]]+[+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+(+!+[])+(+[])+(+[])+(+[]))])[+!+[]+[+[]]] //string "array
*/

var JSF = {
   false: ![], //NOT array
   sfalse: ![]+[], //FALSE + array
   true: !![], //NOT NOT array
   strue: !![]+[], //TRUE + array
   NaN: +[![]], //int(array[false])
   sNaN: +[![]]+[], //string(NaN)
   undefined: [][[]],
   sundefined: [][[]]+[], //string(undefined)
   infinity: +(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]]), //int(1e1000)
   sinfinity: +(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])+[], //string(Infinity)
   plus: (+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[!+[]+!+[]], //string(1e+100)[1]
   period: (+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!![]], //string(1.1e+21)[1]
   //constructed from string(1+string(1)+string(true)[3]+2+0)[1]
   0: +[], //int(array)
   s0:+[]+[], //string(0)
   1: [
      +!![], //int(true)
      +!+[], //Alternate method to get 1
   ],
   s1:+!![]+[], //string(1)
   2: !![]+!![], //Unary 1+1
   3: !![]+!![]+!![], //Unary 1+1+1
   4: !![]+!![]+!![]+!![],
   5: !![]+!![]+!![]+!![]+!![],
   6: !![]+!![]+!![]+!![]+!![]+!![],
   7: !![]+!![]+!![]+!![]+!![]+!![]+!![],
   8: !![]+!![]+!![]+!![]+!![]+!![]+!![]+!![],
   9: !![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![],
   10:+([+!![]]+[+[]]), //int([1]+[0])
   s10:+([+!![]]+[+[]])+[], //string(int([1]+[0]))
   20:+(!![]+!![]+[+[]]), //int(1+1+[0])
   a: [
      (![]+[])[+!![]], //string(false)[1]
      (+[![]]+[])[+!![]], //string(NaN)[1]
   ],
   c: ([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[+([+!![]+!![]+!![]]+[+!![]+!![]])], //string([]["filter"])[int(3 + [2])]
   d: ([][[]]+[])[!![]+!![]], //string(undefined)[2] --string(undefined[8]) would also work but is wasteful for obvious reasons
   e: [
      (![]+[])[!![]+!![]+!![]+!![]], //string(false)[4]
      ([][[]]+[])[!![]+!![]+!![]], //string(undefined)[3] --string(undefined[7]) would also work but is wasteful for obvious reasons
      (!![]+[])[!![]+!![]+!![]], //string(true)[3]
   ],
   f: [
      (![]+[])[+![]], //string(false)[0]
      ([][[]]+[])[!![]+!![]+!![]+!![]], //string(undefined)[4]
   ],
   i: [
      ([][[]]+[])[!![]+!![]+!![]+!![]+!![]], //string(undefined)[5]
      ([![]]+[][[]])[+!![]+[+[]]], //string(falseundefined)[10]
   ],
   l: (![]+[])[!![]+!![]], //string(false)[2]
   n: ([][[]]+[])[+!![]], //string(undefined)[1] --string(undefined[6]) would also work but is wasteful for obvious reasons
   o: ([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[+([+!![]+!![]+!![]]+[+!![]+!![]+!![]])], //string([]["filter"])[int(3 + [3])]
   r: (!![]+[])[+!![]], //string(true)[1]
   s: (![]+[])[!![]+!![]+!![]], //string(false)[3]
   t: (!![]+[])[+[]], //string(true)[0]
   u: [
      ([][[]]+[])[+[]], //string(undefined)[0]
      (!![]+[])[!![]+!![]], //string(true)[2]
   ],
   v: ([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[+([+!![]+!![]]+[+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]])], //string([]["filter"])[int(2 + [9])]
   y: [
      (+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])+[])[!![]+!![]+!![]+!![]+!![]+!![]+!![]], //string(Infinity)[7]
      (+[![]]+[+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+(+!+[])+(+[])+(+[])+(+[]))])[+!![]+[+[]]] //(string(NaN)+infinity)[int(1 + [0])]
   ],
   I: (+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])+[])[+[]], //string(Infinity)[0]
   N: (+[![]]+[])[+[]], //string(NaN)[0] --string(NaN)[2] would also work but is wasteful for obvious reasons
   "(": ([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[+([+!![]]+[!![]+!![]+!![]+!![]+!![]])], //string([]["filter"])[int(1 + [5])]
   ")": ([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[+([+!![]]+[!![]+!![]+!![]+!![]+!![]+!![]])], //string([]["filter"])[int(1 + [6])]
   " ": ([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[+([+!![]]+[!![]+!![]+!![]+!![]+!![]+!![]+!![]])], //string([]["filter"])[int(1 + [7])]
   "{": ([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[+([+!![]]+[!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]])], //string([]["filter"])[int(1 + [8])]
   "}": ([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[+([+!![]+!![]+!![]]+[+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]])], //string([]["filter"])[int(3 + [8])]
   "[": ([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[+([+!![]+!![]]+[+!![]+!![]+!![]+!![]])], //string([]["filter"])[int(2 + [4])]
   "]": ([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[+([+!![]+!![]+!![]]+[+!![]+!![]+!![]+!![]+!![]+!![]])], //string([]["filter"])[int(3 + [6])]
   "\n": ([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[+([+!![]]+[!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]])], //string([]["filter"])[int(1 + [9])]
}
out.innerHTML = JSON.stringify(JSF, null, "    ");

On the local page I'm running that code on it outputs this to verify that my code is correct:
Image
s_ variables are string versions of numbers and other specific values like Infinity, NaN, true, and false. Values holding arrays such as 1, a, or e are each alternate methods to get the same value for approximately the same amount of characters. (Or in 1's case exactly the same amount of characters since it's +!![] and +!+[].)

From this point though I can now move on to constructing the string "constructor" in order to work on retrieving the rest of the characters. The whole []["filter"]+[] thing was a weird trick and I'm still not 100% certain on why exactly it works but it's pretty neat. [] declares a blank array so I'm not certain why []["filter"] is a valid method to access the filter method. I think it might be accessing one of Array's prototype methods or something. And then the +[] at the end casts that to a string and since []["filter"] is a function it gets automatically toSourc()ed which returns this string:

Code: Select all

"function filter() {
    [native code]
}"

which allows us to retrieve several characters including (, ), [, ], {, }, v, c, o, d, " ", and "\n". ([]["filter"]+[])[VAL] allows us to access a specific character from that string so you just need to iterate through the numbers until you reach the character(s) you need.
Ashan wrote:Hah, yeah I was literally running it one time and it ended up being roughly 250 elements in the end. It was immediate.

If I was programming for something to be used by a lot of people and/or multiple times, performance might be something to consider but for a one-time command to find info on a page, it's really not an issue.

Yup, figured as much. Only reason I even mentioned it is cause I noticed a difference myself awhile back when I was messing with something. But I was messing with something in the range of 10,000-100,000 elements or so.
💙💙💙
Image
Image


User avatar
Alice
⦂☽
Posts: 3908
Joined: December 23rd, 2014, 10:47 pm
Location: Wonderland
Contact:

Re: Programming Thread

Postby Alice » August 12th, 2017, 1:10 am

Found a bit of a strange quirk with fullscreen videos in Firefox. I'm rewatching raocow's Hyper V lp. One of the rooms in Bowser's castle is so ridiculously dark that I can barely make out any detail at all. I got the wild idea of trying out a CSS image filter. Turns out it actually works for all the good it did though since there's simply very little detail in the video to begin with due to how dark it is. Afterwards though I went to disable the filter I'd use. First I just tried unticking it in the element inspector tool. This accomplished exactly nothing. So I changed the values back to 100% brightness and contrast. For some reason this resized the video to what it would be if I wasn't in fullscreen mode. Not a huge deal since I could just hit escape then refullscreen it but it was an unexpected quirk. Then again I honestly wasn't expecting the CSS image filter to even work to begin with.
💙💙💙
Image
Image


User avatar
Alice
⦂☽
Posts: 3908
Joined: December 23rd, 2014, 10:47 pm
Location: Wonderland
Contact:

Re: Programming Thread

Postby Alice » August 20th, 2017, 11:43 am

I hate when sites decide to try to combat AdBlock and NoScript users by being even more annoying. TVTropes has apparently decided to be as annoying as possible to people using NoScript addons. It will blank out the page and replace it with an iframe complaining about ad blockers if Javascript is enabled. It pissed me off so I hunted down the script that was responsible and made a userscript to remove said script.

Code: Select all

// ==UserScript==
// @name        Fuck your anti-NoScript
// @namespace   Alice
// @include     http://tvtropes.org/*
// @version     1
// @grant       none
// ==/UserScript==

var alc = document.getElementsByTagName("script");
for (let i = 0; i < alc.length; i++) {
    if (alc[i].innerHTML.match(/8d1f/)) {
      alc[i].remove();
      console.log(`Script ${i} removed!`);
   }
}

Or my less impolitely named copy of it on GreasyFork: https://greasyfork.org/en/scripts/32469 ... pt-remover

I could have just disabled Javascript and been done with it. But they pissed me off by being such obnoxious shit heads. So I went out of my way to bypass it just out of spite. You want me to disable my AdBlockers and such? Simple solution: Don't be annoying pieces of trash who facilitate annoying ads and intrusive trackers. Do something like SMWC and use a less shitty advertiser. (Though even on SMWC I still block Google Analytics.)
💙💙💙
Image
Image


User avatar
Ashan
Posts: 518
Joined: February 15th, 2015, 1:33 am
Location: Saskatchewan
Contact:

Re: Programming Thread

Postby Ashan » August 20th, 2017, 11:56 pm

I look forward to the adblocker blocker blocker blocker blocker(...) arms race
Image
► Show Spoiler

User avatar
Alice
⦂☽
Posts: 3908
Joined: December 23rd, 2014, 10:47 pm
Location: Wonderland
Contact:

Re: Programming Thread

Postby Alice » August 21st, 2017, 1:24 am

They're only ever going to succeed temporarily. What they did here was basically the worst they can accomplish. They put code into a completely nondescript script tag to replace the entire code from the page with an iframe whining about ad blockers. The only thing they could do from there is to fine a way to make it so my regex method of finding the script doesn't work (could be accomplished by doing something like manually constructing the string from different parts or something) but even that should be bypassable. It'd be possible to setup the script to load the page's html into a variable and every few seconds replace the page's html with what's loaded into that variable, for example. It's a really ham-fisted solution and it'd probably perform like crap but it'd also be very difficult to bypass.

They could also probably do stuff involving neutering regex and such if they don't make use of that stuff on their pages themselves but even that should be bypassable since, I believe, userscripts run before everything else on a page by default. Meaning you can simply copy over that stuff to a new function yourself before they have a chance to neuter it.

Or to put it simply, every realistic solution they have is solvable with little issue even from a mediocre programmer such as myself.
💙💙💙
Image
Image


User avatar
Ashan
Posts: 518
Joined: February 15th, 2015, 1:33 am
Location: Saskatchewan
Contact:

Re: Programming Thread

Postby Ashan » August 21st, 2017, 5:58 pm

I spent a ton of time working on my Android app yesterday. I ended up working basically from lunch until like 9:30pm and forgot to eat dinner because I was just in the zone.
It's an app called Quotr that basically lets you put in quotes and then displays them on a nice colorful background, with fancy animations and stuff. Don't know if I've ever talked about it here before. Anyway, I wanted to add a save button that exports the currently viewed quote to an image on the phone's storage. I could have simply taken the View that's displaying the quote on screen and exported that, but I didn't like the idea of size/resolution/aspect ratio being determined by the device and its orientation. I wanted it to be the same on every device. So ended up creating a custom view that overrides the onMeasure() method of the View class, and programmatically lays out the text. It was a bit of a challenge, I kept the width of the image at a fixed resolution of 1000 pixels, and I was originally just gonna keep the height 1000 too, but I figured it would be silly if the exports were the same size whether the quote was 1 line or 5 lines. So I created an algorithm that breaks the quote into words, then goes through word by word, concatenating it to the line, and measuring the width to see if it fits within the 1000 pixel range (minus some padding on each side), and then breaks them into lines, then draws each line on a canvas, calculating the offset based on how many lines there are. Height of the image is also calculated in a similar way.
I'm pretty happy with my end results. Here's a couple sample exports:
Image
Image


My only issue now is with earlier Android APIs. Specifically, pre-Marshmallow devices. In Android Marshmallow (API level 23) Google added run-time permission requests. Previously, an app just had to lay out their permissions in the app manifest, and when you installed the app it would tell you all the permissions it requires, and the user would accept them before installing. Apps targeting Marshmallow or above don't require any permissions at install, and will request permissions whenever they need them. So if I user doesn't want to grant a permission required for a specific task, they should, in theory, be able to not grant them and still use the app depending on implementation of the feature. My permission granting works, but I tested it on an API 16 (Jellybean) device, and it doesn't seem to save the image at all. Only realized this last second, and there's quite a few other things that break on earlier APIs, but I'll worry about that later.

I think I'm pretty close to having my app in a mostly complete state. Once I get all the features I want implemented, I'll probably put in banner ads with like a $2 upgrade to remove them and post it on the Play Store.
Image
► Show Spoiler

User avatar
Ashan
Posts: 518
Joined: February 15th, 2015, 1:33 am
Location: Saskatchewan
Contact:

Re: Programming Thread

Postby Ashan » August 21st, 2017, 6:01 pm

Also, app name is tentative because I Googled it for the first time yesterday and realized there's like 20 apps with that name already. But they're not as good as mine anyway. :tcool:
Image
► Show Spoiler

User avatar
Alice
⦂☽
Posts: 3908
Joined: December 23rd, 2014, 10:47 pm
Location: Wonderland
Contact:

Re: Programming Thread

Postby Alice » August 21st, 2017, 11:59 pm

Ashan wrote:Image

I could've sworn I'd heard this one before but it appears to be a direct quote from today's Yump video, lol. I swear he's said something almost word for word the same though.
💙💙💙
Image
Image


User avatar
Ashan
Posts: 518
Joined: February 15th, 2015, 1:33 am
Location: Saskatchewan
Contact:

Re: Programming Thread

Postby Ashan » August 22nd, 2017, 12:10 am

Hah, yeah I just added that today.
Possible he's made the same joke before. If he did, I don't remember it.
Image
► Show Spoiler

User avatar
Alice
⦂☽
Posts: 3908
Joined: December 23rd, 2014, 10:47 pm
Location: Wonderland
Contact:

Re: Programming Thread

Postby Alice » August 22nd, 2017, 12:23 am

Ashan wrote:Hah, yeah I just added that today.
Possible he's made the same joke before. If he did, I don't remember it.

I can't remember which video I'm remembering it from so it may not be a verbatim copy but it was definitely similar enough to strike a chord with me at least. Really weird reading the quote here then hearing it in his video afterwards though, lol.
💙💙💙
Image
Image


User avatar
Ashan
Posts: 518
Joined: February 15th, 2015, 1:33 am
Location: Saskatchewan
Contact:

Re: Programming Thread

Postby Ashan » August 29th, 2017, 5:32 pm

Image
Image
► Show Spoiler

User avatar
Alice
⦂☽
Posts: 3908
Joined: December 23rd, 2014, 10:47 pm
Location: Wonderland
Contact:

Re: Programming Thread

Postby Alice » October 12th, 2017, 3:49 am

I really freaking hate updating things because other people decided to go and totally break shit. I'm having enough issues with my addons malfunctioning due to Mozilla's totally retarded update to Web Extensions thus completely gutting their far superior addon framework. uMatrix, for example, simply doesn't save my settings anymore. It resets them every time I start my computer now. And of course there's the really retarded Greasemonkey update which forced me to change to Tampermonkey.

Anyways I've been forced to update my Thingifier userscript. But no matter what I try I can't seem to get it to cooperate. Greasemonkey is totally different than how it used to work so it's not an option and Tampermonkey is different enough that it totally breaks. I spend like 6-7 hours or so the other day working on updating it. I didn't succeed but by the time I quit for the night I at least knew what was broken and had an idea of what I needed to do. Cue the next day where I go to work on it and it's magically like 10x more broken than it was when I stopped working on it. That combined with sincus headaches for the next several days made me put it off until today.

Today I restarted and just decided to ignore the unnecessary changes and deal with the necessary ones. Fat lot of good that did. I have most of the changes done. Everything mostly works except the quoting function (which I think I broke, or rather overlooked something I should have updated most likely) and the script actually loading your settings properly. Now it does actually load your settings. However where it actually activates the different functions according to your saved settings randomly doesn't work now. The config loading function checks if a setting is set to true, if so then it clicks the corresponding item in the menu. There's a few issues with this. The first is that unless I set a timeOut function (I'm using 100ms currently) it doesn't even tick the settings correctly. The second is that even though it's clearly clicking the elements it's not activating their click events for some reason. Then the third is that one item simply randomly doesn't even tick its element correctly either.

There's also various other issues. The quoting, like I mentioned. I'm not certain why just yet but it doesn't quote things at all at the moment. I'm also not sure the magnifier works at all because I haven't really messed with it but before I started working on the script it randomly had stopped working. And for some reason I also seem to be failing to get the script's settings to reset to the default when you use the clear settings button and I honestly have no freaking idea why. I have a template I'm using for the settings, it's simply another variable I set at the same time I'm loading the config which is identical other than the fact it uses the default settings for each option. The clear settings button sets the config object to the template object, stores it in local storage, then resets the page. But for some weird reason it doesn't seem to actually clear your settings like it should.

All I know at this point is it'd really probably just be easier to scrap the entire piece of shit and start over from scratch but between the headaches and the fact I've been sleeping rather poorly I just don't have the presence of mind to actually accomplish that.
💙💙💙
Image
Image


User avatar
Alice
⦂☽
Posts: 3908
Joined: December 23rd, 2014, 10:47 pm
Location: Wonderland
Contact:

Re: Programming Thread

Postby Alice » December 12th, 2017, 4:53 am

I really hate trying to do anything with Youtube. Magic Actions for Youtube has an option for magnifying video thumbnails. This is super useful. Except the devs of the extension update it so rarely that it spends 95% of the time useless since that function gets broken constantly. I decided to make my own alternative option. I've got it working pretty well except one massive issue. One of Youtube's own scripts errors out on some pages, such as your subscriptions. You'd think this wouldn't be an error but it completely breaks my script. And of course it;'s incredibly difficult to debug because Youtube is such a pile of trash that I frequently can't get shit done in the dev tools. Firefox Quantum is better than it used to be since I can get it open without locking up my browser at least but it's still something I have to rush through because I have ten seconds at best.

Edit: Well I got things working now. The only remaining issue is figuring out a way to get the highest available resolution since so many videos don't have a maxresdefault thumbnail available despite the fact the name would suggest it would always be the maximum resolution available. Code btw:

Code: Select all

// ==UserScript==
// @name         YT Image replacer
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://www.youtube.com/watch*
// @match        https://www.youtube.com/feed*
// @match        https://www.youtube.com/playlist*
// @match        https://www.youtube.com/channel*
// @match        https://www.youtube.com/user*
// @match        https://www.youtube.com/results*
// @match        https://www.youtube.com/
// @grant        none
// ==/UserScript==

var alcth;

setTimeout(magadd, 50);

function magadd() {
    let el = document.createElement("div");
    el.id = "alcthumb";
    el.style.display = "none";
    el.style.position = "fixed";
    el.style.border = "8px solid #333";
    el.style.background = "#333";
    el.style.borderRadius = "8px";
    el.style.zIndex = "2147483647";
    el.style.height = "284px";
    el.style.width = "494px";
    let st = document.createElement("style");
    st.innerHTML = `div#alcthumb:after {
                    content: "▶";
                    color: #333;
                    position: absolute;
                    top: calc(50% - 16px);
                    right: -26px;
                    font-size: 32px;
                }`;
    document.body.append(st);
    document.body.append(el);
    alcth = document.getElementById("alcthumb");
    let list;
    //Video view
    if (document.URL.match(/https:\/\/www\.youtube.com\/watch/)) {
        list = document.getElementsByClassName("watch-sidebar")[0].querySelectorAll("img");
        addevents(list);
        //With a playlist
        if (document.URL.match(/list=/)) {
            list = document.getElementsByClassName("watch-player-playlist")[0].querySelectorAll("img");
            addevents(list);
        }
    }
    //Feed view
    if (document.URL.match(/https:\/\/www\.youtube.com\/feed/)) {
        list = document.getElementById("browse-items-primary").querySelectorAll("img");
        addevents(list);
    }
    //Base view
    if (document.URL.match(/https:\/\/www\.youtube\.com\/?$/)) {
        list = document.getElementById("feed-main-what_to_watch").querySelectorAll("img");
        addevents(list);
    }
    //Playlist view
    if (document.URL.match(/https:\/\/www\.youtube.com\/playlist/)) {
        list = document.getElementById("browse-items-primary").querySelectorAll("img");
        addevents(list);
    }
    //Channel view
    if (document.URL.match(/https:\/\/www\.youtube.com\/channel/) || document.URL.match(/https:\/\/www\.youtube.com\/user/)) {
        list = document.getElementById("browse-items-primary").querySelectorAll("img");
        addevents(list);
    }
    //Search view
    if (document.URL.match(/https:\/\/www\.youtube.com\/results/)) {
        list = document.getElementById("content").querySelectorAll("img");
        addevents(list);
    }
}

function addevents(list) {
    for (let i = 0; i < list.length; i++) {
        list[i].addEventListener("mouseover", function(e) {
            //console.log(e);
            alcth.style.display = "inline-block";
            //This one doesn't line up right for smaller images and I was too lazy to figure out a way to get it perfectly centered every time.
            //alcth.style.top = e.target.getBoundingClientRect().bottom + e.target.getBoundingClientRect().height - alcth.getBoundingClientRect().height + "px";
            alcth.style.top = e.clientY - (alcth.getBoundingClientRect().height / 2) + "px";
            alcth.style.left = `${e.target.getBoundingClientRect().left - alcth.getBoundingClientRect().width - 16}px`;
            alcth.innerHTML = `<img src=${e.target.src.replace(/(https:\/\/i\.ytimg\.com\/vi\/.+\/)(mq|hq|maxres)?(default\.jpg)(\?.+)?/, "$1maxres$3")} style="width: 100%; height: 100%;">`;
        });
        list[i].addEventListener("mouseleave", function(e) {
            alcth.style.display = "none";
        });
    }
}
💙💙💙
Image
Image


User avatar
Tovarisch Red Yoshi
Resident Commie Chameleon
Posts: 1955
Joined: December 29th, 2014, 10:57 pm
Location: Ashtree

Re: Programming Thread

Postby Tovarisch Red Yoshi » December 12th, 2017, 6:19 am

Did I mention I took csci this semester? I have my final tomorrow. woo
wikipedia wrote:The word "w00t" itself was first seen in 1994.[citation needed] The expression rose in popularity in the late 1990s and early 2000s (decade) mostly on MMORPG such as RuneScape. It remains a niche Internet term and is not in general usage. The symbolic approximation of Latin letter forms makes w00t a prime example of internet leetspeak. It may also sometimes be seen spelled as "wewt" or "wought".
Isocitration wrote:<Isocitration> a long obscure nonsequitur that must be explained
<Isocitration> the joke is funny because of that alone
<tovakj> you've known me how long, yet?
<tovakj> yes
<tovakj> you're finally figuring out my aesthetic

User avatar
chridd
Posts: 213
Joined: December 25th, 2014, 9:20 pm
Location: the internet
Contact:

Re: Programming Thread

Postby chridd » December 12th, 2017, 3:28 pm

Alice wrote:// @namespace http://tampermonkey.net/
The namespace is supposed to be a URL that represents you—if a script has the same name and namespace, then it assumes they're the same script, and the namespace is to prevent conflicts between two scripts with the same name.[1][2]

User avatar
Alice
⦂☽
Posts: 3908
Joined: December 23rd, 2014, 10:47 pm
Location: Wonderland
Contact:

Re: Programming Thread

Postby Alice » December 12th, 2017, 9:48 pm

chridd wrote:The namespace is supposed to be a URL that represents you—if a script has the same name and namespace, then it assumes they're the same script, and the namespace is to prevent conflicts between two scripts with the same name.[1][2]

That's actually the default namespace for Tampermonkey. Usually I change it but I apparently spaced it this time, lol. I just realized I could edit the default template now though so I won't have to worry about that in the future.
💙💙💙
Image
Image



Return to “General Perversion”

Who is online

Users browsing this forum: No registered users and 8 guests