Unity Quickies: Zooming, Dragging, and Panning the Camera in 3D Space

Here is a script I wrote which you can apply to your existing 3D camera in order to perform various functions such as zooming, dragging, or panning the main camera. It worked best for me in a chess game I was writing while learning Unity, in which I had to display a chess board to the user and allow him to move around the board inside of the game.

using UnityEngine;

public class Scene : MonoBehaviour
{

    Vector3 lastDragPosition, lastPanPosition;

    void Update()
    {
        UpdateZoom();
        UpdateDrag();
        UpdatePan();
    }

    void UpdateZoom()
    {
        var isMoving = Mathf.Abs(Input.mouseScrollDelta.y) > 0;
        if (!isMoving)
            return;
        var isZoomingIn = Input.mouseScrollDelta.y > 0;
        transform.position = transform.position +
                             transform.forward.normalized * Time.deltaTime * (isZoomingIn ? 15f : -15f);
    }

    void UpdateDrag()
    {
        if (Input.GetMouseButtonDown(2))
            lastDragPosition = Input.mousePosition;
        if (!Input.GetMouseButton(2))
            return;
        var delta = lastDragPosition - Input.mousePosition;
        transform.Translate(delta * Time.deltaTime * 0.5f);
        lastDragPosition = Input.mousePosition;
    }

    void UpdatePan()
    {
        if (Input.GetMouseButtonDown(1))
            lastPanPosition = Input.mousePosition;
        if (!Input.GetMouseButton(1))
            return;
        var delta = lastPanPosition - Input.mousePosition;
        transform.RotateAround(transform.position, Vector3.up, delta.normalized.x * Time.deltaTime * 25f);
        transform.RotateAround(transform.position, transform.right, -delta.normalized.y * Time.deltaTime * 25f);
        lastPanPosition = Input.mousePosition;
    }
}

How to Find the Hash Rate of a GPU for Mining Ethereum on Windows

I have a laptop with the GeForce GTX 980M on it. I want to find out what my hash rate is to see what my profits could be from mining Ethereum over the Windows platform. Here’s how to do this:

  • Download the latest release of ethminer. Make sure to download the Latest release and not the Pre-release. Unzip it somewhere.
  • Open the command prompt to where you downloaded and unzipped ethminer. Run the ethminer -U -M command:
 C:\Downloads\ethminer-0.11.0-Windows>ethminer -U -M
 Using grid size 8192, block size 128
 Benchmarking on platform: CUDA
 Preparing DAG for block #0
 Warming up...
 i 13:04:52|cudaminer0 set work; seed: #00000000, target: #000000000000
 i 13:04:52|cudaminer0 Initialising miner...
 Using device: GeForce GTX 980M (Compute 5.2)
 Generating DAG for GPU #0
 CUDA#0: 0%
 CUDA#0: 6%
 CUDA#0: 13%
 CUDA#0: 19%
 CUDA#0: 25%
 CUDA#0: 31%
 CUDA#0: 38%
 CUDA#0: 44%
 CUDA#0: 50%
 CUDA#0: 56%
 CUDA#0: 63%
 CUDA#0: 69%
 CUDA#0: 75%
 CUDA#0: 81%
 CUDA#0: 88%
 CUDA#0: 94%
 Trial 1... 13277536
 Trial 2... 12578719
 Trial 3... 13273113
 Trial 4... 12570341
 Trial 5... 13277536
 min/mean/max: 12570341/12995449/13277536 H/s
 inner mean: 13043122 H/s
  • The inner mean is your hash rate. I’m sitting at about 13043122 H/s, which according to some online mining profitability calculator, could earn me about $30.45 / month if I don’t have to pay for electricity.

What is char ** in C or C++? Explaining Functions that Return char **

I just came across a weird API method in a C library for Windows that returned a list of strings as char **. Obviously, to read this back you need to know when to stop enumerating, so it told me this list is NULL terminated (terminated by a NULL pointer). Pretty cool, but I had no clue how to even allocate or to free this data type properly so I set up to create a proper example in a Visual C++ console application, since I couldn’t find any good articles on this online. So, effectively this list lives as a pointer to a pointer to a string. Here is how you can create one, read one back, and free one:

#include "stdafx.h"
#include <malloc.h>
#include <string.h>
 
char ** get_list() {
    char **result = (char **)malloc(3 * sizeof(char *));
    char *valueOne = new char[14];
    strcpy_s(valueOne, 14, "Hello, world.");
    result[0] = valueOne;
    char *valueTwo = new char[14];
    strcpy_s(valueTwo, 14, "Hello, again.");
    result[1] = valueTwo;
    result[2] = NULL;
    return result;
}
 
