Thursday, August 4, 2016

World of Warcraft Error # 132 after installing Windows 10 Anniversary Update

I recently installed the Windows 10 Anniversary Update. After doing so however, my World of Warcraft installation started crashing during launch with a message stating Error 132 memory something or other referenced such and such.

I searched online for a solution and tried a bunch of things listed on this helpful Youtube link - the DX9 fix worked, but I found a better fix. I happened across a post listing what's new in the update and found that they "added support" for World of Warcraft in the Game DVR. On a hunch, I turned it off (in the settings of the X-Box app). Voila, WoW started working again with DX11.

Edit: After posting I found that Blizzard has an official post with the same resolution: http://us.battle.net/forums/en/wow/topic/20748004624#post-1.

Tuesday, January 26, 2016

SQL to de-dupe overlapping ranges of dates

I came across a situation today where I was given a set of date ranges (begin date to end date) and needed to de-duplicate the ranges so any overlapping dates are "collapsed" so the final result would only contain the distinct range(s) of dates. There are probably a number of solutions to this problem, but I rather liked what I came up with so I decided to post it here for posterity. Code first, explanation after:

-- Declare a table variable for test data
DECLARE @Data TABLE
(
 BeginDate DATETIME,
 EndDate  DATETIME
);
-- Fill the test data
INSERT INTO @Data
SELECT '2016-01-01', '2016-01-05'
UNION ALL SELECT '2016-01-03', '2016-01-10'
UNION ALL SELECT '2016-01-12', '2016-01-15'
UNION ALL SELECT '2016-01-14', '2016-01-18'
UNION ALL SELECT '2016-01-16', '2016-01-25'
UNION ALL SELECT '2016-01-16', '2016-01-20'
UNION ALL SELECT '2016-01-16', '2016-01-20'
UNION ALL SELECT '2016-02-01', '2016-03-13'
UNION ALL SELECT '2016-05-01', '2016-05-30'
UNION ALL SELECT '2016-05-28', '2016-06-10';

WITH S AS (
 SELECT BeginDate, MAX(EndDate) AS EndDate -- Select the starting ranges
 FROM @Data D
 WHERE NOT EXISTS(SELECT * FROM @Data WHERE BeginDate < D.BeginDate AND EndDate >= D.BeginDate)
 GROUP BY BeginDate
UNION ALL
 SELECT S.BeginDate, D.EndDate -- recursively expand the ranges
 FROM S
 INNER JOIN @Data D ON D.BeginDate BETWEEN S.BeginDate AND S.EndDate
   AND D.EndDate > S.EndDate
)
SELECT BeginDate, MAX(EndDate)
FROM S
GROUP BY BeginDate;

In this example, I used a common table expression (CTE) for my test data. The work is done by the "S" CTE. It starts by selecting any date range that doesn't have another date range that overlaps its begin date, grouping by that begin date, to select the max end date (to eliminate any ranges that start on the same day). It then recursively joins back to the original data, bringing in any date range that overlaps and has an end date further out. In the final output, you select the BeginDate and MAX(EndDate) to get your distinct list of date ranges.

If you have additional columns you need to group by, you'll need to add them in. For example:

-- Declare a table variable for test data
DECLARE @Data TABLE
(
 ID   INT,
 BeginDate DATETIME,
 EndDate  DATETIME
);
-- Fill the test data
INSERT INTO @Data
SELECT 1, '2016-01-01', '2016-01-05'
UNION ALL SELECT 1, '2016-01-03', '2016-01-10'
UNION ALL SELECT 1, '2016-01-12', '2016-01-15'
UNION ALL SELECT 1, '2016-01-14', '2016-01-18'
UNION ALL SELECT 1, '2016-01-16', '2016-01-25'
UNION ALL SELECT 2, '2016-01-16', '2016-01-20'
UNION ALL SELECT 2, '2016-01-16', '2016-01-20'
UNION ALL SELECT 2, '2016-02-01', '2016-03-13'
UNION ALL SELECT 2, '2016-05-01', '2016-05-30'
UNION ALL SELECT 2, '2016-05-28', '2016-06-10';

WITH S AS (
 SELECT ID, BeginDate, MAX(EndDate) AS EndDate -- Select the starting ranges
 FROM @Data D
 WHERE NOT EXISTS(SELECT * FROM @Data WHERE ID = D.ID AND BeginDate < D.BeginDate AND EndDate >= D.BeginDate)
 GROUP BY ID, BeginDate
UNION ALL
 SELECT S.ID, S.BeginDate, D.EndDate -- recursively expand the ranges
 FROM S
 INNER JOIN @Data D ON S.ID = D.ID
   AND D.BeginDate BETWEEN S.BeginDate AND S.EndDate
   AND D.EndDate > S.EndDate
)
SELECT ID, BeginDate, MAX(EndDate)
FROM S
GROUP BY ID, BeginDate;

Thursday, December 3, 2015

Starting a numbered list at a different number in Gmail or other web email client

I recently was sending a colleague a series of questions across multiple emails and I wanted to continue numbering the list where the previous email left off. The rich text editor used by Gmail doesn't have this built-in (not that I can find at least), but I figured out a way using my trusty browser tools.

I'm a web developer so using the browser tools is perfectly normal for me on an average day, but although this might be unfamiliar, it's fairly easy to accomplish.

  1. If you haven't done so already, open your formatting tools by clicking the A button in the toolbar, then insert the ordered list by clicking the "1 2 3" icon.
  2. Right-click your list and choose "Inspect element". If your browser doesn't have "Inspect element" or another "Inspect" option, you can press F12 to open the browser tools then click the button in the top left - this lets you then click the list to select it.
  3. You'll see the HTML of the current page. The <ol> tag is what you're looking for. Your tools might have auto-selected an <li> instead, in which case you'd look for the parent.
  4. Right-click the <ol> tag and choose "Add Attribute".
  5. Type "start=N" (no quotes) where N is the number you want to start with

