Category: Code

Enter the Skyrim Alchemy Sage

Welcome fellow Skyrim alchemists – interested in brewing the most potent of poisons?! The most proverbial of potions?!! The most electrifying of elixers?!!! …perhaps with a touch of alliteration? Hrmph! I have a scroll called the Skyrim Alchemy Helper that will help you craft the finest concoctions – far beyond the skills of mere mortals… In a land where everything’s for sale, this one is free…

Back to Reality

Whew! Ok, now that the RP’er in me has had a chance, the developer in me has a question for you: have you ever been doing something where you just wished you could tie a few things together quickly? Make sense of large amounts of data in no time? Then call me Mr. Rinse & Repeat, ’cause I can’t stop! heh ok… I’ll calm down.

Anyway, as a developer, I have the advantage of being able to put data together and display it in a fashion that makes sense to me. This is a story about one such helper that I made to assist in all my alchemy endeavors in Skyrim – one that I thought I would use as an example (and advertisement) of code that’s good enough for now and why that too can be ok.

The Pain Point of Inspiration

Recently (well, recent to me), Bethesda Game Studios came out with a freshly revamped Skyrim – Special Edition – full of high res textures, bug fixes, and many improvements. Cool! I’ve sunk a few hours in that game, but it’s been a minute and I wouldn’t mind returning to Skyrim to slay some dragons once more!

I get started and it dawns on me: “Geez, I wish I could get back to crafting my alchemy stuff.” I used to have those recipes memorized! What parts for my paralysis poisons? What’s good for restoring health? What’s the other thing I used to craft for those times when I need that thing?!! Blah! It’s too much to get started all over again!

So what’s the solution you might be asking? The new hotness in web frameworks, CI/CD pipelines, and the latest, most feature rich, spanky IDE?! Huh huh huh?!! =D

Hell no! I ain’t got time for that! I made a few hacky scripts to make sure my alchemy prowess was better than ever so I could get back to the game! Pshhh.. what, is this your first rodeo with Skyrim?

Enter the Lazy Dev Sage

So why is this article under filed under “Code”? I realize the quality of the code in these is more or less not ideal… Not a great start for the Code category. Yet, if there’s one thing I know, it’s the tendency of developers (especially jr. devs) to be paralyzed by the quality of their code to the point where progress is painfully slow. This is my effort to say “Heck with it! I need this now!” and to show that even when you write mediocre, unreadable, and/or unmaintainable code… there’s a place for that too.

Going back to one of my favorite rules of the dev process: “Make it work; Make it right; Make it fast”. Right now, we’re at stage 1… I might not ever need to come back to this code, so while it works, it’s fine as it is – and now I can focus on the next task at hand way sooner than perfection would allow for.

Can improvements be made? Hell yes. Can features be added? Sure – might have to start thinking about the overall architecture if we’re working on this a lot. Is it fast? Probably not as fast as it could be yet not unbearably slow. Does the trick, I guess *scratches head*.

Resultant Results and a Few Caveats

For now – it IS… which is way better than “it is not”. I think that counts for something too. Sure: take feedback from code reviews with respect and perspective. Sure: this isn’t how you should be writing code for mission critical applications (sidenote: if your mission critical software doesn’t already have a CI/CD pipeline to prevent this – HOW ARE YOU LIVING YOUR LIFE RN?!! IS IT BROKE? ARE YOU SURE? ASK GARY AND MAKE SURE! I DON’T CARE – ASK HIM AGAIN! WELL WAKE HIM UP!!!)

heh. I’m a dork.

…and sure: is this the standard I want all my code to sink to? Nahh… but for what it is – it’s just right and that’s ok.

If Source Code Wore Underpants

As it turns out, I even went as far as to make a script that allows you to look at the files and their source code! Yeesh! What was I thinking?! Eh… I was having fun banging out something I wanted to make and not thinking twice about it.

So, without further adieu, if you’d like to see London and you’d like to see France – here’s the Skyrim Helper Scripts underpants. They’re hacky and look like hell, but it’s way better than having to relearn all the different alchemy recipes from scratch again!

Subtitle: and talk about it UNprofessionally

I’ve been writing code for about the last decade and a half. It really wasn’t till I started working on a team of developers that I was pushed to write better, more readable code — a very important lesson. Then, it wasn’t till I started breaking old habits and started writing in a test driven development (or TDD) fashion that I started to write professional code. Continue reading “How I Write Professional Code”

Who are you. Whoo whoo. Whoo whoo.

So let’s say you need to know what user is running a script in PHP. If you’re like me, you may have tried get_current_user only to find that’s just for the current owner of the file. Well THAT’S deceivingly unhelpful! =\

Wait! Sec. One more moment of gripe: If what get_current_user in php does makes sense to you, I’d like to be the first to ask you: …How?!

Not only did that not help, but I also couldn’t find any solutions or hints in the right direction from the comments in the documentation (generally, I find them to be a good place for a next step). There was one suggesting to using posix functions like this: print_r(posix_getpwuid(posix_geteuid())); — however, no luck! If the user is invoking the script with sudo, we lose all trace of who done it. Also, this is technique can limit who can use it as it’s not uncommon for environments to disable posix_* functions for security.

So, Who Really Done It?!

Ranting aside… the answer to this eluded me! Low and behold, the it was inside of $_SERVER all along. Le sigh. I put together a quick function with a few fallbacks to figure it out. Let me know if this doesn’t work for you, but for me, does the trick in spades =]

1

2

3

4

5

6

7

8

9

10

11

12

13

14

functionget_real_current_user()

{

if(isset($_SERVER['SUDO_USER'])){

return$_SERVER['SUDO_USER'].' [priv]';

}

if(isset($_SERVER['LOGNAME'])){

return$_SERVER['LOGNAME'];

}

if(isset($_SERVER['HTTP_HOST'])){

// Could also use $_SERVER['REQUEST_URI'] rather than SCRIPT_NAME... up to you =]

return"Web via: ".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'];

}

return"Unknown User";

}

I like this solution the best. Not only is this data already in the scope of our script already, but we don’t have to use posix or try crap like echo exec("who am i"); and parsing through that. #winning

So, I get that there are probably better ways to handle this circumstance, but when working with legacy code, sometimes, it’s not up to you. I had a method that would be called with either one thing, or an array of these things. Approaching a context like this, the solution we came up with was (what I think is an) amazingly simple way to ensure if you’re sometimes receiving one thing or an array of things, you can handle both.

Check it out:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

classFoo

{

publicfunctiononeOrMany($input)

{

if(is_array($input)){

returnarray_map(array($this,'oneOrMany'),$input);

}

// Now do stuff to one $input only and return your results =]

return$results;

}

}

There it is. And now hopefully I’ll remember this better next time I need something quick.

Code:

Rundown

The basic formula is a BASH for loop that grabs all of the tables in the desired database, filters the output using a combination of AWK and GREP so we can use just a simple list, then drops each table separately.

USE THIS CODE AT YOUR OWN RISK! BACKUP YOUR DATABASE FIRST AND HAVE A RECOVERY PLAN IN PLACE! (trust a man known to fat finger things)

Now, this is relatively uninteresting, but sometimes, you’ll find a list of active queries that have stacked up against your db. Some things that can really help you identify issues is by ensuring each different piece of your platform identifies itself uniquely.

Once that happens, you can see which queries from where are hanging on. Parts of your platform can stall and hold onto connections, queries can take an eternity, bad code can hold result sets in memory, etc… This should give you a good idea where to start looking!