Some final thoughts about “Jumble Attack”

“Jumble Attack” is now live on the Google Play Store, Amazon App Store, Apple Appstore and Facebook! From cradle to grave this little app took us about a month and a half to complete which isn’t too bad considering some of the new technologies we introduced into our game along with the authorizations we had to get from the government. I was a little concerned about the restrictions Apple places on their apps as it is sometimes difficult to get approval, but the approval went through the first time…it still took a good 7 days though from submissions until they approved it. Now that we’ve figured out how to encrypt data, include in-app purchases and communicate with a web server, we can concentrate on the content in our next game rather than how to make the technology work. We are pretty excited about our next project, but it is a lot larger than anything we’ve done thus far. If you like card games with a twist, stay tuned for more info about our next project, Kung Pow Cards!

Poor man’s HTTPS

If you are thinking of using HTTPS to communicate data or encrypting your data in your apps, please read this post first

What do you mean I have to be “properly authorized” to use encryption in my apps?

We were looking at adding some interaction between our mobile apps and our web server and wanted to use HTTPS for this so we’d have a layer of security on top of the communications. I had never setup HTTPS on a web server before, but knew a decent amount of what would have to go into it. So I started looking around cPanel and found the following icon under “Security”

SSL/TSL

After clicking this icon, we are taken to an area where we need to do three things. First is to generate a private key, the second is to create a Certificate Signing Request (CSR) and lastly, place a certificate on our server. Luckily the interface in this version of cPanel (v11.44.1 (build 18)) makes it pretty easy to do.

 

Screen Shot 2014-09-09 at 8.38.48 PM

Screen Shot 2014-09-09 at 8.38.18 PMAfter clicking on the “SSL/TSL” icon, Click on the link here to go to the next screen to generate a private key.  I just used our company name in the description. Once the private key is generated, make sure to save it to a file on your computer.

 

 

 

 

 

Screen Shot 2014-09-09 at 8.38.55 PMScreen Shot 2014-09-09 at 8.39.24 PM

For a Certificate Signing Request
(CSR), go back to the previous screen and click on the link to generate a CSR, select the description you chose in the previous step in the drop down box and fill out the rest of the information and generate your CSR. Again, save it to a text file.

 

Screen Shot 2014-09-09 at 8.39.01 PMScreen Shot 2014-09-09 at 8.40.05 PM

Once this is done, go back to the previous screen again and manage the certificates on your web server. Install a self signed certificate by filling out the information and selecting the key you want to use. Now, a self signed certificate will allow you to use HTTPS on your site BUT you’ll be greeted with an ugly warning message by the browser that the site could not be verified so the certificate could not be trusted. We’d need to send off the CSR we created in the previous step to a Certificate Authority (CA) to receive a verified certificate to remove that warning from the browser.

Well, we only need HTTPS for communications between our app and our web server; so a self signed certificate should be good enough since the user won’t be interacting directly with our website across HTTPS. I did a quick search to see how much a certificate would cost, they vary wildly but seeing stuff for $175/yr. Why spend money on something we don’t need immediately? But, we do have everything we need to get a valid certificate if we decide to use HTTPS for direct user interactions with our website. That is why I call this the poor man’s HTTPS.

Updated:

So I’ve now come across a site that offers free SSL certificates. WOO HOO! I’ve seen mixed reviews, some people swear by them, others don’t seem to like them very much. But I thought I’d give it a shot. The site is https://www.startssl.com. Since I already created my certificate with them, I can only go through the steps again so much.  But it should be enough to figure out. What got me looking at this again was since we are communicating data between our website and our app, the Unity Web Player relies on the browser and JavaScript to do that (More on that one in a later post). Since our web server was only using a self signed certificate for HTTPS, the browser was blocking/complaining about the JavaScript AJAX calls to our web server when running the app using the Unity Web Player. This makes sense, but it didn’t occur to me during development.

Login Page

Head on over to https://www.startssl.com/?app=12. Just click the “Sign-up” button to get started. Please note the first time I tried this, their site was having some overloading issues…I just patiently waited a bit and was able to get on after a while.

Sign Up

There really isn’t too much information here to fill out, but please READ CAREFULLY and take your time to make sure you’ve filled the information out properly. The reason I say this is because there appears to be a price on revoking an SSL cert. Once you’ve finish the sign up process, they’ll send you an email to confirm your account.

homeOnce you have verified your account, StartSSL asks to install a certificate in your browser so you can log in. So if you go to https://www.startssl.com, you should see a page similar to the following. If not, just click the “Authenticate” button.

 

manage-certsIt would be a good idea to back up this certificate they just gave you. In Chrome, you can do it this way: Go to “Settings”, then click the “Advanced” link at the bottom. Find HTTP/SSL “Manage Certificates” and click on it. Find the one for StartSSL and export it and keep it somewhere. This will allow you to reimport the certificate at a later time if you need to.