void free_list(char **list) {
    int i = 0;
    while (true) {
        char *value = *(list + i);
        if (value == NULL)
            break;
        delete[] value;
        i++;
    }
    free(list);
}
 
int main()
{
    char **list = get_list();
    int i = 0;
    while (true) {
        char *value = *(list + i);
        if (value == NULL)
            break;
        printf(value);
        printf("\n");
        i++;
    }
    free_list(list);
    return 0;
}

Hopefully you won’t have to spend a few hours on this like I just did. In addition, you would only use such a structure in production if you knew that none of your strings are ever to be NULL, or else they’d be mistaken for the NULL terminator and your deallocation method will fail miserably.

From Coding to Optics with the Sony a7R II

I feel its time to take a short break from blogging about code, so here are some photos. I took them recently on my Sony a7R II (man, what a camera). I shot them quite exclusively with either the Tamron SP 150-600MM F/5-6.3 Di VC USD lens using the LA-EA3 35mm Full-Frame A-Mount Adapter or via the Sony Vario-Tessar T* FE 16–35 mm F4 ZA OSS lens. Note that some of these Jay’s baseball game shots were literally up in the nosebleeds. I don’t think we could have gotten seats any further from the action.

Leveraging Func<Task> and Getting Funky

Asynchronous programming is a bit nightmarish, but hopefully this sheds some light upon how you can leverage certain delegate types. Take this example, where you want an abstraction layer for calling a block of code up to a set number of attempts until it succeeds, otherwise having it delegate back the exception you’ve obtained on the very last attempt:

class Program
{
	static void Main(string[] args)
	{
		// Since this is a console application, I just ran everything inside of an async task.
		Task.Run(async () => {
			bool throwException = true;
			var firstResult = await AttemptBlock.Run(async () => {
				Console.WriteLine("X called.");
				if (throwException)
				{
					throwException = false;
					throw new Exception();
				}
				await AttemptBlock.Run(async () =>
				{
					Console.WriteLine("Y called.");
					await Z();
					Console.WriteLine("Y finished.");
				}, 3, async (exception) =>
				{
					await Task.Run(() =>
					{
						Console.WriteLine("Y exception handler called.");
					});
				});
				Console.WriteLine("X finished.");
			}, 3, async (exception) =>
			{
				await Task.Run(() =>
				{
					Console.WriteLine("X exception handler called.");
				});
			});
			Console.WriteLine("Finished the first block with {0}.", firstResult);
			var secondResult = await AttemptBlock.Run(async () =>
			{
				Console.WriteLine("O called.");
				await Z();
				throw new Exception();
			}, 3, async (exception) =>
			{
				await Task.Run(() =>
				{
					Console.WriteLine("O exception handler called.");
					throw new Exception();
				});
			});
			Console.WriteLine("Finished the second block with {0}.", secondResult);
		});
		Console.ReadLine();
	}

	private async static Task<bool> Z()
	{
		Console.WriteLine("Z called.");
		await Task.Delay(1000);
		Console.WriteLine("Z finished.");
		return true;
	}
}

class AttemptBlock
{
	public async static Task<bool> Run(Func<Task> function, int attempts, Func<Exception, Task> handler = null)
	{
		while (attempts > 0)
		{
			var candidate = (Exception)null;
			try {
				await function();
				return true;
			} // If this try-catch block was not here, the function could deadlock if it threw an exception.
			catch (Exception exception) {
				candidate = exception;
			}
			attempts--;
			if (attempts <= 0 && handler != null && candidate != null)
				try {
					await handler(candidate);
				}
				catch { } // If this try-catch block was not here, the handler could deadlock if it threw an exception.
		}
		return false;
	}
}

The output is as follows:

X called.
X called.
Y called.
Z called.
Z finished.
Y finished.
X finished.
Finished the first block with True.
O called.
Z called.
Z finished.
O called.
Z called.
Z finished.
O called.
Z called.
Z finished.
O exception handler called.
Finished the second block with False.

You may also want to check out this post on Synchronous and Asynchronous Delegate Types.

Using Google’s reCAPTCHA Version 2.0 on ASP.NET MVC with AJAX

So, you want to add the latest reCAPTCHA Version 2.0 to your existing MVC website, you want to make it secure with server-side validation, and you want to make it asynchronous and have a rich user experience with AJAX? No problem. Start by adding div’s into the forms you need. Their ID’s will indicate where we want to place CAPTCHA elements. Note for all intents and purposes I am using two different CAPTCHA elements on the same page, just to illustrate it can be done, and done nicely:

