Capital Industry Calendar

The industry posts at Eve fail have inspired me to start producing Capitals and this has spawned some new requirements out of our Wallet Manager program.

Problem: Expensive Capital BPOs that are idle mean that they are not producing profitable items

Solution: Use the Corporation Industry Jobs API to display a visual aid of capital job production progress as to easily tell when BPOs will be idle

As always, James and I start off with a quick sketch on paper of what we think the final layout should look like. After some scribbling, debates about tables/CSS/javascript, and layout design we settled on a design.

Here is a shot of our paper sketch.

My knowledge of javascript is rather limited and James is usually the one spearheading new and innovative solutions when I present a design challenges.

Notes from James:

Blake often comes to me with a “I need this thing. Can you make this thing?”, to which I often pause and perform what I like to call shriveled programmer stare. This maneuver involves me scrunching my face as much as possible, raising one eyebrow, and giving a bit of a pained look. I’m quite sure I gave this look when the idea was first proposed. The basic idea actually is just a Gantt chart. I have x number of capital ships in production at any given time and I would like to know exactly, at a quick glance, when they come out of the oven so the next batch of parts will be ready. Simple enough, on paper. The real question is implementation.

A first idea was to use a table, and just change the background color if the job is still running on that day. However, we decided we would like to have the chart auto-scale, so that it would always display far enough out to have the end of the longest job on the chart. Doing this as a pure table would have been inelegant at best, with quite possibly a ludicrous amount of table columns needed for very long jobs. Instead, I took a more difficult, but ultimately more elegant approach; use a single row per job and utilize the margin-left and width css properties to control the positioning and length of each bar.

This, however, required that we have non-table-based vertical lines to delineate our days. For this I used Raphael. Raphael is a nifty little SVG canvas library with decent documentation and a good community base.


//Initialize our variables
var width = $this.width();
var height = $this.children('.industry-job-calendar-table').height();
var offset = globals.headerOffset;

var canvasDiv = $this.children('.industry-job-calendar-table').children('.industry-job-calendar-canvas')[0];

//Create the canvas
var paper = Raphael(canvasDiv, width, height + offset);

A lot of work went into getting our start and end dates, and anyone who’s worked with the JS Date object knows how painful operating in the non-native timezone (even if it is UTC) can be. After our fancy date math, we set the job bar properties, draw the canvas object behind the table rows, attach our tooltip hover() events to the bars, then do a pretty animation of the bars to their final widths.

All in all, a nice little idea that came in at around 325 lines of JS and 20 lines of PHP. And to use it is quite simple:

$('#industry-calendar').phdIndustryCalendar({url: './getCapitalJobs.php'});

And the final result is a clean looking display of our Capital production line.


Wallet Manager Security Issues

If you have been following this blog for a while, you know that my corpmate James and I have been working on a Wallet Manager site to help manage our Eve ventures. Over time it has grown into our all-encompassing-project-management-thing which now has a trading, manufacturing, invention, and cost analysis sections.

I wanted to disclose why this darn thing is not open to the public as the majority of the feedback that I have been hearing has been, “awesome, now when can I use it!?”

We have not made the site public because of security issues, specifically due to the numerous SQL injection abilities in our code.

Here is a common function that we use that takes the typeID of an item and returns its name. We use this so when we display a Cap Recharger II for example, you can see the name of the item and not just the ‘2032’ number identifier that is easier to work with from a programmability standpoint.

This PHP function retrieves the item name from an input of its typeID.

public function getName($typeID)
{
$sql = ‘SELECT typeName FROM invTypes WHERE typeID = ‘.$typeID.’‘;
$connection=Yii::app()->db;
$command=$connection->createCommand($sql);

//Run the query
$results = $command->query();
$itemName = $results->read();

return $itemName[‘typeName’];
}

The database query is highlighted in green and the terrible part has been highlighted in red.

What you are seeing is a database query that is fed a non-sanitized input. Good programmers will take the $typeID variable and sanitize it before putting it into the SQL query. A common check is to limit the variable to only have characters such as A-Z and 1-3 characters. This check will not allow any special characters such as  : ; ‘ ” $ that are used for SQL operations to be allowed in the query.

With our current function with the unsanitized input variable, you can plug in all sort of things into the query. You could inject code in place of the variable to read, drop, and modify the database,  something we obviously don’t want happening.

Sadly around half of our function were written in this fashion in order to get the pages up and working. Because it has been an internal project, the focus has been on the aesthetic result and not the security of the code behind it. If we were to release it to the public we would have to go over each function and check to make sure that it is secure.

Let me quote CCP and say Soon(tm) for the release.