Validate Domain Name - Step 1

Now we need to let them know that we own the domain we are attempting to get a class 1 SSL cert for.  I don’t know exactly the differences between all the classes of SSL certs, but we only need a class 1 for our purpose. I do know that a Class 1 doesn’t support wildcard domains but it will support a top domain name and a sub-domain…in fact it asks you to specify a sub-domain later in the process. So, once you’ve navigated back to https://www.startssl.com, click on the “Validation Wizard” tab and select “Domain Name Validation” from the drop down box.

Validate Domain Name - Step 2

Just put in your domain name here, pretty easy really.

 

 

Validate Domain Name - Step 3

 

It takes a couple of seconds, but a list of email addresses associated with the domain name pop up. You have to have control over one of those email addresses so they can send you a link for domain verification. Just pick one from the list that you are in control of and click “Continue”. Again, I had some issues with this part of the process. It kept telling me it could not verify the email address.  So again, I waited and after a bit it worked. Once you get the email, follow the directions to verify that you own the domain.

Create SSL Cert - Step 1

Now we are able to create an SSL cert for our domain! Click on the “Certificates Wizard” tab at the top and select “Web Server SSL/TLS Certificate” from the drop down box.

 

Create SSL Cert - Step 2

 

From here we can create the keys we need to create our certificate…but we already did that earlier, so click the “Skip” button.Create SSL Cert - Step 3

 

 

Go and find the Certificate Signing Request (CSR) that you saved earlier…you DID save it, right? Simply open it up in a text editor, copy the contents and pate them into the provided box.  Make sure you get the header and footer! Continue following the directions to finish up. After a while (I think I waited about an hour), you’ll receive an email that says you now have a certificate.

 

Retrieve CertClick on the “Tool Box” tab there at the top and select “Retrieve Certificate” from the list of options on the left. After selecting the certificate, (it should already be selected) click the “Continue” button to reveal the certificate.  Copy and paste this info into a plain text file. Once you have this, go back to your web server and install the certificate just like you did for your self signed certificate. Then just remove your self signed certificate.  One of the things I noticed was that even though https://www.nikywilliams.com was covered under the SSL cert, https://www.nikywilliams.com was not. At the moment, this isn’t much of an issue since we don’t have any front facing websites that need HTTPS. Ideally, you’d want both covered under your certificate. Our app is the only thing accessing HTTPS and we can make sure https://www.nikywilliams.com is specified in the code. I’ve seen what looks like a few ways around this. 1) You’d have to get at least a Class 2 certificate so that you can secure both with and without the “www” prefix. 2) Find a way to redirect all https://www.nikywilliams.com requests to https://www.nikywilliams.com. I haven’t verified either way since it isn’t critical to what we are trying to accomplish. In any case, this is still a poor man’s HTTPS since we haven’t spent a dime!

How can I securely save my app data?

Before we look at encrypting data on a device, you may want to read up on this.

What do you mean I have to be “properly authorized” to use encryption in my apps?

Unity has this very nice feature of being able to easily store data on the device via “PlayerPrefs”. The only problem is that it is stored in plain text. If you don’t really care, then it’s not that big of a deal, but if you are caching information to send back to your web server because the user doesn’t have any internet connectivity at the time, then it could be an issue.  Especially if that data contains information you don’t want tampered with like scores, ranking, etc… We’ll take a look at some encrypting functions we can throw into our code that will make encrypting/decrypting information pretty trivial. I’ve pulled in this code from various places so I can’t take credit for most of it. We’ll be using the Triple DES encryption capabilities that we have access to and once done, this should also make it safe to send via POST to a web server without mangling the data since the final data is encoded to BASE64. I’ll have another post detailing how I setup app-to-web server communications here in a bit. I created a file named Crypt.cs and made all the functions static so that we could call these functions anywhere in our code. We just have to pass in what we want to encrypt and the key we will be using. So from anywhere in the code we can call something like:

// Encrypt the data
string data = "Something to encrypt";
string key = "your_key";
string encryptedData = Crypt.Encrypt(data, key);

// Decrypt the data
data = Crypt.Decrypt(encryptedData, key);

Something that bothered me is having the key all in one place like that. So, you could just have it split up in various places in your app and create a function to put the key back together again and pass that in. So, here is the code I used (for the most part) to do this, just take it and put it in a .cs file.


using UnityEngine;
using System;
using System.Collections;
using System.Security.Cryptography;
using System.Text;

