func PrintMemoryStats() {
	var mem runtime.MemStats
	log := log.New(os.Stdout, "", log.LstdFlags)
	log.Println("Printing memory stats...")
	runtime.ReadMemStats(&mem)
	log.Println("Alloc: ", mem.Alloc)
	log.Println("Total alloc: ", mem.TotalAlloc)
	log.Println("Heap alloc:", mem.HeapAlloc)
	log.Println("Heap system:", mem.HeapSys)
}
Print out memory usage
package gostuff
import (
	"bufio"
	"fmt"
	"image"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"time"
	"github.com/disintegration/imaging"
	"github.com/jonpchin/archiver"
)
func IsDirectory(path string) bool {
	f, err := os.Open(path)
	if err != nil {
		return false
	}
	stat, err := f.Stat()
	return stat.IsDir()
}
func IsFileExist(path string) bool {
	isExist := true
	_, err := os.Stat(path)
	if err != nil {
	}
	if os.IsNotExist(err) {
		isExist = false
	}
	return isExist
}
func compress(destination string, source []string) bool {
	err := archiver.Zip.Make(destination, source)
	if err != nil {
		fmt.Println("util.go compress There was an error in compressing the file", err)
		return false
	}
	return true
}
func unzip(source string, destination string) bool {
	err := archiver.Zip.Open(source, destination)
	if err != nil {
		fmt.Println("util.go unzip There was an error in archiving the file", err)
		return false
	}
	return true
}
func ReplaceString(target, desired, source string) bool {
	input, err := ioutil.ReadFile(source)
	if err != nil {
		fmt.Println("Failed to replaceString 1 util.go", err)
		return false
	}
	lines := strings.Split(string(input), "\n")
	for i, line := range lines {
		if strings.Contains(line, target) {
			lines[i] = strings.Replace(lines[i], target, desired, -1)
		}
	}
	output := strings.Join(lines, "\n")
	err = ioutil.WriteFile(source, []byte(output), 0644)
	if err != nil {
		fmt.Println("Failed to replaceString 2 util.go", err)
		return false
	}
	return true
}
func ResizeImages() {
	var gopherPath = "./img/gophers/gopher.png"
	var gamePath = "./img/screenshots/game.png"
	var gameTargetPath = "./img/screenshots/gameResize.png"
	var lobbyPath = "./img/screenshots/lobby.png"
	var lobbyTargetPath = "./img/screenshots/lobbyResize.png"
	var profilePath = "./img/screenshots/profile.png"
	var profileTargetPath = "./img/screenshots/profileResize.png"
	var settingsPath = "./img/screenshots/settings.png"
	var settingsTargetPath = "./img/screenshots/settingsResize.png"
	var screenShotWidth = 600
	var screenShotHeight = 337
	resizeImage(gopherPath, gopherPath, 800, 409)
	resizeImage(gamePath, gameTargetPath, screenShotWidth, screenShotHeight)
	resizeImage(lobbyPath, lobbyTargetPath, screenShotWidth, screenShotHeight)
	resizeImage(profilePath, profileTargetPath, screenShotWidth, screenShotHeight)
	resizeImage(settingsPath, settingsTargetPath, screenShotWidth, screenShotHeight)
}
func resizeImage(path string, targetPath string, desiredWidth int, desiredHeight int) {
	problems, _ := os.OpenFile("logs/errors.txt", os.O_APPEND|os.O_WRONLY, 0666)
	defer problems.Close()
	log.SetOutput(problems)
	image, err := imaging.Open(path)
	if err != nil {
		log.Println(err)
		return
	}
	var width int
	var height int
	exists := IsFileExist(targetPath)
	if exists {
		width, height = getImageDimensions(targetPath)
	} else {
		os.Rename(path, path)
		width, height = getImageDimensions(path)
	}
	if width != desiredWidth || height != desiredHeight {
		resizedImage := imaging.Resize(image, desiredWidth, desiredHeight, imaging.Lanczos)
		err := imaging.Save(resizedImage, targetPath)
		if err != nil {
			log.Println(err)
			return
		}
	}
	fmt.Println("Images successfully resized")
}
func getImageDimensions(imagePath string) (int, int) {
	problems, _ := os.OpenFile("logs/errors.txt", os.O_APPEND|os.O_WRONLY, 0666)
	defer problems.Close()
	log.SetOutput(problems)
	file, err := os.Open(imagePath)
	defer file.Close()
	if err != nil {
		log.Println(err)
	}
	image, _, err := image.DecodeConfig(file)
	if err != nil {
		log.Println(err)
	}
	return image.Width, image.Height
}
func TimeOutHttp(seconds time.Duration) http.Client {
	return http.Client{
		Timeout: time.Duration(seconds * time.Second),
	}
}
func IsFloatEqual(a, b float64) bool {
	var EPSILON float64 = 0.00000001
	if (a-b) < EPSILON && (b-a) < EPSILON {
		return true
	}
	return false
}
func HasTimeElapsed(targetTime string, timeCompare int, timeFormat string, useHour bool) (bool, int) {
	log := log.New(os.Stdout, "", log.LstdFlags|log.Lshortfile)
	then, err := time.Parse(timeFormat, targetTime)
	if err != nil {
		log.Println(err)
		return false, 0
	}
	duration := time.Now().Sub(then)
	var timeZoneDiff float64
	if isWindows {
		timeZoneDiff = 14400.0
	} else {
		timeZoneDiff = 0
	}
	var timeDiff int
	if useHour {
		timeDiff = int(duration.Hours())
	} else {
		timeDiff = int(duration.Seconds() - timeZoneDiff)
	}
	if timeDiff < timeCompare {
		return false, timeDiff
	}
	return true, 0
}
func timeTrack(start time.Time, name string) {
	log := log.New(os.Stdout, "", log.LstdFlags|log.Lshortfile)
	elapsed := time.Since(start)
	log.Printf("%s took %s", name, elapsed)
}
func ValidateJSONFiles() {
	RecurseDirectory("data", validateJSONFile, "*.json")
	RecurseDirectory("mud/equipment", validateJSONFile, "*.json")
}
func validateJSONFile(file string) {
	log := log.New(os.Stdout, "", log.LstdFlags|log.Lshortfile)
	var output []byte
	var err error
	if runtime.GOOS == "windows" {
		output, err = exec.Command("jsonlint", "-q", "-c", file).CombinedOutput()
	} else {
		output, err = exec.Command("/bin/bash", "-c", "jsonlint -q -c "+file).Output()
	}
	if err != nil {
		log.Println(err)
	}
	if string(output) != "" {
		log.Println(string(output))
	}
}
func RecurseDirectory(searchDir string, fp func(string), pattern string) {
	log := log.New(os.Stdout, "", log.LstdFlags|log.Lshortfile)
	fileList := []string{}
	err := filepath.Walk(searchDir, func(path string, f os.FileInfo, err error) error {
		fileList = append(fileList, path)
		return nil
	})
	if err != nil {
		log.Println(err)
	}
	for _, file := range fileList {
		isDir := IsDirectory(file)
		if isDir == false {
			isMatch, err := filepath.Match(pattern, filepath.Base(file))
			if err != nil {
				log.Println(err)
			} else if isMatch {
				fp(file)
			}
		}
	}
}