<form id="register-form">
    <div id="register-captcha"></div>
    <button id="register-button" type="button" class="btn btn-default">Register</button>
</form>
<form id="contact-form">
    <div id="contact-captcha"></div>
    <button id="contact-button" type="button" class="btn btn-default">Send</button>
</form>

Then wire these up. Take note of how the reCAPTCHA API allows us to tell it what loading method to use and what type of rendering we want (explicit, in this case). This is very important, as it allows us to control the CAPTCHA in JavaScript. Also, make sure to include your site key in the rendering calls:

@section Scripts
{
    <script type='text/javascript'>
        // CAPTCHA loading methods.
        var registrationCaptchaID = null;
        var contactCaptchaID = null;
        var loadCaptcha = function () {
            registrationCaptchaID = grecaptcha.render('register-captcha', {
                'sitekey': '1234567890123456789012345678901234567890',
                'callback': function (response) {
                    registrationCaptchaResponse = response;
                }
            });
            contactCaptchaID = grecaptcha.render('contact-captcha', {
                'sitekey': '1234567890123456789012345678901234567890',
                'callback': function (response) {
                    contactCaptchaResponse = response;
                }
            });
        };
        // Register CAPTCHA section.
        var registrationCaptchaResponse = null;
        $('#register-button').click(function () {
            if (registrationCaptchaResponse == null)
                return;
            $.ajax({
                url: '@Url.Action("Register", "Home")',
                type: 'POST',
                data: {
                    recaptchaResponse: registrationCaptchaResponse
                },
                success: function (data, textStatus, jqXHR) {
                    registrationCaptchaResponse = null;
                    grecaptcha.reset(registrationCaptchaID);
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    registrationCaptchaResponse = null;
                    grecaptcha.reset(registrationCaptchaID);
                }
            });
        });
        // Contact CAPTCHA section.
        var contactCaptchaResponse = null;
        $('#contact-button').click(function () {
            if (contactCaptchaResponse == null)
                return;
            $.ajax({
                url: '@Url.Action("Contact", "Home")',
                type: 'POST',
                data: {
                    recaptchaResponse: contactCaptchaResponse
                },
                success: function (data, textStatus, jqXHR) {
                    contactCaptchaResponse = null;
                    grecaptcha.reset(contactCaptchaID);
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    contactCaptchaResponse = null;
                    grecaptcha.reset(contactCaptchaID);
                }
            });
        });
    </script>
    <script src="https://www.google.com/recaptcha/api.js?onload=loadCaptcha&render=explicit" async defer></script>
}

To validate this on the server-side, first set up the secret key in your configuration’s application settings section so you can quickly modify on the fly later on when you need to:

<configuration>
  <appSettings>
    <add key="reCAPTCHASecret" value="1234567890123456789012345678901234567890" />
  </appSettings>
</configuration>

Make use of it on an action post, and call the reCAPTCHA service to manually verify the user-obtained results:

public class reCAPTCHAResponse
{
    public bool Success { get; set; }
}