public class Crypt : MonoBehaviour {

/**
 */
 private static string GetMd5Hash(MD5 md5Hash, string input) {
 // Convert the input string to a byte array and compute the hash.
 byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

 // Remove last 8 bytes to make it 192 bits (24 bytes) and compatible with the DES key property
 byte[] finalData = new byte[12];
 for (int i = 0; i < 12; i++) {
 finalData[i] = data[i];
 }

 // Create a new Stringbuilder to collect the bytes
 // and create a string.
 StringBuilder sBuilder = new StringBuilder();

 // Loop through each byte of the hashed data
 // and format each one as a hexadecimal string.
 for (int i = 0; i < finalData.Length; i++) {
 sBuilder.Append(finalData[i].ToString("x2"));
 }

 // Return the hexadecimal string.
 return (sBuilder.ToString());
 }

/**
 */
 public static string Encrypt(string data, string secret) {
 TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
 MD5 md5 = MD5.Create();

 string key = GetMd5Hash(md5, secret);
 byte[] finalKey = System.Text.Encoding.UTF8.GetBytes(key); 

 des.Mode = CipherMode.ECB;
 des.Key = finalKey;

 des.Padding = PaddingMode.PKCS7;
 ICryptoTransform DESEncrypt = des.CreateEncryptor();
 Byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(data);

 return (Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length)));
 } 

 /**
 */
 public static string Decrypt(string data, string secret) {
 TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
 MD5 md5 = MD5.Create();

 string key = GetMd5Hash(md5, secret);
 byte[] finalKey = System.Text.Encoding.UTF8.GetBytes(key); 

 des.Mode = CipherMode.ECB;
 des.Key = finalKey;

 des.Padding = PaddingMode.PKCS7;
 ICryptoTransform DESEncrypt = des.CreateDecryptor();
 Byte[] Buffer = Convert.FromBase64String(data.Replace(" ", "+"));

 return (Encoding.UTF8.GetString(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length)));
 }

}

Wrapping up Jumble Attack

This app was a particularly fun little project to work on for me. We introduced three new technologies as the main goal of this project was to figure out how to use those three technologies while still making a fun little game we could distribute. There were a lot of assets we were able to reuse from Shape Sprout so it made that part of the project go much more quickly. For our previous app, Shape Sprout, we included ads into our game using AdBuddiz which was relatively painless. For Jumble Attack, we added in-app purchases, data encryption and app-to-web server communication. The in-app purchases I think took the most time as they had to work on three different platforms: Apple App Store, Google Play Store and the Amazon Appstore. Each platform has a different way of allowing you to test those purchases without generating a real monetary transaction. Amazon seems to have given us the most trouble as the 3rd party plug in we were using, SOOMLA, has some issues with Amazon on their most recent update. We just went back to a previous version and all was well in the world. SOOMLA is actually pretty straightforward when integrating with the Unity platform and I have really enjoyed it so far, you can’t complain much for an open source plugin like this.  The setup required to make the in-app transactions happen can become pretty confusing; pretty soon I’ll have three new blogs on how to setup a store in Unity for each of the platforms, how we did the encryption and what we did to make the app-to-web site communications happen…including the extra steps you have to take when you want app-to-web site communications when playing your game through the Unity Web Player.  All very interesting stuff. We are in the last stages of testing Jumble Attack and hope to have it in the app stores very soon. We already know what our next project is going to be, so if you like cards, we know you’ll like Kung Pow Cards!

Why doesn’t my particle system show in front of my sprites??

Particle System Sort LayerThis one had me befuddled for a little while. I could not figure out why my particle system was not showing up in front of my sprites for the life of me. I had the “Layer” set properly but I could not find a place to set the “Sorting Layer”. I came across some other folks who were saying you had to set the sorting layer manually in code so the particle system would show up where it needed to (sorry, I can’t remember the references!). Okay, that seems easy enough, let’s see if we can figure that out. It looks like we can do that via the following code. The “sortingLayerName” is just a string of a sorting layer you have defined in Unity and the “sortingOrder” is an integer that specifies the z-order in that sorting layer. The higher the number, the closer the object “looks” to you.


particleSystem.renderer.sortingLayerName = sortingLayerName;
particleSystem.renderer.sortingOrder = sortingOrder;

So now let’s just make this into a script so we can easily apply it to all particle systems we create.

I put the following code into a file named “ParticleSystemFix.cs” and attached it to any particle systems I create.

using UnityEngine;
using System.Collections;

public class ParticleSystemFix : MonoBehaviour {

public string sortingLayerName;
public int sortingOrder;

/**
 */
void Start() {
    particleSystem.renderer.sortingLayerName = sortingLayerName;
    particleSystem.renderer.sortingOrder = sortingOrder;
    enabled = false;
  }
}

I’ll usually tell a script to disable itself once it is done initializing or if the code in the Update() function starts to be skipped because of a certain condition. I’m sure there has to be a slight performance advantage to doing this…every little bit helps.  Plus it lets me know if something is executing properly when I expect the script to become disabled.