Your browser should update immediately and you'll see the new number as your starting point.

Monday, August 10, 2015

David Hasselhoff Screensaver

It's good sense to lock your computer when you're away. My co-workers have a habit of punishing those who don't by changing their desktop background to a picture of David Hasselhoff (usually the one where he's naked holding a puppy), a practice known as "Hoffing". I decided to go one further and create a screensaver that displays mister Hasselhoff in all his glory.

This is the result. Extract the file on your victim's computer, right-click the .scr file and choose "Install". And here is the source code in case you're worried about malicious code (or just want to see how it works). I leaned heavily on the code from Frank McCown at http://www.harding.edu/fmccown/screensaver/screensaver.html.

Update 2015-09-17 - I found that the previous version was crashing when trying to move the image. I've uploaded new versions of the .scr and source code (same links) to resolve the issue.

Sunday, September 14, 2014

Star Wars: Commander

I've Meanwhile, the non-optional PvP element is basically just stealing the hard-earned resources of other players. he real goal of these games though is to get you to buy whatever points they're selling in order to speed things up. This goal results in gameplay that just isn't fun.

Don't get me wrong, they're totally addicting. That's the whole point. Each stage opens up a new thing that makes you a little bit more powerful so you keep thinking "now I can do This", but each stage of the game takes longer and longer and ultimately, nothing really changes. You're still do the same thing over and over again. It's addicting, but I get no joy in the experience. It's just hard to stop.

Meanwhile, the non-optional PvP element is basically just stealing the hard-earned resources of other players. You log into the game to find another player has stolen resources it took you hours or even days to gather. Sure, you can attack them back, but them you lose the temporary protection obtained by having your base destroyed. And what's the point? Now they've lost time and resources.

This experience could be totally turned around by adding some additional strategy or RTS elements. As is, your attack units are completely mindless. After dropping them on the battlefield, you have no control over their behavior. They'll attack random (and strategically worthless) walls while being fired upon (and destroyed) by enemy units. Your defenses seem woefully underpowered (at least that's my experience) at repelling invading players. A single enemy unit was capable of taking down both shield generators and three turrets before being reinforced by the rest of the army for wiping out the rest of the base.

OK, rant over. And so is my time with this game.

Monday, September 8, 2014

Dynamically Changing the Color of SVG Using an ASP.NET HttpHandler

I have an SVG file that I'm using as the background image of elements on the page (using sprites). I wanted to dynamically update the color of the shapes and paths when theming the application, but I could not find a way to do this using CSS when the SVG is loaded as a background image (I have heard that inline <svg> elements will inherit style rules).

The way I solved the issue was to use a custom HttpHandler in my ASP.NET application that allows me to replace parts of the SVG with other content. Here's the code I used:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web;

namespace MyNamespace
{
 public class DynamicSVGHandler : IHttpHandler
 {
  public bool IsReusable
  {
   get
   {
    return true;
   }
  }

  public void ProcessRequest( HttpContext context )
  {
   var request = context.Request;
   var response = context.Response;

   var file = context.Server.MapPath( Path.ChangeExtension( request.Url.LocalPath, ".svg" ) );

   if( File.Exists( file ) )
   {
    var lastWrite = File.GetLastWriteTimeUtc( file );
    response.Clear();
    response.ContentType = "image/svg+xml";
    response.Cache.SetExpires( DateTime.Now.AddMinutes( 5d ) );
    response.Cache.SetCacheability( HttpCacheability.Public );

    List<KeyValuePair<string, string>> replacements = new List<KeyValuePair<string, string>>();

    string value;

    foreach( string key in request.QueryString )
    {
     if( key.Length > 3 && !string.IsNullOrEmpty( value = request.QueryString[key] ) && value.Length > 3 )//Implement any custom validation here.
      replacements.Add( new List<KeyValuePair<string, string>>( key, value ) );
    }

    if( replacements.Count > 0 )
    {
     string line;
     using( StreamReader reader = new StreamReader( File.OpenRead( file ) ) )
     {
      while( (line = reader.ReadLine()) != null )
      {
       foreach( var replacement in replacements )
        line = line.Replace( replacement.Key, replacement.Value );

       response.Output.WriteLine( line );
      }
     }
    }
    else
     response.WriteFile( file );
   }
   else
   {
    response.Clear();
    response.StatusCode = 404;
    response.End();
   }
  }
 }
}

Make sure to register your handler in your web.config (This example is for IIS 7+, integrated mode and I used the extension .dsvg):

<configuration>
 <system.webServer>
  <handlers>
   <add name="*.dsvg" path="*.dsvg" preCondition="integratedMode" verb="*" type="MyNamespace.DynamicSVGHandler, MyAssembly"/>
  </handlers>
 </system.webServer>
</configuration>

You can now reference any svg file in your application with the extension .dsvg instead of .svg and specify replacements in the URL (e.g. mysvg.dsvg?white=red to change "white" to "red").

In my SVG, I found it easiest to define the color using a style section rather than setting the fill of each shape, then add the class="svg-shape" to all the shapes.

Thursday, March 13, 2014

Changing the Color of Table and Column Names in SQL Server Management Studio 2012

If you've upgraded to SQL Server 2012 and used the new Management Studio, you've probably noticed that your table and column names are now a teal color that looks exactly like the color of your comments. Previous versions of Management Studio would use the color specified for "Plain Text", but the new version uses a new setting.

To change the color, open the Tools menu and choose Options.... In the Environment settings click Fonts and Colors. Locate and click "Identifier" in the Display Items list box then change the Item foreground to something other than Default. That should do the trick.