コード例 #1
0
ファイル: fieldContext.go プロジェクト: gk-turnip/server
func (fieldContext *FieldContextDef) sendSingleAvatarObject(websocketConnectionContext *websocketConnectionContextDef, fieldObject *fieldObjectDef) *gkerr.GkErrDef {
	var gkErr *gkerr.GkErrDef

	var svgJsonData *message.SvgJsonDataDef = new(message.SvgJsonDataDef)

	svgJsonData.Id = fieldObject.id
	svgJsonData.IsoXYZ = fieldObject.isoXYZ
	gklog.LogTrace("sourceSessionId: " + fieldObject.sourceSessionId)
	if fieldObject.sourceSessionId != websocketConnectionContext.sessionId {
		var singleSession *ses.SingleSessionDef
		singleSession = fieldContext.sessionContext.GetSessionFromId(fieldObject.sourceSessionId)
		svgJsonData.UserName = singleSession.GetUserName()
		gklog.LogTrace("going to send to ws userName: " + singleSession.GetUserName())
	}

	var messageToClient *message.MessageToClientDef = new(message.MessageToClientDef)
	gkErr = messageToClient.BuildSvgMessageToClient(fieldContext.avatarSvgDir, message.AddSvgReq, fieldObject.fileName, svgJsonData)
	if gkErr != nil {
		return gkErr
	}

	fieldContext.queueMessageToClient(websocketConnectionContext.sessionId, messageToClient)

	return nil
}
コード例 #2
0
ファイル: tokenContext.go プロジェクト: gk-turnip/server
func (tokenContext *tokenContextDef) getUserFromToken(token string) string {

	var ok bool
	var tokenEntry *tokenEntryDef

	tokenContext.purgeOldTokenEntries()

	tokenContext.tokenMutex.Lock()
	defer tokenContext.tokenMutex.Unlock()

	gklog.LogTrace(fmt.Sprintf("getting token entry: %+v", token))
	tokenEntry, ok = tokenContext.tokenMap[token]
	if !ok {
		gklog.LogTrace("did not find")
		return ""
	}

	var userName string

	userName = tokenEntry.userName
	gklog.LogTrace("found " + userName)

	// token cannot be reused
	// but for now we allow it to be reused :)
	//delete(tokenContext.tokenMap,tokenEntry.tokenId)

	return userName
}
コード例 #3
0
ファイル: fieldContext.go プロジェクト: gk-turnip/server
// an avatar is moving from one pod to another
// so delete any object matching by sessionId from old pod
// then add them to the new pod
func (fieldContext *FieldContextDef) moveAllAvatarBySessionId(sessionId string, oldPodId int32, newPodId int32, destinationX int16, destinationY int16, destinationZ int16) *gkerr.GkErrDef {
	gklog.LogTrace("moving all object by session id")
	var gkErr *gkerr.GkErrDef

	for _, fieldObject := range fieldContext.podMap[oldPodId].avatarMap {
		if fieldObject.sourceSessionId == sessionId {
			var messageToClient *message.MessageToClientDef = new(message.MessageToClientDef)

			messageToClient.Command = message.DelSvgReq
			messageToClient.JsonData = []byte(fmt.Sprintf("{ \"id\": \"%s\"}", fieldObject.id))
			messageToClient.Data = make([]byte, 0, 0)

			for _, websocketConnectionContext := range fieldContext.podMap[oldPodId].websocketConnectionMap {
				if sessionId == websocketConnectionContext.sessionId {
					fieldObject.isoXYZ.X = destinationX
					fieldObject.isoXYZ.Y = destinationY
					fieldObject.isoXYZ.Z = destinationZ
					gklog.LogTrace(fmt.Sprintf("moveAllAvatarBySessionId new destination: %d,%d,%d", fieldObject.isoXYZ.X, fieldObject.isoXYZ.Y, fieldObject.isoXYZ.Z))
				}
				fieldContext.queueMessageToClient(websocketConnectionContext.sessionId, messageToClient)
			}

			for _, websocketConnectionContext := range fieldContext.podMap[newPodId].websocketConnectionMap {
				gkErr = fieldContext.sendSingleAvatarObject(websocketConnectionContext, fieldObject)
				if gkErr != nil {
					return gkErr
				}
			}

			delete(fieldContext.podMap[oldPodId].avatarMap, fieldObject.id)
			fieldContext.podMap[newPodId].avatarMap[fieldObject.id] = fieldObject
		}
	}
	return nil
}
コード例 #4
0
ファイル: httpContext.go プロジェクト: gk-turnip/server
func (httpContext *httpContextDef) handleGameInitial(res http.ResponseWriter, req *http.Request) {
	var gameData gameDataDef
	var gkErr *gkerr.GkErrDef
	var singleSession *ses.SingleSessionDef
	var token string

	token = req.Form.Get(_tokenParam)
	gklog.LogTrace("got token: " + token)
	var userName string
	userName = httpContext.tokenContext.getUserFromToken(token)
	gklog.LogTrace("got username: "******"not valid token", res, req)
		return
	}

	var lastPodId int32
	lastPodId, gkErr = httpContext.persistenceContext.GetLastPodId(userName)
	if gkErr != nil {
		errorMessage := "persistenceContext.getLastPodName"
		gklog.LogGkErr(errorMessage, gkErr)
		httpContext.redirectToError(errorMessage, res, req)
		return
	}

	singleSession = httpContext.sessionContext.NewSingleSession(userName, lastPodId, req.RemoteAddr)

	gameData.Title = "game"
	gameData.WebAddressPrefix = httpContext.gameConfig.WebAddressPrefix
	gameData.WebsocketAddressPrefix = httpContext.gameConfig.WebsocketAddressPrefix
	gameData.AudioAddressPrefix = httpContext.gameConfig.AudioAddressPrefix
	gameData.WebsocketPath = httpContext.gameConfig.WebsocketPath
	gameData.SessionId = singleSession.GetSessionId()

	gkErr = _gameTemplate.Build(gameData)
	if gkErr != nil {
		errorMessage := "_gameTemplate.Build"
		gklog.LogGkErr(errorMessage, gkErr)
		httpContext.redirectToError(errorMessage, res, req)
		return
	}

	gkErr = _gameTemplate.Send(res, req)
	if gkErr != nil {
		gklog.LogGkErr("_gameTemplate.Send", gkErr)
		return
	}
}
コード例 #5
0
ファイル: tokenContext.go プロジェクト: gk-turnip/server
func (tokenContext *tokenContextDef) ServeHTTP(res http.ResponseWriter, req *http.Request) {
	path := req.URL.Path

	gklog.LogTrace(req.Method)
	gklog.LogTrace(path)

	if req.Method == _methodGet || req.Method == _methodPost {
		if gknet.RequestMatches(path, _tokenRequest) {
			tokenContext.handleTokenRequest(res, req)
		} else {
			http.NotFound(res, req)
		}
	} else {
		http.NotFound(res, req)
	}
}
コード例 #6
0
ファイル: queueMessage.go プロジェクト: gk-turnip/server
func (fieldContext *FieldContextDef) queueMessageToClient(sessionId string, messageToClient *message.MessageToClientDef) {

	var websocketConnectionContext *websocketConnectionContextDef
	var gkErr *gkerr.GkErrDef

	gklog.LogTrace("queu up message " + messageToClient.Command)

	websocketConnectionContext, gkErr =
		fieldContext.getWebsocketConnectionContextById(sessionId)

	if gkErr != nil {
		gklog.LogGkErr("", gkErr)
	} else {
		var localSize int

		websocketConnectionContext.toClientQueue.mutex.Lock()
		localSize = websocketConnectionContext.toClientQueue.queueSize
		websocketConnectionContext.toClientQueue.mutex.Unlock()

		if localSize > MAX_MESSAGES_TO_CLIENT_QUEUE {
			gkErr = gkerr.GenGkErr("messageToClient queue overflow, dropping message", nil, ERROR_ID_MESSAGE_TO_CLIENT_QUEUE_OVERFLOW)
			gklog.LogGkErr("", gkErr)
		} else {
			websocketConnectionContext.toClientQueue.mutex.Lock()
			websocketConnectionContext.toClientQueue.queueSize += 1
			websocketConnectionContext.toClientQueue.mutex.Unlock()
			websocketConnectionContext.toClientQueue.messagesChan <- messageToClient
		}
	}
}
コード例 #7
0
ファイル: queueMessage.go プロジェクト: gk-turnip/server
func (websocketConnectionContext *websocketConnectionContextDef) runQueue() {

	var done bool
	done = false
	for !done {
		var messageToClient *message.MessageToClientDef

		select {
		case messageToClient = <-websocketConnectionContext.toClientQueue.messagesChan:
		case done = <-websocketConnectionContext.toClientQueue.doneChan:
		}
		if !done {
			gklog.LogTrace("got message to send: " + messageToClient.Command)
			select {
			case websocketConnectionContext.messageToClientChan <- messageToClient:
			case done = <-websocketConnectionContext.toClientQueue.doneChan:
			}
			if !done {
				websocketConnectionContext.toClientQueue.mutex.Lock()
				websocketConnectionContext.toClientQueue.queueSize -= 1
				websocketConnectionContext.toClientQueue.mutex.Unlock()
			}
		}
	}
}
コード例 #8
0
ファイル: tempTokens.go プロジェクト: gk-turnip/server
// purge any expired tokens
func checkTokenExpire() {
	expireTime := time.Now().Add(time.Duration(-1) * _tokenExpiry)

	for k, v := range _tokenMap {
		if expireTime.After(v.createdDate) {
			gklog.LogTrace(fmt.Sprintf("removing map entry (timeout) k: %+v v: %+v", k, v))
			delete(_tokenMap, k)
		}
	}
}
コード例 #9
0
ファイル: gkTmpl.go プロジェクト: gk-turnip/server
func NewTemplate(templateDir string, templateName string) (*TemplateDef, *gkerr.GkErrDef) {
	var gkTemplate *TemplateDef = new(TemplateDef)

	gkTemplate.tmpl = template.New(templateName)

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

	templateListFileName = templateDir + string(os.PathSeparator) + templateName + ".txt"
	file, err = os.Open(templateListFileName)
	if err != nil {
		return nil, gkerr.GenGkErr("os.Open", err, ERROR_ID_OPEN_TEMPLATE_LIST)
	}

	defer file.Close()

	var br *bufio.Reader

	localFileNames := make([]string, 0, 0)

	br = bufio.NewReader(file)
	for {
		var line string

		line, err = br.ReadString('\n')

		line = strings.Trim(line, "\r\n\t ")

		if line != "" {
			localFileNames = append(localFileNames, templateDir+string(os.PathSeparator)+line)
		}

		if err != nil {
			if err == io.EOF {
				break
			}
			return nil, gkerr.GenGkErr("br.ReadString", err, ERROR_ID_READ_TEMPLATE_LIST)
		}
	}

	//	localFileNames = make([]string, len(fileNames), len(fileNames))
	//	for i := 0; i < len(fileNames); i++ {
	//		localFileNames[i] = templateDir + string(os.PathSeparator) + fileNames[i] + ".html"
	//	}

	gklog.LogTrace(fmt.Sprintf("localFileNames: %+v", localFileNames))

	_, err = gkTemplate.tmpl.ParseFiles(localFileNames...)
	if err != nil {
		return nil, gkerr.GenGkErr("tmpl.ParseFiles", err, ERROR_ID_PARSE_FILES)
	}

	return gkTemplate, nil
}
コード例 #10
0
ファイル: tempTokens.go プロジェクト: gk-turnip/server
// check if the token / userName is valid
func CheckToken(token string, userName string) bool {
	_tokenMapMutex.Lock()
	defer _tokenMapMutex.Unlock()

	checkTokenExpire()

	var tokenEntry tokenEntryDef
	var ok bool

	tokenEntry, ok = _tokenMap[token]
	gklog.LogTrace(fmt.Sprintf("check map entry k: %+v v: %+v", token, ok))
	if ok {
		gklog.LogTrace(fmt.Sprintf("check map entry k: %+v v: %+v", token, tokenEntry))
		if tokenEntry.userName == userName {
			return true
		}
	}

	return false
}
コード例 #11
0
ファイル: httpContext.go プロジェクト: gk-turnip/server
func (httpContext *httpContextDef) ServeHTTP(res http.ResponseWriter, req *http.Request) {
	if _gameTemplate == nil {
		gklog.LogError("missing call to gameInit")
	}

	path := req.URL.Path

	gklog.LogTrace(req.Method)
	gklog.LogTrace(path)

	if req.Method == _methodGet || req.Method == _methodPost {
		if gknet.RequestMatches(path, _gameRequest) {
			httpContext.handleGameRequest(res, req)
		} else {
			http.NotFound(res, req)
		}
	} else {
		http.NotFound(res, req)
	}
}
コード例 #12
0
ファイル: handleSetSvgReq.go プロジェクト: gk-turnip/server
func (fieldContext *FieldContextDef) setAllAvatars(sessionId string, fieldObject *fieldObjectDef) {

	var messageToClient *message.MessageToClientDef = new(message.MessageToClientDef)

	messageToClient.Command = message.SetSvgReq
	messageToClient.JsonData = []byte(fmt.Sprintf("{ \"id\": \"%s\", \"x\": %d, \"y\": %d, \"z\": %d }", fieldObject.id, fieldObject.isoXYZ.X, fieldObject.isoXYZ.Y, fieldObject.isoXYZ.Z))

	var singleSession *ses.SingleSessionDef
	singleSession = fieldContext.sessionContext.GetSessionFromId(sessionId)
	var podId int32 = singleSession.GetCurrentPodId()

	for _, websocketConnectionContext := range fieldContext.podMap[podId].websocketConnectionMap {
		gklog.LogTrace("compare session " + websocketConnectionContext.sessionId + " " + sessionId)

		if websocketConnectionContext.sessionId != sessionId {
			gklog.LogTrace("Trace about to queue up move command")
			fieldContext.queueMessageToClient(websocketConnectionContext.sessionId, messageToClient)
		}
	}
}
コード例 #13
0
ファイル: tokenContext.go プロジェクト: gk-turnip/server
func (tokenContext *tokenContextDef) purgeOldTokenEntries() {
	tokenContext.tokenMutex.Lock()
	defer tokenContext.tokenMutex.Unlock()

	for tokenId, tokenEntry := range tokenContext.tokenMap {
		if tokenEntry.createdDate.Add(time.Second * _tokenTimeoutSeconds).Before(time.Now()) {
			gklog.LogTrace(fmt.Sprintf("purge token entry: %+v", tokenEntry))
			delete(tokenContext.tokenMap, tokenId)
		}
	}
}
コード例 #14
0
func (loginConfig *loginConfigDef) ServeHTTP(res http.ResponseWriter, req *http.Request) {
	if _loginTemplate == nil {
		gklog.LogError("missing call to loginInit")
	}

	path := req.URL.Path

	gklog.LogTrace(req.Method)
	gklog.LogTrace(path)

	if req.Method == _methodGet || req.Method == _methodPost {
		if gknet.RequestMatches(path, _loginServer) {
			handleLogin(loginConfig, res, req)
		} else {
			http.NotFound(res, req)
		}
	} else {
		http.NotFound(res, req)
	}

}
コード例 #15
0
ファイル: handleSetSvgReq.go プロジェクト: gk-turnip/server
func (fieldContext *FieldContextDef) handleSetAvatarSvgReq(messageFromClient *message.MessageFromClientDef) *gkerr.GkErrDef {

	var gkErr *gkerr.GkErrDef
	var err error
	var setSvg setSvgDef

	gklog.LogTrace("json raw: " + string(messageFromClient.JsonData))

	err = json.Unmarshal(messageFromClient.JsonData, &setSvg)
	if err != nil {
		gkErr = gkerr.GenGkErr("json.Unmarshal", err, ERROR_ID_JSON_UNMARSHAL)
		return gkErr
	}

	var singleSession *ses.SingleSessionDef
	singleSession = fieldContext.sessionContext.GetSessionFromId(messageFromClient.SessionId)
	var podId int32 = singleSession.GetCurrentPodId()

	var fieldObject *fieldObjectDef
	var ok bool
	fieldObject, ok = fieldContext.podMap[podId].avatarMap[setSvg.Id]
	if ok {
		var cord int
		cord, _ = strconv.Atoi(setSvg.X)
		fieldObject.isoXYZ.X = int16(cord)
		cord, _ = strconv.Atoi(setSvg.Y)
		fieldObject.isoXYZ.Y = int16(cord)
		cord, _ = strconv.Atoi(setSvg.Z)
		fieldObject.isoXYZ.Z = int16(cord)

		gklog.LogTrace("one")
		fieldContext.setAllAvatars(messageFromClient.SessionId, fieldObject)
	} else {
		gkErr = gkerr.GenGkErr("move object", nil, ERROR_ID_COULD_NOT_FIND_OBJECT_TO_MOVE)
		gklog.LogGkErr("", gkErr)
	}

	return nil
}
コード例 #16
0
ファイル: tempTokens.go プロジェクト: gk-turnip/server
// add a new token / userName to the list of tokens
func AddNewToken(token string, userName string) {
	_tokenMapMutex.Lock()
	defer _tokenMapMutex.Unlock()

	checkTokenExpire()

	var tokenEntry tokenEntryDef

	tokenEntry.userName = userName
	tokenEntry.createdDate = time.Now()
	_tokenMap[token] = tokenEntry
	gklog.LogTrace(fmt.Sprintf("add map entry k: %+v v: %+v", token, tokenEntry))
}
コード例 #17
0
ファイル: gkTmpl.go プロジェクト: gk-turnip/server
func (gkTemplate *TemplateDef) Build(buildData interface{}) *gkerr.GkErrDef {
	gkTemplate.dataBuffer = bytes.NewBuffer(make([]byte, 0, 0))
	var err error

	gklog.LogTrace(fmt.Sprintf("buildData: %+v", buildData))

	err = gkTemplate.tmpl.ExecuteTemplate(gkTemplate.dataBuffer, "main", buildData)
	if err != nil {
		return gkerr.GenGkErr("tmpl.ExecuteTemplate", err, ERROR_ID_EXECUTE_TEMPLATE)
	}

	return nil
}
コード例 #18
0
ファイル: fieldContext.go プロジェクト: gk-turnip/server
// put the avatar back
func (fieldContext *FieldContextDef) reAddAvatarBySessionId(sessionId string, newPodId int32) *gkerr.GkErrDef {
	gklog.LogTrace("re adding an avatar by session id")
	var gkErr *gkerr.GkErrDef

	for _, fieldObject := range fieldContext.podMap[newPodId].avatarMap {
		if fieldObject.sourceSessionId == sessionId {
			websocketConnectionContext := fieldContext.podMap[newPodId].websocketConnectionMap[sessionId]
			gklog.LogTrace(fmt.Sprintf("reAddAvatarBySessionId new destination: %d,%d,%d", fieldObject.isoXYZ.X, fieldObject.isoXYZ.Y, fieldObject.isoXYZ.Z))
			gkErr = fieldContext.sendSingleAvatarObject(websocketConnectionContext, fieldObject)
			if gkErr != nil {
				return gkErr
			}

			//			for _, websocketConnectionContext := range fieldContext.podMap[newPodId].websocketConnectionMap {

			//				if (sessionId == websocketConnectionContext.sessionId) {
			//				}
			//			}
		}
	}

	return nil
}
コード例 #19
0
func (fieldContext *FieldContextDef) handleSaveTerrainEditReq(messageFromClient *message.MessageFromClientDef) *gkerr.GkErrDef {

	var saveTerrainEditReq saveTerrainEditReqDef
	var gkErr *gkerr.GkErrDef
	var err error

	var singleSession *ses.SingleSessionDef
	singleSession = fieldContext.sessionContext.GetSessionFromId(messageFromClient.SessionId)

	gklog.LogTrace("handleSaveTerrainEditReq")
	gklog.LogTrace(fmt.Sprintf("singleSession: %+v", singleSession))
	gklog.LogTrace(fmt.Sprintf("messageFromClient.JsonData: %s", string(messageFromClient.JsonData)))

	err = json.Unmarshal(messageFromClient.JsonData, &saveTerrainEditReq)
	if err != nil {
		gkErr = gkerr.GenGkErr("json.Unmarshal", err, ERROR_ID_JSON_UNMARSHAL)
		return gkErr
	}

	for k, v := range saveTerrainEditReq.TerrainMapMap {
		gklog.LogTrace(fmt.Sprintf("k: %+v", k))
		gklog.LogTrace(fmt.Sprintf("v: %+v", v))
		// v has:
		// x, y, zlist, terrainName, Field

	}

	//
	//	gkErr = fieldContext.persistenceContext.SetSaveTerrainEdit(singleSession.GetUserName(), saveTerrainEditReq.PrefName, saveTerrainEditReq.PrefValue)
	//	if gkErr != nil {
	//		// inserting user preferences is non critical
	//		// so just log the error
	//		gklog.LogGkErr("fieldContext.persistenceContext.SetSaveTerrainEdit", gkErr)
	//	}

	return nil
}
コード例 #20
0
ファイル: fieldContext.go プロジェクト: gk-turnip/server
func NewFieldContext(avatarSvgDir string, terrainSvgDir string, sessionContext *ses.SessionContextDef, persistenceContext *persistence.PersistenceContextDef) (*FieldContextDef, *gkerr.GkErrDef) {
	var fieldContext *FieldContextDef = new(FieldContextDef)
	var gkErr *gkerr.GkErrDef

	fieldContext.avatarSvgDir = avatarSvgDir
	fieldContext.terrainSvgDir = terrainSvgDir
	fieldContext.sessionContext = sessionContext
	fieldContext.persistenceContext = persistenceContext
	fieldContext.WebsocketOpenedChan = make(chan WebsocketOpenedMessageDef)
	fieldContext.WebsocketClosedChan = make(chan WebsocketClosedMessageDef)
	fieldContext.MessageFromClientChan = make(chan *message.MessageFromClientDef)

	var podList []database.DbPodDef

	podList, gkErr = persistenceContext.GetPodsList()
	if gkErr != nil {
		return nil, gkErr
	}

	fieldContext.podMap = make(map[int32]*podEntryDef)
	for _, dbPod := range podList {
		gklog.LogTrace(fmt.Sprintf("populate pod %+v", dbPod))
		var podEntry *podEntryDef = new(podEntryDef)
		podEntry.podId = dbPod.Id
		podEntry.title = dbPod.Title
		podEntry.websocketConnectionMap = make(map[string]*websocketConnectionContextDef)
		podEntry.avatarMap = make(map[string]*fieldObjectDef)
		podEntry.objectMap = make(map[string]*fieldObjectDef)

		podEntry.terrainJson, gkErr = fieldContext.newTerrainMap(podEntry.podId)
		if gkErr != nil {
			return nil, gkErr
		}
		fieldContext.podMap[podEntry.podId] = podEntry
	}

	fieldContext.savedChatMutex = new(sync.Mutex)
	fieldContext.savedChat = list.New()

	//	fieldContext.terrainMap, gkErr = fieldContext.newTerrainMap(fieldContext, fieldContext.terrainSvgDir, fieldContext.persistenceContext)
	//	if gkErr != nil {
	//		return nil, gkErr
	//	}

	return fieldContext, nil
}
コード例 #21
0
ファイル: websocketHandler.go プロジェクト: gk-turnip/server
func goGetMessage(ws *websocket.Conn, ch chan *receiveWebsocketDef) {

	var receiveWebsocket *receiveWebsocketDef
	var err error

	for {
		var message []byte
		message = make([]byte, 0, 0)
		err = websocket.Message.Receive(ws, &message)
		receiveWebsocket = new(receiveWebsocketDef)
		receiveWebsocket.message = message
		receiveWebsocket.err = err
		ch <- receiveWebsocket
		if err != nil {
			gklog.LogTrace("exit goGetMessage due to error")
			break
		}
	}
}
コード例 #22
0
ファイル: tokenContext.go プロジェクト: gk-turnip/server
func (tokenContext *tokenContextDef) handleTokenRequest(res http.ResponseWriter, req *http.Request) {

	req.ParseForm()

	var tokenEntry *tokenEntryDef = new(tokenEntryDef)

	var userName string = req.Form.Get(_userNameParam)

	if len(userName) > 2 {
		tokenEntry.tokenId = tokenContext.getSessionToken()
		tokenEntry.createdDate = time.Now()
		tokenEntry.userName = userName
		tokenContext.tokenMutex.Lock()
		tokenContext.tokenMap[tokenEntry.tokenId] = tokenEntry
		tokenContext.tokenMutex.Unlock()
		gklog.LogTrace(fmt.Sprintf("adding token entry: %+v", tokenEntry))
	} else {
		tokenEntry.tokenId = ""
	}

	res.Write([]byte(tokenEntry.tokenId))
}
コード例 #23
0
ファイル: fieldContext.go プロジェクト: gk-turnip/server
func (fieldContext *FieldContextDef) removeAllAvatarBySessionId(sessionId string) {
	gklog.LogTrace("removing all object by session id")

	var singleSession *ses.SingleSessionDef
	singleSession = fieldContext.sessionContext.GetSessionFromId(sessionId)
	var podId int32 = singleSession.GetCurrentPodId()

	for _, fieldObject := range fieldContext.podMap[podId].avatarMap {
		if fieldObject.sourceSessionId == sessionId {
			var messageToClient *message.MessageToClientDef = new(message.MessageToClientDef)

			messageToClient.Command = message.DelSvgReq
			messageToClient.JsonData = []byte(fmt.Sprintf("{ \"id\": \"%s\"}", fieldObject.id))
			messageToClient.Data = make([]byte, 0, 0)

			//fieldContext.removeSendRemoveAvatarBySessionId(podId, messageToClient)
			for _, websocketConnectionContext := range fieldContext.podMap[podId].websocketConnectionMap {
				fieldContext.queueMessageToClient(websocketConnectionContext.sessionId, messageToClient)
			}
			delete(fieldContext.podMap[podId].avatarMap, fieldObject.id)
		}
	}
}
コード例 #24
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")
}
コード例 #25
0
ファイル: websocketHandler.go プロジェクト: gk-turnip/server
func WebsocketHandler(ws *websocket.Conn) {

	var url *url.URL = ws.Request().URL
	var gkErr *gkerr.GkErrDef

	defer ws.Close()

	gklog.LogTrace("WebsocketHandler start")
	defer gklog.LogTrace("WebsocketHandler end")

	//	var websocketConfig *websocket.Config
	//	websocketConfig = ws.Config()

	if url.Path != _wsContext.gameConfig.WebsocketPath {
		gkErr = gkerr.GenGkErr("invalid websocket path: "+url.Path, nil, ERROR_ID_WEBSOCKET_INVALID_PATH)
		gklog.LogGkErr("", gkErr)
		return
	}

	var sessionId string

	sessionId = _wsContext.sessionContext.OpenSessionWebsocket(url.RawQuery, ws.Request().RemoteAddr)
	if sessionId == "" {
		gkErr = gkerr.GenGkErr("session not valid", nil, ERROR_ID_WEBSOCKET_INVALID_SESSION)
		gklog.LogGkErr("", gkErr)
		return
	}

	defer func() {
		_wsContext.sessionContext.CloseSessionWebsocket(sessionId)
	}()

	var singleSession *ses.SingleSessionDef
	var singleWs *singleWsDef

	singleSession = _wsContext.sessionContext.GetSessionFromId(sessionId)
	singleWs = _wsContext.newSingleWs(singleSession)

	var websocketOpenedMessage field.WebsocketOpenedMessageDef
	websocketOpenedMessage.SessionId = sessionId
	websocketOpenedMessage.MessageToClientChan = singleWs.messageToClientChan
	_wsContext.fieldContext.WebsocketOpenedChan <- websocketOpenedMessage

	defer func() {
		var websocketClosedMessage field.WebsocketClosedMessageDef
		websocketClosedMessage.SessionId = sessionId
		_wsContext.fieldContext.WebsocketClosedChan <- websocketClosedMessage
	}()

	var receiveWebsocketChan chan *receiveWebsocketDef = make(chan *receiveWebsocketDef)

	go goGetMessage(ws, receiveWebsocketChan)

	var done bool = false
	for !done {
		var receiveWebsocket *receiveWebsocketDef

		select {
		case receiveWebsocket = <-receiveWebsocketChan:

			if receiveWebsocket.err != nil {
				if receiveWebsocket.err == io.EOF {
					gklog.LogTrace(fmt.Sprintf("closing websocket got eof sessionId: %s", sessionId))
					done = true
					break
				}
				gkErr = gkerr.GenGkErr(fmt.Sprintf("got websocket input error sessionId %s", sessionId), receiveWebsocket.err, ERROR_ID_WEBSOCKET_RECEIVE)
				gklog.LogGkErr("websocket error", gkErr)
				return
			} else {
				var messageFromClient *message.MessageFromClientDef = new(message.MessageFromClientDef)
				messageFromClient.PopulateFromMessage(sessionId, receiveWebsocket.message)

				_wsContext.fieldContext.MessageFromClientChan <- messageFromClient
			}

		case messageToClient := <-singleWs.messageToClientChan:

			gkErr = sendWebsocketMessage(ws, messageToClient)
			if gkErr != nil {
				gklog.LogGkErr(fmt.Sprintf("sendWebsocketMessage sessionId: %s", sessionId), gkErr)
				return
			}
		}
	}
}
コード例 #26
0
func handleLogin(loginConfig *loginConfigDef, res http.ResponseWriter, req *http.Request) {
	var act string
	var userName string
	var password string
	var email string
	var token string

	req.ParseForm()

	act = req.Form.Get(_actParam)
	userName = req.Form.Get(_userNameParam)
	password = req.Form.Get(_passwordParam)
	email = req.Form.Get(_emailParam)
	token = req.Form.Get(_tokenParam)

	// for security sleep on password attempt
	time.Sleep(sec.GetSleepDurationPasswordAttempt())

	gklog.LogTrace("act: " + act)

	switch act {
	case "":
		var login string

		login = req.Form.Get(_loginParam)

		if login != "" {
			handleLoginLogin(loginConfig, res, req, userName, password)
			return
		}

		handleLoginInitial(loginConfig, res, req)
		return
	case "login":
		var register string
		var forgotPassword string

		register = req.Form.Get(_registerParam)
		forgotPassword = req.Form.Get(_forgotPasswordParam)

		if register != "" {
			handleLoginRegisterInitial(loginConfig, res, req, userName)
			return
		}

		if forgotPassword != "" {
			handleLoginForgotPasswordInitial(loginConfig, res, req)
			return
		}

		if userName == "" {
			handleLoginInitial(loginConfig, res, req)
			return
		}
		handleLoginLogin(loginConfig, res, req, userName, password)
		return
	case "register":
		handleLoginRegister(loginConfig, res, req, userName, password, email)
	case "forgot_password":
		handleLoginForgotPassword(loginConfig, res, req, userName)
	case "reset_password":
		handleLoginResetPassword(loginConfig, res, req, token, userName, password)
	default:
		gklog.LogError("unknown act")
		redirectToError("unknown act", res, req)
		return
	}
}
コード例 #27
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)
	}
}
コード例 #28
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)
	}
}
コード例 #29
0
func handleLoginResetPassword(loginConfig *loginConfigDef, res http.ResponseWriter, req *http.Request, token string, userName string, password string) {
	var resetPasswordData resetPasswordDataDef
	var gkErr *gkerr.GkErrDef

	resetPasswordData.Title = "resetPassword"
	resetPasswordData.LoginWebAddressPrefix = loginConfig.LoginWebAddressPrefix
	resetPasswordData.Token = token
	resetPasswordData.UserName = userName

	if !CheckToken(token, userName) {
		redirectToError("token expired", res, req)
		return
	}

	gklog.LogTrace("reset password: "******"" {
		gklog.LogTrace("password blank")
		gkErr = _resetPasswordTemplate.Build(resetPasswordData)
		if gkErr != nil {
			gklog.LogGkErr("_resetPasswordTemplate.Build", gkErr)
			redirectToError("_resetPasswordTemplate.Build", res, req)
			return
		}

		gkErr = _resetPasswordTemplate.Send(res, req)
		if gkErr != nil {
			gklog.LogGkErr("_resetPasswordTemplate.send", gkErr)
		}
		return
	}

	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
	var err error

	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)

	gklog.LogTrace("change password")
	gkDbCon.ChangePassword(userName, string(passwordHash), string(passwordSalt))
	if gkErr != nil {
		gklog.LogGkErr("gkDbCon.ChangePassword", gkErr)
		redirectToError("gbDbCon.ChangePassword", res, req)
		return
	}

	gklog.LogTrace("redirect to login")
	http.Redirect(res, req, loginConfig.LoginWebAddressPrefix+_loginServer, http.StatusFound)
}