func (Player) PlayerSettingsSet(server *wsevent.Server, so *wsevent.Client, data []byte) []byte { reqerr := chelpers.FilterRequest(so, 0, true) if reqerr != nil { return reqerr.Encode() } var args struct { Key string `json:"key"` Value string `json:"value"` } err := chelpers.GetParams(data, &args) if err != nil { return helpers.NewTPErrorFromError(err).Encode() } player, _ := models.GetPlayerBySteamId(chelpers.GetSteamId(so.Id())) err = player.SetSetting(args.Key, args.Value) if err != nil { return helpers.NewTPErrorFromError(err).Encode() } return chelpers.EmptySuccessJS }
func (Lobby) LobbyLeave(server *wsevent.Server, so *wsevent.Client, data []byte) []byte { reqerr := chelpers.FilterRequest(so, authority.AuthAction(0), true) if reqerr != nil { return reqerr.Encode() } var args struct { Id *uint `json:"id"` } if err := chelpers.GetParams(data, &args); err != nil { return helpers.NewTPErrorFromError(err).Encode() } steamId := chelpers.GetSteamId(so.Id()) lob, player, tperr := removePlayerFromLobby(*args.Id, steamId) if tperr != nil { return tperr.Encode() } chelpers.AfterLobbyLeave(server, so, lob, player) return chelpers.EmptySuccessJS }
func (Player) PlayerSettingsSet(so *wsevent.Client, args struct { Key *string `json:"key"` Value *string `json:"value"` }) interface{} { player, _ := models.GetPlayerBySteamID(chelpers.GetSteamId(so.ID)) err := player.SetSetting(*args.Key, *args.Value) if err != nil { return helpers.NewTPErrorFromError(err) } switch *args.Key { case "siteAlias": profile := models.DecoratePlayerProfileJson(player) so.EmitJSON(helpers.NewRequest("playerProfile", profile)) if lobbyID, _ := player.GetLobbyID(true); lobbyID != 0 { lobby, _ := models.GetLobbyByID(lobbyID) lobbyData := lobby.LobbyData(true) lobbyData.Send() } case "mumbleNick": if !reMumbleNick.MatchString(*args.Value) { return helpers.NewTPError("Invalid Mumble nick.", -1) } } return chelpers.EmptySuccessJS }
func (Player) PlayerSettingsGet(server *wsevent.Server, so *wsevent.Client, data []byte) []byte { reqerr := chelpers.FilterRequest(so, 0, true) if reqerr != nil { return reqerr.Encode() } var args struct { Key string `json:"key"` } err := chelpers.GetParams(data, &args) if err != nil { return helpers.NewTPErrorFromError(err).Encode() } player, _ := models.GetPlayerBySteamId(chelpers.GetSteamId(so.Id())) var settings []models.PlayerSetting var setting models.PlayerSetting if args.Key == "*" { settings, err = player.GetSettings() } else { setting, err = player.GetSetting(args.Key) settings = append(settings, setting) } if err != nil { return helpers.NewTPErrorFromError(err).Encode() } result := models.DecoratePlayerSettingsJson(settings) resp, _ := chelpers.BuildSuccessJSON(result).Encode() return resp }
func (Player) PlayerProfile(server *wsevent.Server, so *wsevent.Client, data []byte) []byte { reqerr := chelpers.FilterRequest(so, 0, true) if reqerr != nil { return reqerr.Encode() } var args struct { Steamid string `json:"steamid"` } err := chelpers.GetParams(data, &args) if err != nil { return helpers.NewTPErrorFromError(err).Encode() } steamid := args.Steamid if steamid == "" { steamid = chelpers.GetSteamId(so.Id()) } player, playErr := models.GetPlayerWithStats(steamid) if playErr != nil { return playErr.Encode() } result := models.DecoratePlayerProfileJson(player) resp, _ := chelpers.BuildSuccessJSON(result).Encode() return resp }
func (Lobby) RequestLobbyListData(so *wsevent.Client, _ struct{}) interface{} { var lobbies []models.Lobby db.DB.Where("state = ?", models.LobbyStateWaiting).Order("id desc").Find(&lobbies) so.EmitJSON(helpers.NewRequest("lobbyListData", models.DecorateLobbyListData(lobbies))) return chelpers.EmptySuccessJS }
func (Player) PlayerSettingsSet(so *wsevent.Client, args struct { Key *string `json:"key"` Value *string `json:"value"` }) interface{} { player := chelpers.GetPlayer(so.Token) switch *args.Key { case "siteAlias": if len(*args.Value) > 32 { return errors.New("Site alias must be under 32 characters long.") } player.SetSetting(*args.Key, *args.Value) player.SetPlayerProfile() so.EmitJSON(helpers.NewRequest("playerProfile", player)) if lobbyID, _ := player.GetLobbyID(true); lobbyID != 0 { lob, _ := lobby.GetLobbyByID(lobbyID) slot, _ := lob.GetPlayerSlot(player) player.SetMumbleUsername(lob.Type, slot) lobby.BroadcastLobby(lob) } default: player.SetSetting(*args.Key, *args.Value) } return emptySuccess }
func (Lobby) LobbySpectatorJoin(server *wsevent.Server, so *wsevent.Client, data []byte) []byte { reqerr := chelpers.FilterRequest(so, authority.AuthAction(0), true) if reqerr != nil { bytes, _ := json.Marshal(reqerr) return bytes } var args struct { Id *uint `json:"id"` } if err := chelpers.GetParams(data, &args); err != nil { return helpers.NewTPErrorFromError(err).Encode() } var lob *models.Lobby lob, tperr := models.GetLobbyById(*args.Id) if tperr != nil { return tperr.Encode() } player, tperr := models.GetPlayerBySteamId(chelpers.GetSteamId(so.Id())) if tperr != nil { return tperr.Encode() } var specSameLobby bool arr, tperr := player.GetSpectatingIds() if len(arr) != 0 { for _, id := range arr { if id == *args.Id { specSameLobby = true continue } lobby, _ := models.GetLobbyById(id) lobby.RemoveSpectator(player, true) server.RemoveClient(so.Id(), fmt.Sprintf("%d_public", id)) } } // If the player is already in the lobby (either joined a slot or is spectating), don't add them. // Just Broadcast the lobby to them, so the frontend displays it. if id, _ := player.GetLobbyId(); id != *args.Id && !specSameLobby { tperr = lob.AddSpectator(player) if tperr != nil { return tperr.Encode() } chelpers.AfterLobbySpec(server, so, lob) } models.BroadcastLobbyToUser(lob, player.SteamId) return chelpers.EmptySuccessJS }
func (Lobby) RequestLobbyListData(_ *wsevent.Server, so *wsevent.Client, data []byte) []byte { var lobbies []models.Lobby db.DB.Where("state = ?", models.LobbyStateWaiting).Order("id desc").Find(&lobbies) list, _ := json.Marshal(models.DecorateLobbyListData(lobbies)) so.EmitJSON(helpers.NewRequest("lobbyListData", string(list))) return chelpers.EmptySuccessJS }
func BroadcastScrollback(so *wsevent.Client, room uint) { messages, err := chat.GetScrollback(int(room)) if err != nil { return } so.EmitJSON(helpers.NewRequest("chatScrollback", messages)) }
func (Global) GetSocketInfo(server *wsevent.Server, so *wsevent.Client, data []byte) []byte { socketinfo := struct { ID string `json:"id"` Rooms []string `json:"rooms"` }{so.Id(), server.RoomsJoined(so.Id())} bytes, _ := json.Marshal(socketinfo) return bytes }
func (Chat) ChatSend(server *wsevent.Server, so *wsevent.Client, data []byte) []byte { reqerr := chelpers.FilterRequest(so, 0, true) if reqerr != nil { return reqerr.Encode() } var args struct { Message *string `json:"message"` Room *int `json:"room"` } err := chelpers.GetParams(data, &args) if err != nil { return helpers.NewTPErrorFromError(err).Encode() } player, tperr := models.GetPlayerBySteamId(chelpers.GetSteamId(so.Id())) if tperr != nil { return tperr.Encode() } //helpers.Logger.Debug("received chat message: %s %s", *args.Message, player.Name) if *args.Room > 0 { spec := player.IsSpectatingId(uint(*args.Room)) //Check if player has either joined, or is spectating lobby lobbyId, tperr := player.GetLobbyId() if tperr != nil && !spec && lobbyId != uint(*args.Room) { return helpers.NewTPError("Player is not in the lobby.", 5).Encode() } } else { // else room is the lobby list room *args.Room, _ = strconv.Atoi(config.Constants.GlobalChatRoom) } if (*args.Message)[0] == '\n' { return helpers.NewTPError("Cannot send messages prefixed with newline", 4).Encode() } if len(*args.Message) > 120 { return helpers.NewTPError("Message too long", 4).Encode() } message := models.NewChatMessage(*args.Message, *args.Room, player) db.DB.Save(message) bytes, _ := json.Marshal(message) broadcaster.SendMessageToRoom(fmt.Sprintf("%s_public", chelpers.GetLobbyRoom(uint(*args.Room))), "chatReceive", string(bytes)) if strings.HasPrefix(*args.Message, "!admin") { chelpers.SendToSlack(*args.Message, player.Name, player.SteamId) } return chelpers.EmptySuccessJS }
func FilterRequest(so *wsevent.Client, action authority.AuthAction, login bool) (err *helpers.TPError) { if int(action) != 0 { var role, _ = GetPlayerRole(so.Id()) can := role.Can(action) if !can { err = helpers.NewTPError("You are not authorized to perform this action.", 0) } } return }
func AfterLobbyLeave(server *wsevent.Server, so *wsevent.Client, lobby *models.Lobby, player *models.Player) { //pub := fmt.Sprintf("%s_public", GetLobbyRoom(lobby.ID)) // bytes, _ := json.Marshal(models.DecorateLobbyData(lobby, true)) // broadcaster.SendMessageToRoom(pub, "lobbyData", string(bytes)) bytes, _ := json.Marshal(models.DecorateLobbyLeave(lobby)) broadcaster.SendMessage(player.SteamId, "lobbyLeft", string(bytes)) server.RemoveClient(so.Id(), fmt.Sprintf("%s_private", GetLobbyRoom(lobby.ID))) }
func BroadcastScrollback(so *wsevent.Client, room uint) { // bytes, _ := json.Marshal(ChatHistoryClearEvent{room}) // so.EmitJSON(helpers.NewRequest("chatHistoryClear", string(bytes))) messages, err := models.GetScrollback(int(room)) if err != nil { return } for i := len(messages) - 1; i != -1; i-- { so.EmitJSON(helpers.NewRequest("chatReceive", messages[i])) } }
func AfterConnect(server *wsevent.Server, so *wsevent.Client) { server.AddClient(so, fmt.Sprintf("%s_public", config.GlobalChatRoom)) //room for global chat var lobbies []models.Lobby err := db.DB.Where("state = ?", models.LobbyStateWaiting).Order("id desc").Find(&lobbies).Error if err != nil { logrus.Error(err) return } so.EmitJSON(helpers.NewRequest("lobbyListData", models.DecorateLobbyListData(lobbies))) chelpers.BroadcastScrollback(so, 0) so.EmitJSON(helpers.NewRequest("subListData", models.DecorateSubstituteList())) }
func SocketHandler(w http.ResponseWriter, r *http.Request) { //check if player is in the whitelist if config.Constants.SteamIDWhitelist != "" { allowed := false session, err := chelpers.GetSessionHTTP(r) if err == nil { steamid, ok := session.Values["steam_id"] allowed = ok && chelpers.IsSteamIDWhitelisted(steamid.(string)) } if !allowed { http.Error(w, "Sorry, but you're not in the closed alpha", 403) return } } session, err := chelpers.GetSessionHTTP(r) var so *wsevent.Client if err == nil { _, ok := session.Values["steam_id"] if ok { so, err = socket.AuthServer.NewClient(upgrader, w, r) } else { so, err = socket.UnauthServer.NewClient(upgrader, w, r) } pprof.Clients.Add(1) } else { var estr = "Couldn't create WebSocket connection." //estr = err.Error() logrus.Error(err.Error()) http.Error(w, estr, 500) return } if err != nil || so == nil { login.LogoutSession(w, r) return } //logrus.Debug("Connected to Socket") err = SocketInit(so) if err != nil { login.LogoutSession(w, r) so.Close() } }
func (Unauth) LobbySpectatorJoin(so *wsevent.Client, args struct { ID *uint `json:"id"` }) interface{} { lob, err := lobby.GetLobbyByID(*args.ID) if err != nil { return err } hooks.AfterLobbySpec(socket.UnauthServer, so, nil, lob) so.EmitJSON(helpers.NewRequest("lobbyData", lobby.DecorateLobbyData(lob, true))) return emptySuccess }
func (Lobby) UnAuthSpecJoin(so *wsevent.Client, args struct { ID *uint `json:"id"` }) interface{} { var lob *models.Lobby lob, tperr := models.GetLobbyByID(*args.ID) if tperr != nil { return tperr } hooks.AfterLobbySpec(socket.UnauthServer, so, lob) so.EmitJSON(helpers.NewRequest("lobbyData", models.DecorateLobbyData(lob, true))) return chelpers.EmptySuccessJS }
func SocketHandler(w http.ResponseWriter, r *http.Request) { token, err := chelpers.GetToken(r) if err != nil && err != http.ErrNoCookie { //invalid jwt token logrus.Errorf("Error reading JWT: %v", err) token = nil } //check if player is in the whitelist if config.Constants.SteamIDWhitelist != "" { if token == nil { // player isn't logged in, // and access is restricted to logged in people http.Error(w, "Not logged in", http.StatusForbidden) return } if !chelpers.IsSteamIDWhitelisted(token.Claims.(*chelpers.TF2StadiumClaims).SteamID) { http.Error(w, "you're not in the beta", http.StatusForbidden) return } } var so *wsevent.Client if token != nil { //received valid jwt so, err = socket.AuthServer.NewClient(upgrader, w, r) } else { so, err = socket.UnauthServer.NewClient(upgrader, w, r) } if err != nil { return } so.Token = token //logrus.Debug("Connected to Socket") err = SocketInit(so) if err != nil { logrus.Error(err) so.Close() return } }
func (Player) PlayerReady(_ *wsevent.Server, so *wsevent.Client, data []byte) []byte { reqerr := chelpers.FilterRequest(so, authority.AuthAction(0), true) if reqerr != nil { return reqerr.Encode() } steamid := chelpers.GetSteamId(so.Id()) player, tperr := models.GetPlayerBySteamId(steamid) if tperr != nil { return tperr.Encode() } lobbyid, tperr := player.GetLobbyId() if tperr != nil { return tperr.Encode() } lobby, tperr := models.GetLobbyByIdServer(lobbyid) if tperr != nil { return tperr.Encode() } if lobby.State != models.LobbyStateReadyingUp { return helpers.NewTPError("Lobby hasn't been filled up yet.", 4).Encode() } tperr = lobby.ReadyPlayer(player) if tperr != nil { return tperr.Encode() } if lobby.IsEveryoneReady() { db.DB.Table("lobbies").Where("id = ?", lobby.ID).Update("state", models.LobbyStateInProgress) chelpers.BroadcastLobbyStart(lobby) models.BroadcastLobbyList() models.FumbleLobbyStarted(lobby) } return chelpers.EmptySuccessJS }
func (Lobby) LobbyServerReset(server *wsevent.Server, so *wsevent.Client, data []byte) []byte { reqerr := chelpers.FilterRequest(so, authority.AuthAction(0), true) if reqerr != nil { return reqerr.Encode() } var args struct { ID *uint `json:"id"` } if err := chelpers.GetParams(data, &args); err != nil { return helpers.NewTPErrorFromError(err).Encode() } player, err := models.GetPlayerBySteamId(chelpers.GetSteamId(so.Id())) if err != nil { return err.Encode() } lobby, tperr := models.GetLobbyById(*args.ID) if player.SteamId != lobby.CreatedBySteamID { return helpers.NewTPError("Player not authorized to close lobby.", -1).Encode() } if tperr != nil { return tperr.Encode() } if lobby.State == models.LobbyStateEnded { return helpers.NewTPError("Lobby has ended", 1).Encode() } if err := models.ReExecConfig(lobby.ID); err != nil { return helpers.NewTPErrorFromError(err).Encode() } return chelpers.EmptySuccessJS }
func (Lobby) LobbyBan(server *wsevent.Server, so *wsevent.Client, data []byte) []byte { reqerr := chelpers.FilterRequest(so, authority.AuthAction(0), true) if reqerr != nil { return reqerr.Encode() } var args struct { Id *uint `json:"id"` Steamid *string `json:"steamid"` } if err := chelpers.GetParams(data, &args); err != nil { return helpers.NewTPErrorFromError(err).Encode() } steamId := *args.Steamid selfSteamId := chelpers.GetSteamId(so.Id()) if steamId == selfSteamId { return helpers.NewTPError("Player can't kick himself.", -1).Encode() } if ok, tperr := playerCanKick(*args.Id, selfSteamId); !ok { return tperr.Encode() } lob, player, tperr := removePlayerFromLobby(*args.Id, steamId) if tperr != nil { return tperr.Encode() } lob.BanPlayer(player) so, _ = broadcaster.GetSocket(player.SteamId) chelpers.AfterLobbyLeave(server, so, lob, player) broadcaster.SendMessage(steamId, "sendNotification", fmt.Sprintf(`{"notification": "You have been removed from Lobby #%d"}`, *args.Id)) return chelpers.EmptySuccessJS }
func AfterConnect(server *wsevent.Server, so *wsevent.Client) { server.AddClient(so, fmt.Sprintf("%s_public", config.Constants.GlobalChatRoom)) //room for global chat var lobbies []models.Lobby err := db.DB.Where("state = ?", models.LobbyStateWaiting).Order("id desc").Find(&lobbies).Error if err != nil { helpers.Logger.Critical("%s", err.Error()) return } bytes, _ := json.Marshal(models.DecorateLobbyListData(lobbies)) if err != nil { helpers.Logger.Critical("Failed to send lobby list: %s", err.Error()) return } so.EmitJSON(helpers.NewRequest("lobbyListData", string(bytes))) BroadcastScrollback(so, 0) bytes, _ = json.Marshal(helpers.NewRequestFromObj("subListData", models.GetSubList())) so.EmitJSON(helpers.NewRequest("subListData", string(bytes))) }
//SocketInit initializes the websocket connection for the provided socket func SocketInit(so *wsevent.Client) error { chelpers.AuthenticateSocket(so.ID, so.Request) loggedIn := chelpers.IsLoggedInSocket(so.ID) if loggedIn { steamid := chelpers.GetSteamId(so.ID) sessions.AddSocket(steamid, so) } if loggedIn { hooks.AfterConnect(socket.AuthServer, so) player, err := models.GetPlayerBySteamID(chelpers.GetSteamId(so.ID)) if err != nil { logrus.Warning( "User has a cookie with but a matching player record doesn't exist: %s", chelpers.GetSteamId(so.ID)) chelpers.DeauthenticateSocket(so.ID) hooks.AfterConnect(socket.UnauthServer, so) return ErrRecordNotFound } hooks.AfterConnectLoggedIn(so, player) } else { hooks.AfterConnect(socket.UnauthServer, so) so.EmitJSON(helpers.NewRequest("playerSettings", "{}")) so.EmitJSON(helpers.NewRequest("playerProfile", "{}")) } so.EmitJSON(helpers.NewRequest("socketInitialized", "{}")) return nil }
func (Lobby) LobbyClose(server *wsevent.Server, so *wsevent.Client, data []byte) []byte { reqerr := chelpers.FilterRequest(so, authority.AuthAction(0), true) if reqerr != nil { return reqerr.Encode() } var args struct { Id *uint `json:"id"` } if err := chelpers.GetParams(data, &args); err != nil { return helpers.NewTPErrorFromError(err).Encode() } player, _ := models.GetPlayerBySteamId(chelpers.GetSteamId(so.Id())) lob, tperr := models.GetLobbyByIdServer(uint(*args.Id)) if tperr != nil { return tperr.Encode() } if player.SteamId != lob.CreatedBySteamID && player.Role != helpers.RoleAdmin { return helpers.NewTPError("Player not authorized to close lobby.", -1).Encode() } if lob.State == models.LobbyStateEnded { return helpers.NewTPError("Lobby already closed.", -1).Encode() } models.FumbleLobbyEnded(lob) lob.Close(true) models.BroadcastLobbyList() // has to be done manually for now return chelpers.EmptySuccessJS }
func (Lobby) LobbySpectatorLeave(server *wsevent.Server, so *wsevent.Client, data []byte) []byte { reqerr := chelpers.FilterRequest(so, authority.AuthAction(0), true) if reqerr != nil { return reqerr.Encode() } var args struct { Id *uint `json:"id"` } if err := chelpers.GetParams(data, &args); err != nil { return helpers.NewTPErrorFromError(err).Encode() } steamId := chelpers.GetSteamId(so.Id()) player, tperr := models.GetPlayerBySteamId(steamId) if tperr != nil { return tperr.Encode() } lob, tperr := models.GetLobbyById(*args.Id) if tperr != nil { return tperr.Encode() } if !player.IsSpectatingId(lob.ID) { if id, _ := player.GetLobbyId(); id == *args.Id { chelpers.AfterLobbySpecLeave(server, so, lob) return chelpers.EmptySuccessJS } return helpers.NewTPError("Player is not spectating", -1).Encode() } lob.RemoveSpectator(player, true) chelpers.AfterLobbySpecLeave(server, so, lob) return chelpers.EmptySuccessJS }
func (Player) PlayerNotReady(_ *wsevent.Server, so *wsevent.Client, data []byte) []byte { reqerr := chelpers.FilterRequest(so, authority.AuthAction(0), true) if reqerr != nil { return reqerr.Encode() } player, tperr := models.GetPlayerBySteamId(chelpers.GetSteamId(so.Id())) if tperr != nil { return tperr.Encode() } lobbyid, tperr := player.GetLobbyId() if tperr != nil { return tperr.Encode() } lobby, tperr := models.GetLobbyById(lobbyid) if tperr != nil { return tperr.Encode() } if lobby.State != models.LobbyStateReadyingUp { return helpers.NewTPError("Lobby hasn't been filled up yet.", 4).Encode() } tperr = lobby.UnreadyPlayer(player) lobby.RemovePlayer(player) if tperr != nil { return tperr.Encode() } lobby.UnreadyAllPlayers() return chelpers.EmptySuccessJS }
func AfterConnectLoggedIn(server *wsevent.Server, so *wsevent.Client, player *models.Player) { lobbyIdPlaying, err := player.GetLobbyId() if err == nil { lobby, _ := models.GetLobbyByIdServer(lobbyIdPlaying) AfterLobbyJoin(server, so, lobby, player) AfterLobbySpec(server, so, lobby) models.BroadcastLobbyToUser(lobby, GetSteamId(so.Id())) slot := &models.LobbySlot{} err := db.DB.Where("lobby_id = ? AND player_id = ?", lobby.ID, player.ID).First(slot).Error if err == nil { if lobby.State == models.LobbyStateInProgress && !models.IsPlayerInServer(player.SteamId) { bytes, _ := json.Marshal(models.DecorateLobbyConnect(lobby, player.Name, slot.Class)) broadcaster.SendMessage(player.SteamId, "lobbyStart", string(bytes)) } else if lobby.State == models.LobbyStateReadyingUp && !slot.Ready { data := struct { Timeout int64 `json:"timeout"` }{lobby.ReadyUpTimeLeft()} bytes, _ := json.Marshal(data) broadcaster.SendMessage(player.SteamId, "lobbyReadyUp", string(bytes)) } } } settings, err2 := player.GetSettings() if err2 == nil { bytes, _ := json.Marshal(models.DecoratePlayerSettingsJson(settings)) broadcaster.SendMessage(player.SteamId, "playerSettings", string(bytes)) } profilePlayer, err3 := models.GetPlayerWithStats(player.SteamId) if err3 == nil { bytes, _ := json.Marshal(models.DecoratePlayerProfileJson(profilePlayer)) broadcaster.SendMessage(player.SteamId, "playerProfile", string(bytes)) } }
func (Admin) AdminChangeRole(server *wsevent.Server, so *wsevent.Client, data []byte) []byte { reqerr := chelpers.FilterRequest(so, 0, true) if reqerr != nil { return reqerr.Encode() } var args struct { Steamid *string `json:"steamid"` Role *string `json:"role"` } err := chelpers.GetParams(data, &args) if err != nil { return helpers.NewTPErrorFromError(err).Encode() } role, ok := helpers.RoleMap[*args.Role] if !ok || role == helpers.RoleAdmin { return helpers.NewTPError("Invalid role parameter", 0).Encode() } otherPlayer, err := models.GetPlayerBySteamId(*args.Steamid) if err != nil { return helpers.NewTPError("Player not found.", 0).Encode() } currPlayer, _ := chelpers.GetPlayerSocket(so.Id()) models.LogAdminAction(currPlayer.ID, helpers.ActionChangeRole, otherPlayer.ID) // actual change happens otherPlayer.Role = role db.DB.Save(&otherPlayer) // rewrite session data. THIS WON'T WRITE A COOKIE SO IT ONLY WORKS WITH // STORES THAT STORE DATA IN COOKIES (AND NOT ONLY SESSION ID). session, sesserr := chelpers.GetSessionHTTP(so.Request()) if sesserr == nil { session.Values["role"] = role session.Save(so.Request(), FakeResponseWriter{}) } return chelpers.EmptySuccessJS }