コード例 #1
0
ファイル: loginServer.go プロジェクト: gk-turnip/server
func LoginServerStart() {

	var fileName *string = flag.String("config", "", "config file name")
	var loginConfig loginConfigDef
	var gkErr *gkerr.GkErrDef

	flag.Parse()

	if *fileName == "" {
		flag.PrintDefaults()
		return
	}

	loginConfig, gkErr = loadConfigFile(*fileName)
	if gkErr != nil {
		fmt.Printf("error before log setup %s\n", gkErr.String())
		return
	}

	gklog.LogInit(loginConfig.LogDir)
	gkErr = loginConfig.loginInit()
	if gkErr != nil {
		gklog.LogGkErr("loginConfig.loginInit", gkErr)
		return
	}

	address := fmt.Sprintf(":%d", loginConfig.Port)

	http.ListenAndServe(address, &loginConfig)
}
コード例 #2
0
ファイル: gkLog.go プロジェクト: gk-turnip/server
func logAll(level int, message string, argErr error, argGkErr *gkerr.GkErrDef) {
	if _logDir == "" {
		fmt.Printf("missing call to gklog.LogInit()\n")
		return
	}

	var levelString string = "Unknown"

	switch level {
	case _trace:
		levelString = "Trace"
	case _error:
		levelString = "Error"
	}

	var fileName string
	var file *os.File
	var err error

	now := time.Now()
	dateName := fmt.Sprintf("%04d_%02d_%02d", now.Year(), now.Month(), now.Day())
	timeStamp := fmt.Sprintf("%02d %02d %02d:%02d:%02d.%02d", now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), now.Nanosecond()/10000000.0)
	fileName = _logDir + string(os.PathSeparator) + dateName + _logSuffix

	file, err = os.OpenFile(fileName, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
	if err != nil {
		fmt.Printf("could not open output log file: %s\n", fileName)
		return
	}

	defer file.Close()

	totalMessage := timeStamp + " " + levelString + " " + message
	if err != nil {
		totalMessage = totalMessage + " " + fmt.Sprintf("[%v]", err)
	}
	if argGkErr != nil {
		totalMessage = totalMessage + " <" + argGkErr.String() + ">"
	}

	totalMessage = totalMessage + "\n"

	_, err = file.Write([]byte(totalMessage))
	if err != nil {
		fmt.Printf("could not write log file: %s\n", fileName)
		return
	}
}
コード例 #3
0
ファイル: svg_test.go プロジェクト: gk-turnip/server
func testSvgHighLevel(t *testing.T) {
	var gkErr *gkerr.GkErrDef

	var inputData []byte = []byte(svgInputData1)
	var result []byte

	result, gkErr = FixSvgData(inputData, "pre")
	if gkErr != nil {
		t.Logf("FixSvgData failure " + gkErr.String())
		t.Fail()
	}

	if string(result) != svgOutputData1 {
		t.Logf("FixSvgData did not match in: " + svgInputData1 + "\n out: " + string(result) + "\n exp: " + svgOutputData1 + "\n")
		t.Fail()
	}
}
コード例 #4
0
ファイル: fixSvgMain.go プロジェクト: gk-turnip/server
func main() {

	var inputFileName *string = flag.String("in", "", "svg input filename")
	var outputFileName *string = flag.String("out", "", "svg output filename")

	flag.Parse()

	if (*inputFileName == "") || (*outputFileName == "") {
		flag.PrintDefaults()
		return
	}

	var inputData []byte
	var err error

	inputData, err = readSvgData(*inputFileName)
	if err != nil {
		fmt.Printf("error reading file: %v\n", err)
		return
	}

	var gkErr *gkerr.GkErrDef

	var index int
	index = strings.LastIndex(*inputFileName, "/")
	var prefix string
	prefix = (*inputFileName)[index+1:]
	prefix = prefix[:len(prefix)-4]

	var outputData []byte

	outputData, gkErr = gksvg.FixSvgData(inputData, prefix)
	if gkErr != nil {
		fmt.Printf("error fixing svg file: %s\n", gkErr.String())
		return
	}

	err = writeSvgData(*outputFileName, outputData)
	if err != nil {
		fmt.Printf("error writing file: %v\n", err)
		return
	}
}
コード例 #5
0
func handleLoginForgotPassword(loginConfig *loginConfigDef, res http.ResponseWriter, req *http.Request, userName string) {
	var forgotPasswordData forgotPasswordDataDef
	var gkErr *gkerr.GkErrDef

	forgotPasswordData.Title = "forgotPassword"
	forgotPasswordData.LoginWebAddressPrefix = loginConfig.LoginWebAddressPrefix
	forgotPasswordData.UserName = userName
	forgotPasswordData.ErrorList = make([]string, 0, 0)

	var gotError bool

	if userName == "" {
		forgotPasswordData.ErrorList = append(forgotPasswordData.ErrorList, "user name cannot be blank")
		forgotPasswordData.UserNameError = genErrorMarker()
		gotError = true
	}

	var dbUser *database.DbUserDef

	if !gotError {
		var gkDbCon *database.GkDbConDef

		gkDbCon, gkErr = database.NewGkDbCon(loginConfig.DatabaseUserName, loginConfig.DatabasePassword, loginConfig.DatabaseHost, loginConfig.DatabasePort, loginConfig.DatabaseDatabase)
		if gkErr != nil {
			gklog.LogGkErr("database.NewGkDbCon", gkErr)
			redirectToError("database.NewGkDbCon", res, req)
			return
		}

		defer gkDbCon.Close()

		dbUser, gkErr = gkDbCon.GetUser(
			forgotPasswordData.UserName)

		if gkErr != nil {
			if gkErr.GetErrorId() == database.ERROR_ID_NO_ROWS_FOUND {
				forgotPasswordData.ErrorList = append(forgotPasswordData.ErrorList, "no such user")
				forgotPasswordData.UserNameError = genErrorMarker()
				gotError = true
			} else {
				gklog.LogGkErr("gbDbCon.GetUser", gkErr)
				redirectToError("gbDbCon.GetUser", res, req)
				return
			}
		}
	}

	var err error

	if !gotError {
		// create temporary forgot password token

		//var token []byte
		var forgotPasswordEmailData forgotPasswordEmailDataDef

		forgotPasswordEmailData.LoginWebAddressPrefix = loginConfig.LoginWebAddressPrefix
		forgotPasswordEmailData.UserName = userName

		var token []byte

		token, err = sec.GenForgotPasswordToken()
		if err != nil {
			gkErr = gkerr.GenGkErr("GenForgotPasswordToken", err, ERROR_ID_GEN_TOKEN)
			gklog.LogGkErr("GenForgotPasswordToken", gkErr)
			redirectToError("GenForgotPasswordToken", res, req)
			return
		}

		forgotPasswordEmailData.Token = string(token)

		gkErr = _forgotPasswordEmailTemplate.Build(forgotPasswordEmailData)
		if gkErr != nil {
			gklog.LogGkErr("_forgotPasswordEmailTemplate.Build", gkErr)
			redirectToError("_forgotPasswordEmailTemplate.Build", res, req)
			return
		}

		var message []byte

		message, gkErr = _forgotPasswordEmailTemplate.GetBytes()
		if gkErr != nil {
			gklog.LogGkErr("_forgotPasswordEmailTemplate.GetBytes", gkErr)
			redirectToError("_forgotPasswordEmailTemplate.GetBytes", res, req)
			return
		}

		toArray := make([]string, 1, 1)
		toArray[0] = dbUser.Email
		var sendId string

		AddNewToken(string(token), userName)

		sendId, gkErr = gknet.SendEmail(loginConfig.EmailServer, loginConfig.ServerFromEmail, toArray, "gourdian knot forgotten password", message)

		if gkErr != nil {
			gklog.LogGkErr("gknet.SendEmail", gkErr)
		} else {
			gklog.LogTrace("forgot email sent to: " + toArray[0] + " sendId: [" + sendId + "]")
		}
	}

	if gotError {
		gkErr = _forgotPasswordTemplate.Build(forgotPasswordData)
		if gkErr != nil {
			gklog.LogGkErr("_forgotPasswordTemplate.Build", gkErr)
			redirectToError("_forgotPasswordTemplate.Build", res, req)
			return
		}

		gkErr = _forgotPasswordTemplate.Send(res, req)
		if gkErr != nil {
			gklog.LogGkErr("_forgotPasswordTemplate.send", gkErr)
		}
	} else {
		http.Redirect(res, req, _loginServer, http.StatusFound)
	}
}
コード例 #6
0
func handleLoginRegister(loginConfig *loginConfigDef, res http.ResponseWriter, req *http.Request, userName string, password string, email string) {
	var registerData registerDataDef
	var gkErr *gkerr.GkErrDef
	var err error

	registerData.Title = "register"
	registerData.LoginWebAddressPrefix = loginConfig.LoginWebAddressPrefix
	registerData.UserName = userName
	registerData.Email = email
	registerData.ErrorList = make([]string, 0, 0)

	var gotError bool

	if !isNewUserNameValid(userName) {
		registerData.ErrorList = append(registerData.ErrorList, "invalid user name")
		registerData.UserNameError = genErrorMarker()
		gotError = true
	}
	if !isPasswordValid(password) {
		registerData.ErrorList = append(registerData.ErrorList, "invalid password")
		registerData.PasswordError = genErrorMarker()
		gotError = true
	}
	if !isEmailValid(email) {
		registerData.ErrorList = append(registerData.ErrorList, "invalid email")
		registerData.EmailError = genErrorMarker()
		gotError = true
	}

	if !gotError {
		var gkDbCon *database.GkDbConDef

		gkDbCon, gkErr = database.NewGkDbCon(loginConfig.DatabaseUserName, loginConfig.DatabasePassword, loginConfig.DatabaseHost, loginConfig.DatabasePort, loginConfig.DatabaseDatabase)
		if gkErr != nil {
			gklog.LogGkErr("database.NewGkDbCon", gkErr)
			redirectToError("database.NewGkDbCon", res, req)
			return
		}

		defer gkDbCon.Close()

		var passwordHash, passwordSalt []byte

		passwordSalt, err = sec.GenSalt()
		if err != nil {
			gkErr = gkerr.GenGkErr("sec.GenSalt", err, ERROR_ID_GEN_SALT)
			gklog.LogGkErr("sec.GenSalt", gkErr)
			redirectToError("sec.GenSalt", res, req)
		}

		passwordHash = sec.GenPasswordHashSlow([]byte(password), passwordSalt)

		gkErr = gkDbCon.AddNewUser(
			registerData.UserName,
			string(passwordHash),
			string(passwordSalt),
			email)

		if gkErr != nil {
			if gkErr.GetErrorId() == database.ERROR_ID_UNIQUE_VIOLATION {
				registerData.ErrorList = append(registerData.ErrorList, "user name already in use")
				registerData.UserNameError = genErrorMarker()
				gotError = true
			} else {
				gklog.LogGkErr("gbDbCon.AddNewUser", gkErr)
				redirectToError("gbDbCon.AddNewUser", res, req)
				return
			}
		}
	}

	if gotError {
		gkErr = _registerTemplate.Build(registerData)
		if gkErr != nil {
			gklog.LogGkErr("_registerTemplate.Build", gkErr)
			redirectToError("_registerTemplate.Build", res, req)
			return
		}

		gkErr = _registerTemplate.Send(res, req)
		if gkErr != nil {
			gklog.LogGkErr("_registerTemplate.send", gkErr)
		}
	} else {
		http.Redirect(res, req, _loginServer, http.StatusFound)
		//		var gameRedirect string
		//		gameRedirect = getGameRedirect(loginConfig, loginData.UserName)
		//		http.Redirect(res, req, gameRedirect, http.StatusFound)
	}
}
コード例 #7
0
func handleLoginLogin(loginConfig *loginConfigDef, res http.ResponseWriter, req *http.Request, userName string, password string) {
	var loginData loginDataDef
	var gkErr *gkerr.GkErrDef
	var gotError bool

	loginData.Title = "login"
	loginData.UserName = userName
	loginData.LoginWebAddressPrefix = loginConfig.LoginWebAddressPrefix

	if loginData.UserName == "" {
		loginData.ErrorList = append(loginData.ErrorList, "invalid user name")
		loginData.UserNameError = genErrorMarker()
		gotError = true
	}

	if password == "" {
		loginData.ErrorList = append(loginData.ErrorList, "invalid password")
		loginData.PasswordError = genErrorMarker()
		gotError = true
	}

	var passwordHashFromUser []byte

	var dbUser *database.DbUserDef
	var gkDbCon *database.GkDbConDef

	if !gotError {

		gkDbCon, gkErr = database.NewGkDbCon(loginConfig.DatabaseUserName, loginConfig.DatabasePassword, loginConfig.DatabaseHost, loginConfig.DatabasePort, loginConfig.DatabaseDatabase)
		if gkErr != nil {
			gklog.LogGkErr("database.NewGkDbCon", gkErr)
			redirectToError("database.NewGkDbCon", res, req)
			return
		}

		defer gkDbCon.Close()

		dbUser, gkErr = gkDbCon.GetUser(loginData.UserName)

		if gkErr != nil {
			if gkErr.GetErrorId() == database.ERROR_ID_NO_ROWS_FOUND {
				var passwordSalt string

				password = "******"
				passwordSalt = "abc123QWE."
				// make it take the same amount of time
				// between no user and invalid password
				passwordHashFromUser = sec.GenPasswordHashSlow([]byte(password), []byte(passwordSalt))
				loginData.ErrorList = append(loginData.ErrorList, "invalid username/password")
				loginData.UserNameError = genErrorMarker()
				loginData.PasswordError = genErrorMarker()
				gotError = true
			} else {
				gklog.LogGkErr("gkDbCon.GetPasswordHashAndSalt", gkErr)
				redirectToError("gkDbCon.GetPasswordhashAndSalt", res, req)
				return
			}
		}
	}

	if !gotError {
		passwordHashFromUser = sec.GenPasswordHashSlow([]byte(password), []byte(dbUser.PasswordSalt))

		gklog.LogTrace(fmt.Sprintf("dbUser: %v fromUser: %s", dbUser, passwordHashFromUser))
		if dbUser.PasswordHash != string(passwordHashFromUser) {
			loginData.ErrorList = append(loginData.ErrorList, "invalid username/password")
			loginData.UserNameError = genErrorMarker()
			loginData.PasswordError = genErrorMarker()
			gotError = true
		}
	}

	if gotError {
		// for security, to slow down an attack that is guessing passwords,
		// sleep between 100 and 190 milliseconds
		time.Sleep(sec.GetSleepDurationPasswordInvalid())

		gkErr = _loginTemplate.Build(loginData)
		if gkErr != nil {
			gklog.LogGkErr("_loginTemplate.Build", gkErr)
			redirectToError("_loginTemplate.Build", res, req)
			return
		}

		gkErr = _loginTemplate.Send(res, req)
		if gkErr != nil {
			gklog.LogGkErr("_loginTemplate.Send", gkErr)
			return
		}
	} else {
		gkErr = gkDbCon.UpdateUserLoginDate(dbUser.UserName)
		if gkErr != nil {
			// this error is going to be logged
			// but the user is not going to be redirected to an error
			// because they are going to be redirected to the game server
			// and it is not critical that their login date be updated.
			gklog.LogGkErr("_loginTemplate.Send", gkErr)
		}
		var gameRedirect string
		gameRedirect, gkErr = getGameRedirect(loginConfig, loginData.UserName)
		if gkErr != nil {
			gklog.LogGkErr("getGameRedirect", gkErr)
			return
		}
		http.Redirect(res, req, gameRedirect, http.StatusFound)
	}
}
コード例 #8
0
ファイル: svg_test.go プロジェクト: gk-turnip/server
func testSvgMidLevel(t *testing.T) {
	var result string
	var gkErr *gkerr.GkErrDef

	var idMap map[string]string = make(map[string]string)
	var space, name, value string

	idMap["id1"] = "new_id1"
	idMap["id2"] = "new_id2"

	name = "href"
	space = "xlink"
	value = "#id1"
	result, gkErr = substituteOneAttributeId(idMap, space, name, value)
	if gkErr != nil {
		t.Logf("gkErr on substituteOneAttributeId")
		t.Fail()
	}
	if result != "#new_id1" {
		t.Logf("invalid result on substituteOneAttibuteId")
		t.Fail()
	}

	name = "style"
	space = ""
	value = "fill:url(#id2);fill-opacity:1"
	result, gkErr = substituteOneAttributeId(idMap, space, name, value)
	if gkErr != nil {
		t.Logf("gkErr on substituteOneAttributeId " + gkErr.String())
		t.Fail()
	}
	if result != "fill:url(#new_id2);fill-opacity:1" {
		t.Logf("invalid result on substituteOneAttibuteId " + result)
		t.Fail()
	}

	name = "style"
	space = ""
	value = "stroke:none;fill-opacity:1"
	result, gkErr = substituteOneAttributeId(idMap, space, name, value)
	if gkErr != nil {
		t.Logf("gkErr on substituteOneAttributeId " + gkErr.String())
		t.Fail()
	}
	if result != "stroke:none;fill-opacity:1" {
		t.Logf("invalid result on substituteOneAttibuteId " + result)
		t.Fail()
	}

	idMap = make(map[string]string)
	idMap["linearGradient9986-0-1-3-1-1"] = "new_linearGradient9986-0-1-3-1-1"
	idMap["filter8705-8-7-6-6-6-1"] = "new_filter8705-8-7-6-6-6-1"

	name = "style"
	space = ""
	value = "opacity:0.6;fill:url(#linearGradient9986-0-1-3-1-1);fill-opacity:1;filter:url(#filter8705-8-7-6-6-6-1)"
	result, gkErr = substituteOneAttributeId(idMap, space, name, value)
	if gkErr != nil {
		t.Logf("gkErr on substituteOneAttributeId " + gkErr.String())
		t.Fail()
	}
	if result != "opacity:0.6;fill:url(#new_linearGradient9986-0-1-3-1-1);fill-opacity:1;filter:url(#new_filter8705-8-7-6-6-6-1)" {
		t.Logf("invalid result on substituteOneAttibuteId " + result)
		t.Fail()
	}
}
コード例 #9
0
ファイル: message_test.go プロジェクト: gk-turnip/server
func testPopulateFromMessage(t *testing.T) {
	//	var command string
	//	var jsonData []byte
	//	var data []byte
	var gkErr *gkerr.GkErrDef
	var message []byte
	var messageFromClient *MessageFromClientDef
	var sessionId string = "test"

	message = []byte("com~{\"name\":\"value\"}~data")
	messageFromClient = new(MessageFromClientDef)
	gkErr = messageFromClient.PopulateFromMessage(sessionId, message)
	if gkErr != nil {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data) + " gkErr: " + gkErr.String())
		t.Fail()
	}
	if messageFromClient.Command != "com" {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data) + " gkErr: " + gkErr.String())
		t.Fail()
	}
	if string(messageFromClient.JsonData) != "{\"name\":\"value\"}" {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data) + " gkErr: " + gkErr.String())
		t.Fail()
	}
	if string(messageFromClient.data) != "data" {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data) + " gkErr: " + gkErr.String())
		t.Fail()
	}
	message = []byte("com~{\"name\":\"value\"}~")
	messageFromClient = new(MessageFromClientDef)
	gkErr = messageFromClient.PopulateFromMessage(sessionId, message)
	if gkErr != nil {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data) + " gkErr: " + gkErr.String())
		t.Fail()
	}
	if messageFromClient.Command != "com" {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data) + " gkErr: " + gkErr.String())
		t.Fail()
	}
	if string(messageFromClient.JsonData) != "{\"name\":\"value\"}" {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data) + " gkErr: " + gkErr.String())
		t.Fail()
	}
	if string(messageFromClient.data) != "" {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data) + " gkErr: " + gkErr.String())
		t.Fail()
	}
	message = []byte("commandOnly~~")
	messageFromClient = new(MessageFromClientDef)
	gkErr = messageFromClient.PopulateFromMessage(sessionId, message)
	if gkErr != nil {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data) + " gkErr: " + gkErr.String())
		t.Fail()
	}
	if messageFromClient.Command != "commandOnly" {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data) + " gkErr: " + gkErr.String())
		t.Fail()
	}
	if string(messageFromClient.JsonData) != "" {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data) + " gkErr: " + gkErr.String())
		t.Fail()
	}
	if string(messageFromClient.data) != "" {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data) + " gkErr: " + gkErr.String())
		t.Fail()
	}

	message = []byte("com~{\"name\":\"value\"}data")
	messageFromClient = new(MessageFromClientDef)
	gkErr = messageFromClient.PopulateFromMessage(sessionId, message)
	if gkErr == nil {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data))
		t.Fail()
	}
	message = []byte("com{\"name\":\"value\"}data")
	messageFromClient = new(MessageFromClientDef)
	gkErr = messageFromClient.PopulateFromMessage(sessionId, message)
	if gkErr == nil {
		t.Logf("PopulateFromMessage message: " + string(message) + " jsonData: " + string(messageFromClient.JsonData) + " data: " + string(messageFromClient.data))
		t.Fail()
	}
}
コード例 #10
0
ファイル: gameServer.go プロジェクト: gk-turnip/server
func GameServerStart() {

	var fileName *string = flag.String("config", "", "config file name")
	var gameConfig *config.GameConfigDef
	var gkErr *gkerr.GkErrDef

	flag.Parse()

	if *fileName == "" {
		flag.PrintDefaults()
		return
	}

	gameConfig, gkErr = config.LoadConfigFile(*fileName)
	if gkErr != nil {
		fmt.Print(gkErr.String())
		return
	}

	gklog.LogInit(gameConfig.LogDir)

	var randContext *gkrand.GkRandContextDef
	var persistenceContext *persistence.PersistenceContextDef
	var tokenContext *tokenContextDef
	var sessionContext *ses.SessionContextDef
	var httpContext *httpContextDef

	randContext = gkrand.NewGkRandContext()
	persistenceContext, gkErr = persistence.NewPersistenceContext(gameConfig)
	if gkErr != nil {
		gklog.LogGkErr("persistence.NewPersisenceContext", gkErr)
		return
	}
	tokenContext = NewTokenContext(gameConfig, randContext, sessionContext)
	sessionContext = ses.NewSessionContext(randContext)
	httpContext = NewHttpContext(gameConfig, persistenceContext, sessionContext, tokenContext)

	gkErr = httpContext.gameInit()
	if gkErr != nil {
		gklog.LogGkErr("httpContext.gameInit", gkErr)
		return
	}

	gkErr = tokenContext.gameInit()
	if gkErr != nil {
		gklog.LogGkErr("tokenContext.gameInit", gkErr)
		return
	}

	gklog.LogTrace("game server started")

	var wsContext *ws.WsContextDef
	var fieldContext *field.FieldContextDef

	fieldContext, gkErr = field.NewFieldContext(gameConfig.AvatarSvgDir, gameConfig.TerrainSvgDir, sessionContext, persistenceContext)
	if gkErr != nil {
		gklog.LogGkErr("field.NewFieldContext", gkErr)
		return
	}

	wsContext = ws.NewWsContext(gameConfig, sessionContext, fieldContext)
	ws.SetGlobalWsContext(wsContext)

	go fieldContext.StartFieldHandler()

	httpAddress := fmt.Sprintf(":%d", gameConfig.HttpPort)

	tokenAddress := fmt.Sprintf(":%d", gameConfig.TokenPort)

	var err error

	go func() {
		err = http.ListenAndServe(tokenAddress, tokenContext)
		if err != nil {
			gkErr = gkerr.GenGkErr("http.ListenAndServer token", err, ERROR_ID_TOKEN_SERVER_START)
			gklog.LogGkErr("", gkErr)
			return
		}
		gklog.LogTrace("token listener ended, this is probably bad")
	}()

	go func() {
		err = http.ListenAndServe(httpAddress, httpContext)
		if err != nil {
			gkErr = gkerr.GenGkErr("http.ListenAndServer http", err, ERROR_ID_HTTP_SERVER_START)
			gklog.LogGkErr("", gkErr)
			return
		}
		gklog.LogTrace("http listener ended, this is probably bad")
	}()

	go func() {
		websocketAddress := fmt.Sprintf(":%d", gameConfig.WebsocketPort)
		gklog.LogTrace("starting web socket listener")
		if gameConfig.CertificatePath == "" {
			err = http.ListenAndServe(websocketAddress, websocket.Handler(ws.WebsocketHandler))
		} else {
			err = http.ListenAndServeTLS(websocketAddress, gameConfig.CertificatePath, gameConfig.PrivateKeyPath, websocket.Handler(ws.WebsocketHandler))
		}
		if err != nil {
			gkErr = gkerr.GenGkErr("http.ListenAndServer websocket", err, ERROR_ID_WEBSOCKET_SERVER_START)
			gklog.LogGkErr("", gkErr)
			return
		}
		gklog.LogTrace("websocket listener ended, this is probably bad")
	}()

	// give it time for the servers to start
	time.Sleep(time.Second * 60)
	// wait for all go routines to finish
	select {}
	gklog.LogTrace("game server ended")
}