예제 #1
0
파일: chat.go 프로젝트: sayanriju/tuxychat
func publish(c appengine.Context, roomId string, email string, message string) error {
	room := newRoom()
	_, err := memcache.JSON.Get(c, roomId, room)
	if err != nil {
		return err
	}

	errs := make([]error, 0, len(room.Users))
	for user, _ := range room.Users {
		if user == email {
			continue
		}

		if message == "" {
			channel.SendJSON(c, user+roomId, command{"join", email, message})
		} else {
			channel.SendJSON(c, user+roomId, command{"msg", email, message})
		}
	}

	if len(errs) > 0 {
		return errors.New("Publishing message failed!")
	}

	return nil
}
예제 #2
0
func submitWord(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	tableKey := r.FormValue("g")
	user := r.FormValue("u")
	word := r.FormValue("word")
	points, _ := strconv.Atoi(r.FormValue("points"))
	hasWord := false
	totalPoints := 0
	gameChanger := func(g *MyGame) bool {
		// In our current model, users can only submit valid words since their
		// clients have the solutions.
		hasWord = g.HasWord(word)
		if g.HasWord(word) {
			return false
		}
		totalPoints = g.AddWord(user, word, points) // user found a word congrats, store it.
		return true
	}
	g := ChangeGame(c, tableKey, gameChanger)
	if hasWord {
		wordUpdate := &WordUpdate{
			User:        user,
			Word:        word,
			TotalPoints: -1,
		}
		resp := &Resp{
			Action:  "wordUpdate",
			Payload: wordUpdate,
		}
		myToken := r.FormValue("t")
		channel.SendJSON(c, myToken, resp)
		return
	}

	wordUpdate := &WordUpdate{
		User:        user,
		Word:        word,
		TotalPoints: totalPoints,
	}

	resp := &Resp{
		Action:  "wordUpdate",
		Payload: wordUpdate,
	}
	// Send table information to everyone in the room about what the result
	// was.
	for _, token := range g.GetUserTokens() {
		err := channel.SendJSON(c, token, resp)
		if err != nil {
			c.Errorf("Err with sendTables response: %v", err)
		}
	}
}
예제 #3
0
// What to do when a user leaves (send a notification to everyone and
// reset the game if everyone left the table).
func leaving(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	cid := ClientId{
		clientId: r.FormValue("from"),
	}
	c.Infof("Client id leaving: %v", cid.clientId)
	tableKey := cid.table()
	c.Infof("User %v has left table %v.", cid.user(), tableKey)

	gameChanger := func(g *MyGame) bool {
		g.RemoveUser(cid.user())
		if len(g.Users) == 0 {
			c.Infof("There are no more users left in this game. Deleting game.")
			g.Clear() // Clear the game when everyone has left.
		}
		return true
	}
	g := ChangeGame(c, tableKey, gameChanger) // Just need to read the game.

	resp := &Resp{
		Action:  "join",
		Payload: g,
	}
	c.Infof("Notifying these tokens that a user left: %v", g.GetUserTokens())
	// Let everyone know that they joined the game!
	for _, token := range g.GetUserTokens() {
		err := channel.SendJSON(c, token, resp)
		if err != nil {
			c.Errorf("sending Start game updates: %v", err)
		}
	}
}
예제 #4
0
// Reset the state of the game and let all users know about that.
func gameOver(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	tableKey := r.FormValue("g")
	justEnded := false
	gameChanger := func(g *MyGame) bool {
		justEnded = g.HadState("justEnded")
		if justEnded {
			return false
		}
		g.Clear()
		g.AddState("justEnded")
		return true
	}
	g := ChangeGame(c, tableKey, gameChanger)
	if justEnded {
		return
	}
	resp := &Resp{
		Action:  "gameEnded",
		Payload: g,
	}
	// Send update to people letting them know the game is over.
	for _, token := range g.GetUserTokens() {
		err := channel.SendJSON(c, token, resp)
		if err != nil {
			c.Errorf("Err with gameOver response: %v", err)
		}
	}
}
예제 #5
0
func client_callback(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	itsStatus, _ := strconv.Atob(r.FormValue("Status"))
	msg := MSG{itsStatus, r.FormValue("Nickname"), r.FormValue("Message")}
	for _, value := range map_clients {
		channel.SendJSON(c, value, msg)
	}
}
예제 #6
0
파일: main.go 프로젝트: kiran-mk/go
func sendResponseToChannel(w http.ResponseWriter, message string, r *http.Request, uuid string) {
	c := appengine.NewContext(r)
	err := channel.SendJSON(c, uuid, message)
	c.Infof("json")
	if err != nil {
		c.Errorf("sending Game: %v", err)
	}
}
예제 #7
0
func RenderPost(blog_config map[string]interface{}) func(w http.ResponseWriter, req *http.Request) {
	l := func(w http.ResponseWriter, req *http.Request) {
		appcontext := appengine.NewContext(req)
		err := req.ParseMultipartForm(1024 * 1024)
		if err != nil {
			appcontext.Errorf("sending markdown payload: %v", err)
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		dataFile, _, err := req.FormFile("data")
		if err != nil {
			http.Error(w, "did not specify data as a param", http.StatusBadRequest)
			return
		}

		data, err := ioutil.ReadAll(dataFile)
		if err != nil {
			appcontext.Errorf("ioutil.ReadAll(): %v", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		if len(data) < 1 {
			appcontext.Errorf("len(data): %v", len(data))
			http.Error(w, "did not specify data as a param", http.StatusBadRequest)
			return
		}

		key := req.FormValue("g")
		if key == "" {
			http.Error(w, "did not specify a key!", http.StatusBadRequest)
			return
		}

		var decoded interface{}
		err = json.Unmarshal(data, &decoded)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		q := decoded.(map[string]interface{})
		str, ok := q["data"]
		if !ok {
			http.Error(w, "error: must supply JSON with 'data' specified!", http.StatusBadRequest)
			return
		}

		con := map[string]interface{}{"markdown": bytes.NewBuffer(blackfriday.MarkdownCommon(bytes.NewBufferString(fmt.Sprintf("%v", str)).Bytes())).String()}
		err = channel.SendJSON(appcontext, key, con)
		if err != nil {
			appcontext.Errorf("sending markdown payload: %v", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}
	return l
}
예제 #8
0
// 発言時の処理
// Javascriptのクライアントから
// /submit?chatkey=(chatkey)[&msg=(msg)] というクエリでリクエストがくる
// msgの内容をデータストアに保存し、発言内容リストをchannelを経由して
// 部屋にいるすべてのJavascriptクライアントにSendJSONする
func submit(w http.ResponseWriter, r *http.Request) {

	c := appengine.NewContext(r)
	u := user.Current(c)
	tkey := r.FormValue("chatkey")

	// 発言内容をデータストアに保存する
	stm := Message{
		Date:    time.Now(),
		Name:    u.String(),
		Content: r.FormValue("msg"),
	}

	log.Printf("tkey: %v, msg: %v\n", tkey, stm.Content)

	// データストアへ発言内容をPut
	stmkey := datastore.NewIncompleteKey(c, "message", tinychatKey(c, tkey))
	_, err := datastore.Put(c, stmkey, &stm)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// データストアから現在の部屋にいるユーザ全員を取得する
	q := datastore.NewQuery("Member").Ancestor(memberKey(c, tkey))
	members := make([]Member, 0, 20)
	if _, err := q.GetAll(c, &members); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	log.Printf("member: %v\n", members)

	// 発言内容を20件取得
	q = datastore.NewQuery("message").Ancestor(tinychatKey(c, tkey)).Order("-Date").Limit(20)
	messages := make([]Message, 0, 20)
	if _, err := q.GetAll(c, &messages); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// すべてのユーザに対してSendJSONする
	d := Display{
		Token:    "",
		Me:       u.ID,
		Chat_key: tkey,
		Messages: messages,
	}
	for _, member := range members {
		err := channel.SendJSON(c, member.ID+tkey, d)
		if err != nil {
			c.Errorf("sending data: %v", err)
		}
	}

	//log.Printf("hello")
}
예제 #9
0
func rendezVous(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	id := r.FormValue("from")
	if waiting.Len() == 0 {
		waiting.PushBack(id)
		channel.SendJSON(c, id, map[string]int{"t": WAITING_PARTNER})
		c.Infof("User %v added to the waiting list", id)
	} else {
		opponent := waiting.Front()
		opponentId, _ := opponent.Value.(string)
		waiting.Remove(opponent)
		channel.SendJSON(c, opponentId, map[string]int{"t": FOUND_PARTNER, "p": 0})
		channel.SendJSON(c, id, map[string]int{"t": FOUND_PARTNER, "p": 1})
		pairs[opponentId] = id
		pairs[id] = opponentId
		c.Infof("Matching user %v with %v", id, opponentId)
	}
}
예제 #10
0
파일: main.go 프로젝트: julan/Koderank
func messageHandler(w http.ResponseWriter, r *http.Request) {

	w.Header().Set("Content-Type", "application/json")

	c := appengine.NewContext(r)
	if r.Method != "POST" {
		c.Errorf("messageHandler did not expect %s", r.Method)
		http.Error(w, "Method not allowed.", http.StatusInternalServerError)
		return
	}

	var patchSet map[string]interface{}

	defer r.Body.Close()
	if err := json.NewDecoder(r.Body).Decode(&patchSet); err != nil {
		c.Errorf("json.NewDecoder: %s", err)
		http.Error(w, "Error decoding json.", http.StatusInternalServerError)
		return
	}

	code := patchSet["key"].(string)
	repo := repository.NewRepo(c)

	candidate, interviewer, err := repo.GetSession(code)
	if err != nil {
		c.Errorf("repo.GetSession: %v", err)
		http.Redirect(w, r, "/", 301)
		return
	}

	if code == interviewer {
		err := channel.SendJSON(c, candidate, patchSet)
		if err != nil {
			c.Errorf("channel.SendJSON, problem sending: %s.", err)
			http.Error(w, "Error decoding json.", http.StatusInternalServerError)
		}
	} else {
		err := channel.SendJSON(c, interviewer, patchSet)
		if err != nil {
			c.Errorf("channel.SendJSON, problem sending: %s.", err)
			http.Error(w, "Error decoding json.", http.StatusInternalServerError)
		}
	}
}
예제 #11
0
func move(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	id := r.FormValue("id")
	y, _ := strconv.Atoi(r.FormValue("y"))
	direction, _ := strconv.Atoi(r.FormValue("d"))
	c.Infof("Seding move msg from %v to %v", id, pairs[id])
	err := channel.SendJSON(c, pairs[id], map[string]int{"t": PARTNER_MOVED, "y": y, "d": direction})
	if err != nil {
		c.Errorf("%v", err)
	}
}
예제 #12
0
func startGame(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	c.Infof("Got a message from a client that they want to start a game.")

	// Need to keep track of all users associated with the games, then
	// we must broadcast an update to all of them.
	tableKey := r.FormValue("g")
	isStarted := false
	g := defaultGame()
	err := datastore.RunInTransaction(c, func(c appengine.Context) error {
		k := datastore.NewKey(c, "WrGame", tableKey, 0, nil)
		if err := datastore.Get(c, k, g); err != nil {
			return err
		}
		isStarted = g.HadState("justStarted")
		if isStarted {
			return nil
		}
		g.AddState("justStarted") // Set to true when a user first starts the game.
		if _, err := datastore.Put(c, k, g); err != nil {
			return err
		}
		return nil
	}, nil)

	if err != nil {
		c.Errorf("Error in start game db call. %v", err)
		return
	}

	if isStarted {
		// Do nothing if the game is already started.
		// TODO(dlluncor): Update the user's UI that the game is already started.
		c.Infof("Game has already started!!!")
		return
	}

	resp := &Resp{
		Action:  "startGame",
		Payload: "start",
	}
	c.Infof("Tokens: %v", g.Tokens)
	for _, token := range g.GetUserTokens() {
		err := channel.SendJSON(c, token, resp)
		if err != nil {
			c.Errorf("sending Start game updates: %v", err)
		}
	}
	return
}
예제 #13
0
func sendAll(c appengine.Context, h *hunt.Hunt, m Message) {
	var listeners []Listener
	_, err := datastore.NewQuery(listenerKind).Ancestor(h.Key).Filter("Open =", true).GetAll(c, &listeners)
	if err != nil {
		c.Errorf("Send: %v", err)
		return
	}
	for _, listener := range listeners {
		err := channel.SendJSON(c, listener.Channel, m)
		if err != nil {
			c.Errorf("Send(%s): %v", listener.Channel, err)
		}
	}
}
예제 #14
0
func disconnect(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	id := r.FormValue("from")
	_, isPaired := pairs[id]
	if isPaired {
		partner := pairs[id]
		delete(pairs, id)
		delete(pairs, partner)
		channel.SendJSON(c, partner, map[string]int{"t": PARTNER_LEFT})
		c.Infof("Removed Pair %v,%v", id, partner)
	} else {
		for e := waiting.Front(); e != nil; e = e.Next() {
			if e.Value == id {
				waiting.Remove(e)
				c.Infof("User %v removed from the waiting list", id)
				return
			}
		}
	}
}
예제 #15
0
func handle(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "GET":
		Execute("get", w, nil)
	case "POST":
		wID := r.FormValue("ID")
		wToken, err := channel.Create(appengine.NewContext(r), wID)
		if err != nil {
			Execute("get", w, map[string]string{"Error": err.Error()})
		} else {
			Execute(
				"post",
				w,
				map[string]string{
					"ID":    wID,
					"Token": wToken,
				},
			)
		}
	case "PUT":
		ctx := appengine.NewContext(r)

		keys, err := datastore.NewQuery("Channels").KeysOnly().GetAll(ctx, nil)
		if err != nil {
			panic(err)
		}

		for _, key := range keys {
			if err := channel.SendJSON(
				ctx,
				key.StringID(),
				map[string]interface{}{
					"message": r.FormValue("Message"),
					"ID":      r.FormValue("ID"),
				},
			); err != nil {
				panic(err)
			}
		}
	}
}
예제 #16
0
// send data client callbacks.
func SendCallBack(c appengine.Context, clientID int64, request string, args interface{}) error {

	// clientKey
	clientKey := datastore.NewKey(c, "ClientInfo", "", clientID, nil)

	// sent data
	handler := fmt.Sprintf("on%s", request)
	data := struct {
		Call string      `json:"call"`
		Args interface{} `json:"args"`
	}{
		handler,
		args,
	}
	q := datastore.NewQuery("CallBackInfo").Ancestor(clientKey).Filter("Request=", request)

	// callbacks
	var callbacks []CallBackInfo
	keys, err := q.GetAll(c, &callbacks)
	if err != nil {
		c.Errorf(err.Error())
		return err
	}

	// send
	for i, callback := range callbacks {
		k := keys[i]
		client := callback.ClientID
		c.Infof("Send to %s", client)
		channel.SendJSON(c, client, data)

		// remove request
		err = datastore.Delete(c, k)
		if err != nil {
			return err
		}
	}

	return nil
}
예제 #17
0
// When the first user starts the game and gives us tables that defines
// this entire game.
//
// Notifies all users to start their timers for round 1.
func sendTables(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	tableKey := r.FormValue("g")
	// Store all tables as part of the game state and send
	// a "startTimer" response.
	timerStarted := false
	gameChanger := func(g *MyGame) bool {
		timerStarted = g.HadState("timerStarted")
		if timerStarted {
			return false
		}
		g.AddState("timerStarted")
		tableStrKeys := []string{"table1", "table2", "table3", "table4"}
		for _, tableStrKey := range tableStrKeys {
			tableVal := r.FormValue(tableStrKey)
			g.SetTable(tableStrKey, tableVal)
		}
		return true
	}
	g := ChangeGame(c, tableKey, gameChanger)

	if timerStarted {
		return
	}

	resp := &Resp{
		Action:  "startTimers",
		Payload: "",
	}

	// Send an update to everyone.
	for _, token := range g.GetUserTokens() {
		err := channel.SendJSON(c, token, resp)
		if err != nil {
			c.Errorf("Err with sendTables response: %v", err)
		}
	}
}
예제 #18
0
func messageReceived(w http.ResponseWriter, r *http.Request) {

	var clients []Client

	c := appengine.NewContext(r)

	message := r.FormValue("name") + ": " + r.FormValue("message")

	_, err := memcache.JSON.Get(c, "sut", &clients)
	if err != nil && err != memcache.ErrCacheMiss {
		http.Error(w, err.String(), http.StatusInternalServerError)
		return
	}

	if err == memcache.ErrCacheMiss {
		q := datastore.NewQuery("Client")
		_, err = q.GetAll(c, &clients)
		if err != nil {
			http.Error(w, err.String(), http.StatusInternalServerError)
			return
		}
		err = memcache.JSON.Set(c, &memcache.Item{
			Key: "sut", Object: clients,
		})
		if err != nil {
			http.Error(w, err.String(), http.StatusInternalServerError)
			return
		}
	}

	for _, client := range clients {
		channel.SendJSON(c, client.ClientID, map[string]string{
			"reply_message": message,
		})
	}

}
예제 #19
0
// One user can request for the entire group all the information for
// a round like the words to solve and the actual puzzle.
// At this time there is 10 seconds left before the round starts.
func getRoundInfo(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	tableKey := r.FormValue("g")
	round := r.FormValue("r")
	isRoundFetched := false
	gameChanger := func(g *MyGame) bool {
		val := "roundFetched" + round
		isRoundFetched = g.HadState(val)
		if isRoundFetched {
			return false
		}
		roundInt, _ := strconv.Atoi(round)
		g.CreateTableInfo(roundInt)
		g.AddState(val)
		g.SetRoundFetched()
		return true
	}
	g := ChangeGame(c, tableKey, gameChanger) // Just need to read the game.

	if isRoundFetched {
		// We can only fetch a round once...
		return
	}
	tableInfo := g.GetTableInfo()
	resp := &Resp{
		Action:  "aboutToStartRound",
		Payload: tableInfo,
	}
	// Send table information to everyone in the room (need a solution
	// for when someone randomly jumps into the game).
	for _, token := range g.GetUserTokens() {
		err := channel.SendJSON(c, token, resp)
		if err != nil {
			c.Errorf("Err with sendTables response: %v", err)
		}
	}
}
예제 #20
0
파일: routing.go 프로젝트: huluwa/2016_Gofr
func (handler taskRequestHandler) handleRequest(pfc *PFContext) {
	if userID := pfc.R.PostFormValue("userID"); userID != "" {
		pfc.UserID = storage.UserID(userID)
		if channelID := pfc.R.PostFormValue("channelID"); channelID != "" {
			pfc.ChannelID = channelID
		}

		if user, err := storage.UserByID(pfc.C, pfc.UserID); err != nil {
			pfc.C.Errorf("Error loading user: %s", err)
			http.Error(pfc.W, "Unexpected error", http.StatusInternalServerError)
			return
		} else {
			pfc.User = user
		}
	}

	var response interface{}
	taskMessage, err := handler.RouteHandler(pfc)
	if err != nil {
		pfc.C.Errorf("Task failed: %s", err.Error())
		http.Error(pfc.W, err.Error(), http.StatusInternalServerError)
		response = map[string]string{"error": err.Error()}
	} else {
		response = taskMessage
	}

	if !taskMessage.Silent {
		if channelID := pfc.R.PostFormValue("channelID"); channelID != "" {
			if err := channel.SendJSON(pfc.C, channelID, response); err != nil {
				pfc.C.Criticalf("Error writing to channel: %s", err)
			}
		} else {
			pfc.C.Warningf("Channel ID is empty!")
		}
	}
}
예제 #21
0
func Save(blog_config map[string]interface{}) func(w http.ResponseWriter, req *http.Request) {
	l := func(w http.ResponseWriter, req *http.Request) {
		appcontext := appengine.NewContext(req)
		blobs, _, err := blobstore.ParseUpload(req)
		if err != nil {
			appcontext.Errorf("error parsing blobstore! %v", err)
			http.Error(w, "error parsing blobstore!", http.StatusBadRequest)
			return
		}

		//key := "coolguys"
		key := req.FormValue("g")
		if key == "" {
			http.Error(w, "did not specify a key!", http.StatusBadRequest)
			return
		}

		send_message := func(stat string, color string) {
			con := map[string]interface{}{"status": stat, "color": color}
			err := channel.SendJSON(appcontext, key, con)
			if err != nil {
				appcontext.Errorf("sending update message: %v", err)
				http.Error(w, err.Error(), http.StatusInternalServerError)
			}
		}

		bdata, ok := blobs["data"]
		if !ok {
			http.Error(w, "did not specify data as a param", http.StatusBadRequest)
			send_message("internal error while saving!", "#AA0000")
			return
		}
		if len(bdata) != 1 {
			appcontext.Errorf("error parsing blobstore!", err)
			http.Error(w, "error parsing blobstore!", http.StatusBadRequest)
			return
		}
		jsonkey := bdata[0].BlobKey
		data, err := ioutil.ReadAll(blobstore.NewReader(appcontext, jsonkey))
		if err != nil {
			appcontext.Errorf("error parsing blobstore!", err)
			http.Error(w, "error parsing blobstore!", http.StatusBadRequest)
			return
		}
		if len(data) <= 0 {
			http.Error(w, "did not specify data as a param", http.StatusBadRequest)
			send_message("internal error while saving!", "#AA0000")
			return
		}

		var decoded interface{}
		err = json.Unmarshal(data, &decoded)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			send_message("internal error while saving!", "#AA0000")
			return
		}

		q := decoded.(map[string]interface{})
		_, ok = q["data"].(string)
		if !ok {
			http.Error(w, "error: must supply JSON with 'data' specified!", http.StatusBadRequest)
			send_message("internal error while saving!", "#AA0000")
			return
		}
		title, ok := q["title"].(string)
		if !ok {
			http.Error(w, "error: must supply JSON with 'title' specified!", http.StatusBadRequest)
			send_message("internal error while saving!", "#AA0000")
			return
		}
		labels, ok := q["labels"].(string)
		if !ok {
			http.Error(w, "error: must supply JSON with 'labels' specified!", http.StatusBadRequest)
			send_message("internal error while saving!", "#AA0000")
			return
		}
		individual_labels := strings.Split(labels, ",")
		real_labels := make([]string, len(individual_labels))
		for i := range individual_labels {
			real_labels[i] = strings.ToLower(strings.Trim(individual_labels[i], " \t"))
		}

		_, err = post.SavePost(appcontext, title, jsonkey, real_labels, time.Now())
		if err != nil {
			appcontext.Errorf("saving a post: %v", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			send_message("internal error while saving!", "#AA0000")
			return
		}

		send_message("saved", "#00AA00")
	}
	return l
}
예제 #22
0
파일: game.go 프로젝트: josephburnett/kdt3
func updateClients(c appengine.Context, game *m.Game) {
	for _, player := range game.Players {
		channel.SendJSON(c, player.PlayerId, "true")
	}
}
예제 #23
0
func (m *Messages) roomEmit() {
	// sends messages to every user
	for _, key := range getUserList() {
		channel.SendJSON(c, key, m)
	}
}
예제 #24
0
func opened(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	c.Infof("Got a message from a client that they connected to a table.")

	// Make sure the table is in the database here and provide the entire state
	// to the user of what is going on right now.
	// The user needs to know.
	// users and their points.
	// current puzzles associated with game.
	// current words found in the puzzle.
	g := defaultGame()
	tableKey := r.FormValue("g")
	token := r.FormValue("t")
	userExists := false
	err := datastore.RunInTransaction(c, func(c appengine.Context) error {
		k := datastore.NewKey(c, "WrGame", tableKey, 0, nil)
		if err := datastore.Get(c, k, g); err != nil {
			c.Infof("We have never entered this game into the database. Should have one already!!!")
			return err
		}
		// Now write this user to the list of connect users to this table.
		user := r.FormValue("u")
		userExists = g.AddUserToken(user, token)
		if userExists {
			c.Infof("User %v already exists, replacing their token.", user)
		}
		if _, err := datastore.Put(c, k, g); err != nil {
			return err
		}
		// Update user count for lounge.
		return nil
	}, nil)

	if !userExists {
		// Update the lounge with the number of current players for this table.
		// when a new player was added.
		lounge := r.FormValue("l")
		loungeChanger := func(l *MyLounge) bool {
			// TODO(dlluncor): In the middle of something will need to resolve this later...
			return true
		}
		ChangeLounge(c, lounge, loungeChanger)
	}

	if err != nil {
		c.Errorf("Error in db with connect to table. %v", err)
	}

	g.SetNow() // Let users who jump in randomly to figure out what time it is from
	// when the last round started.
	resp := &Resp{
		Action:  "join",
		Payload: g,
	}
	c.Infof("Notifying these tokens that a user entered: %v", g.GetUserTokens())
	// Let everyone know that they joined the game!
	for _, token := range g.GetUserTokens() {
		err := channel.SendJSON(c, token, resp)
		if err != nil {
			c.Errorf("sending Start game updates: %v", err)
		}
	}
}