Particle System Sort LayerNow, just attach this script to any particle system; there in the inspector, you can define a “sortingLayerName” and “sortingOrder” on the “ParticleSystemFix”.  I used a large number like 999 as my “sortingOrder” since I want my particle systems to appear on top of all my sprites.

 

 

Particle System Sort LayerMake sure that what you pass into the “sortingLayerName” is defined in Unity!

That is about it, as long as the “sortingLayerName” for your particle system is where it needs to be hierarchically, your particle system should appear on top of the sprites.

 

 

 

 

Okay, I’ve got my game built for the Unity Web Player, now what?

Unity has some pretty cool stuff. It can build your app for a multitude of platforms to which they seem to be constantly adding to. One of the things you are able to do is build your game for the web using the Unity Web Player. When we first started, I was using LibGDX and by using it plus some other tools, I could export my project to WebGL. At that point in time, WebGL was not fully supported on all browser so our game did not have the compatibility that we wanted it to. Unity uses its own plugin and seems to be compatible with all major browsers. I’ve tried it on IE, Chrome, Firefox, Safari and Opera. It seems to work the same on all the browsers. Now, how exactly do we publish said game for others to access? We wanted a presence on Facebook with our games as well as on mobile platforms. Mobile being our primary target of course. I began to do some research into Facebook apps and how exactly they worked. So, I headed on over to https://developers.facebook.com to get started. I believe you have to register with them to become a developer…its been a while since I did that part.

fbCreateAppfbCreateApp2Once you are logged in, the first thing to do is to create a new application, just select “Apps” from the top menu and then “Create New App”. Fill out the info as needed to get the skeleton of your app created.

At this point, we don’t have much, just that we’ve told Facebook we want to create an app and this is what it is going to be called. The next part is we need to figure out how we are going to host our game for Facebook to reference. Facebook doesn’t actually host the game itself, that is up to us in how we do it. There are two ways you can do this. If you have your own web server, you can point Facebook to where the main file resides or if you don’t, you can use Dropbox (or probably any number of other online storage) to host your game. I’ll cover both methods here. First I’ll talk about Dropbox, you’ll need an account if you don’t already have one. Once you have it setup and ready to go, log into your Dropbox account online and create a “Public” folder. You don’t have to have this, but it helps me to keep stuff separated. Inside there create another directory for your game you want to host. Once that is done, move your .unity3d and the .html file into this directory. Right click on your .html file and select “Copy public link”.  This will give you a box with a link that looks something like:

dbLink

 

 

 

Copy this link to use in your Facebook app. Going back over to Facebook, we need to start filling things out. Select your app from the “Apps” menu at the top if you haven’t already and start with the “App Details” from the menu on the left.

fbAppDetailsThere is quite a bit of info here to fill out, but take your time and fill it out as detailed as possible. I usually use a lot of the same descriptions and info I use when I place our apps on iTunes, Google Play or Amazon.

 

 

 

 

 

fbSettingsAfter this, head on over to the “Settings”. This is where you connect your app to Facebook so it knows how to run it.

For the “App Domains” section, use “dl.dropboxusercontent.com”.

Now, click the “Add Platform” button at the bottom and chose “Facebook Canvas” from the selections presented. There are quite a few others here you can use as well.

When the properties for the Facebook Canvas appears, you have a “Canvas URL” and a “Secure Canvas URL”. Remember that link I said to save from Dropbox? Yup, we use it here…with one small addition. Make sure to put a “?” at the end of the URL you get from Dropbox. The Facebook Canvas expects the URL to be “dynamic”, so I guess this appeases what it wants. Use HTTP for the “Canvas URL” and HTTPS for the “Secure Canvas URL”. Click “Save Changes” at the bottom and you are pretty much done! Look at the “Canvas Page” property at the top of the “Facebook Canvas” window there to get the URL of your Facebook app. Copy and paste that into your web browser and you should now have an application on Facebook. This was the simplest way I could see for getting our app on Facebook.

Now, if you have your own web server, the process is very similar to that of Dropbox. Copy your game files to your web server and follow the general directions above and that is pretty much it. I renamed the .html file to “index.html” so I wouldn’t have to specify an .html file and I renamed the .unity3d to something a bit more web server friendly (be sure to change the reference in your .html file). You will need an HTTPS server, however, since the Facebook Canvas operates on HTTPS and the browser will warn you that the connection is not secure if you attempt to just use the HTTP link. The only other change is to be sure the “App Domain” at the top of the settings is your domain and not Dropbox.

If Facebook was our primary target, I’d probably spend a lot more time actually integrating Facebook functions into our game along with using “Open Graph” more. Maybe further down the road we will do this, but for now, this works.