[HttpPost]
public ActionResult Register(string recaptchaResponse)
{
    if (String.IsNullOrEmpty(recaptchaResponse))
        throw new InvalidOperationException("Missing CAPTCHA response.");
    var client = new WebClient();
    var secret = ConfigurationManager.AppSettings["reCAPTCHASecret"];
    if (String.IsNullOrWhiteSpace(secret))
        throw new InvalidOperationException("Missing CAPTCHA configuration.");
    var response = client.DownloadString(String.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", secret, recaptchaResponse));
    var serializer = new JavaScriptSerializer();
    var reCAPTCHA = serializer.Deserialize<reCAPTCHAResponse>(response);
    if (!reCAPTCHA.Success)
        throw new InvalidOperationException("Incorrect CAPTCHA response.");
    return Json(true); // At this point, the request is valid, and you can do whatever you wish.
}

That’s another case closed.

Client-Side File Generation and File Downloads on Modern Browsers

Sometimes, you just need an extension method to generate and download files from the client-side of most modern browsers. The only real takeaway from the code below is that Internet Explorer browser agents like to behave differently and require a different function call to provide this type of functionality. Other than that its pretty clear-cut, with most other modern browsers supporting the download attribute.

$(document).ready(function() {
    saveFile("Example.txt", "data:attachment/text", "Hello, world.");
});

function saveFile (name, type, data) {
    if (data != null && navigator.msSaveBlob)
        return navigator.msSaveBlob(new Blob([data], { type: type }), name);
    var a = $("<a style='display: none;'/>");
    var url = window.URL.createObjectURL(new Blob([data], {type: type}));
    a.attr("href", url);
    a.attr("download", name);
    $("body").append(a);
    a[0].click();
    window.URL.revokeObjectURL(url);
    a.remove();
}

Generating Self-Signed X509 Certificates in Vanilla .NET and C#

To generate a self-signed X509 certificate out of the box with vanilla .NET and C#, you will need to Platform Invoke the Cryptography library in Windows. You don’t need to use any third party libraries for this, Windows is perfectly capable of tackling this task for you. Wired up for using the SHA512 hashing algorithm, here is the code to make the magic happen:

public struct SystemTime
{
	public Int16 Year;
	public Int16 Month;
	public Int16 DayOfWeek;
	public Int16 Day;
	public Int16 Hour;
	public Int16 Minute;
	public Int16 Second;
	public Int16 Milliseconds;
}

public static class MarshalHelper
{
	public static void CheckReturnValue(Boolean nativeCallSucceeded)
	{
		if (!nativeCallSucceeded)
			Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
	}
}

public static class DateTimeExtensions
{
	[DllImport("kernel32.dll", SetLastError = true)]
	static extern Boolean FileTimeToSystemTime(ref Int64 fileTime, out SystemTime systemTime);

	public static SystemTime ToSystemTime(this DateTime dateTime)
	{
		Int64 fileTime = dateTime.ToFileTime();
		SystemTime systemTime;
		MarshalHelper.CheckReturnValue(FileTimeToSystemTime(ref fileTime, out systemTime));
		return systemTime;
	}
}

class X509Certificate2Helper
{
	[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
	static extern Boolean CryptAcquireContextW(out IntPtr providerContext, String container, String provider, UInt32 providerType, UInt32 flags);
	
	[DllImport("advapi32.dll", SetLastError = true)]
	static extern Boolean CryptReleaseContext(IntPtr providerContext, Int32 flags);
	
	[DllImport("advapi32.dll", SetLastError = true)]
	static extern Boolean CryptGenKey(IntPtr providerContext, Int32 algorithmId, Int32 flags, out IntPtr cryptKeyHandle);
	
	[DllImport("advapi32.dll", SetLastError = true)]
	static extern Boolean CryptDestroyKey(IntPtr cryptKeyHandle);
	
	[DllImport("crypt32.dll", SetLastError = true)]
	static extern Boolean CertStrToNameW(Int32 certificateEncodingType, IntPtr x500, Int32 strType, IntPtr reserved, Byte[] encoded, ref Int32 encodedLength, out IntPtr errorString);
	
	[DllImport("crypt32.dll", SetLastError = true)]
	static extern IntPtr CertCreateSelfSignCertificate(IntPtr providerHandle, ref CryptoApiBlob subjectIssuerBlob, Int32 flags, ref CryptKeyProviderInformation keyProviderInformation, IntPtr signatureAlgorithm, ref SystemTime startTime, ref SystemTime endTime, IntPtr extensions);
	
	[DllImport("crypt32.dll", SetLastError = true)]
	static extern Boolean CertFreeCertificateContext(IntPtr certificateContext);
	
	[DllImport("crypt32.dll", SetLastError = true)]
	static extern Boolean CertSetCertificateContextProperty(IntPtr certificateContext, Int32 propertyId, Int32 flags, ref CryptKeyProviderInformation data);

	public static X509Certificate2 GenerateSelfSignedCertificate(String name = "", DateTime? startTime = null, DateTime? endTime = null)
	{
		if (startTime == null || (DateTime)startTime < DateTime.FromFileTimeUtc(0))
			startTime = DateTime.FromFileTimeUtc(0);
		var startSystemTime = ((DateTime)startTime).ToSystemTime();
		if (endTime == null)
			endTime = DateTime.MaxValue;
		var endSystemTime = ((DateTime)endTime).ToSystemTime();
		String containerName = Guid.NewGuid().ToString();
		GCHandle dataHandle = new GCHandle();
		IntPtr providerContext = IntPtr.Zero;
		IntPtr cryptKey = IntPtr.Zero;
		IntPtr certificateContext = IntPtr.Zero;
		IntPtr algorithmPoInt32er = IntPtr.Zero;
		RuntimeHelpers.PrepareConstrainedRegions();
		try
		{
			MarshalHelper.CheckReturnValue(CryptAcquireContextW(out providerContext, containerName, null, 0x1, 0x8));
			MarshalHelper.CheckReturnValue(CryptGenKey(providerContext, 0x1, 0x20000001, out cryptKey));
			IntPtr errorStringPtr;
			Int32 nameDataLength = 0;
			Byte[] nameData;
			dataHandle = GCHandle.Alloc(name, GCHandleType.Pinned);
			if (!CertStrToNameW(0x10001, dataHandle.AddrOfPinnedObject(), 3, IntPtr.Zero, null, ref nameDataLength, out errorStringPtr))
			{
				String error = Marshal.PtrToStringUni(errorStringPtr);
				throw new ArgumentException(error);
			}
			nameData = new Byte[nameDataLength];
			if (!CertStrToNameW(0x10001, dataHandle.AddrOfPinnedObject(), 3, IntPtr.Zero, nameData, ref nameDataLength, out errorStringPtr))
			{
				String error = Marshal.PtrToStringUni(errorStringPtr);
				throw new ArgumentException(error);
			}
			dataHandle.Free();
			dataHandle = GCHandle.Alloc(nameData, GCHandleType.Pinned);
			CryptoApiBlob nameBlob = new CryptoApiBlob { cbData = (UInt32)nameData.Length, pbData = dataHandle.AddrOfPinnedObject() };
			dataHandle.Free();
			CryptKeyProviderInformation keyProvider = new CryptKeyProviderInformation { pwszContainerName = containerName, dwProvType = 1, dwKeySpec = 1 };
			CryptAlgorithmIdentifier algorithm = new CryptAlgorithmIdentifier { pszObjId = "1.2.840.113549.1.1.13", Parameters = new CryptoApiBlob() };
			algorithmPoInt32er = Marshal.AllocHGlobal(Marshal.SizeOf(algorithm));
			Marshal.StructureToPtr(algorithm, algorithmPoInt32er, false);
			certificateContext = CertCreateSelfSignCertificate(providerContext, ref nameBlob, 0, ref keyProvider, algorithmPoInt32er, ref startSystemTime, ref endSystemTime, IntPtr.Zero);
			MarshalHelper.CheckReturnValue(certificateContext != IntPtr.Zero);
			return new X509Certificate2(certificateContext);
		}
		finally
		{
			if (dataHandle.IsAllocated)
				dataHandle.Free();
			if (certificateContext != IntPtr.Zero)
				CertFreeCertificateContext(certificateContext);
			if (cryptKey != IntPtr.Zero)
				CryptDestroyKey(cryptKey);
			if (providerContext != IntPtr.Zero)
				CryptReleaseContext(providerContext, 0);
			if (algorithmPoInt32er != IntPtr.Zero)
			{
				Marshal.DestroyStructure(algorithmPoInt32er, typeof(CryptAlgorithmIdentifier));
				Marshal.FreeHGlobal(algorithmPoInt32er);
			}
		}
   	}

	struct CryptoApiBlob
	{
		public UInt32 cbData;
		public IntPtr pbData;
	}
	
	struct CryptAlgorithmIdentifier {
		[MarshalAs(UnmanagedType.LPStr)]
		public String pszObjId;
		public CryptoApiBlob Parameters;
	}
	
	struct CryptKeyProviderInformation
	{
		[MarshalAs(UnmanagedType.LPWStr)]
		public String pwszContainerName;
		[MarshalAs(UnmanagedType.LPWStr)]
		public String pwszProvName;
		public UInt32 dwProvType;
		public UInt32 dwFlags;
		public UInt32 cProvParam;
		public IntPtr rgProvParam;
		public UInt32 dwKeySpec;
	}
}

To call this class, specify the common name to your self-signed certificate, and actually get a certificate out of it (in PFX format with a simple password for it’s private key):

var certificate = X509Certificate2Helper.GenerateSelfSignedCertificate("CN = localhost");
File.WriteAllBytes(@"C:\Users\User\Desktop\Certificate.pfx", certificate.Export(X509ContentType.Pfx, "password"));

How to Bypass SSL Security Checks in Firefox

In Firefox, you can bypass SSL security checks in order to do local development on machines you trust the identity of. To do this:

  • Type about:config into the URL field of Firefox and hit the enter key.
  • Find security.tls.insecure_fallback_hosts, double click its value and type your domain(s) there. For example: localhost,dev.local.

This should resolve any Secure Connection Failed errors if you are seeing these on your development machines, but also, its not something you should do for any website out there, because it can easily compromise security.

How to Center an Image Vertically and Horizontally in HTML

It all depends on the size of the image. You need to set your top edge and left edge to 50%, then subtract half of the content size. So for example, my image below has a width of 300px, so I subtract 150px from the left edge by setting the left margin and do the same operation on the top margin.

<!DOCTYPE html>
<html>
<body>
	<div style="position:absolute;top:50%;margin-top:-179px;left:50%;margin-left:-150px;">
		<img src="image.png" width="300" height="358">
	</div>
</body>
</html>