func (Player) PlayerNotReady(so *wsevent.Client, _ struct{}) interface{} { player, tperr := models.GetPlayerBySteamID(chelpers.GetSteamId(so.ID)) if tperr != nil { return tperr } lobbyid, tperr := player.GetLobbyID(false) if tperr != nil { return tperr } lobby, tperr := models.GetLobbyByID(lobbyid) if tperr != nil { return tperr } if lobby.State != models.LobbyStateReadyingUp { return helpers.NewTPError("Lobby hasn't been filled up yet.", 4) } tperr = lobby.UnreadyPlayer(player) lobby.RemovePlayer(player) hooks.AfterLobbyLeave(lobby, player) lobby.AddSpectator(player) hooks.AfterLobbySpec(socket.AuthServer, so, lobby) if tperr != nil { return tperr } lobby.UnreadyAllPlayers() return chelpers.EmptySuccessJS }
func (Lobby) LobbyServerReset(so *wsevent.Client, args struct { ID *uint `json:"id"` }) interface{} { player := chelpers.GetPlayerFromSocket(so.ID) lobby, tperr := models.GetLobbyByID(*args.ID) if player.SteamID != lobby.CreatedBySteamID || player.Role != helpers.RoleAdmin { return helpers.NewTPError("Player not authorized to reset server.", -1) } if tperr != nil { return tperr } if lobby.State == models.LobbyStateEnded { return helpers.NewTPError("Lobby has ended", 1) } if err := models.ReExecConfig(lobby.ID); err != nil { return helpers.NewTPErrorFromError(err) } 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 removePlayerFromLobby(lobbyId uint, steamId string) (*models.Lobby, *models.Player, *helpers.TPError) { player, tperr := models.GetPlayerBySteamID(steamId) if tperr != nil { return nil, nil, tperr } lob, tperr := models.GetLobbyByID(lobbyId) if tperr != nil { return nil, nil, tperr } switch lob.State { case models.LobbyStateInProgress: return lob, player, helpers.NewTPError("Lobby is in progress.", 1) case models.LobbyStateEnded: return lob, player, helpers.NewTPError("Lobby has closed.", 1) } _, err := lob.GetPlayerSlot(player) if err != nil { return lob, player, helpers.NewTPError("Player not playing", 2) } if err := lob.RemovePlayer(player); err != nil { return lob, player, err } return lob, player, lob.AddSpectator(player) }
func playerSub(playerID, lobbyID uint) { player, _ := models.GetPlayerByID(playerID) lobby, _ := models.GetLobbyByID(lobbyID) lobby.Substitute(player) models.SendNotification(fmt.Sprintf("%s has been reported.", player.Name), int(lobby.ID)) }
func playerConn(playerID, lobbyID uint) { player, _ := models.GetPlayerByID(playerID) lobby, _ := models.GetLobbyByID(lobbyID) lobby.SetInGame(player) models.SendNotification(fmt.Sprintf("%s has connected to the server.", player.Alias()), int(lobby.ID)) }
//OnDisconnect is connected when a player with a given socketID disconnects func OnDisconnect(socketID string) { pprof.Clients.Add(-1) defer chelpers.DeauthenticateSocket(socketID) if chelpers.IsLoggedInSocket(socketID) { steamid := chelpers.GetSteamId(socketID) sessions.RemoveSocket(socketID, steamid) player, tperr := models.GetPlayerBySteamID(steamid) if tperr != nil || player == nil { logrus.Error(tperr.Error()) return } ids, tperr := player.GetSpectatingIds() if tperr != nil { logrus.Error(tperr.Error()) return } for _, id := range ids { //if this _specific_ socket is spectating this lobby, remove them from it //player might be spectating other lobbies in another tab, but we don't care if sessions.IsSpectating(socketID, id) { lobby, _ := models.GetLobbyByID(id) err := lobby.RemoveSpectator(player, true) if err != nil { logrus.Error(err.Error()) continue } sessions.RemoveSpectator(socketID) //logrus.Debug("removing %s from %d", player.SteamId, id) } } id, _ := player.GetLobbyID(true) //if player is in a waiting lobby, and hasn't connected for > 30 seconds, //remove him from it. Here, connected = player isn't connected from any tab/window if id != 0 && sessions.ConnectedSockets(player.SteamID) == 0 { time.AfterFunc(time.Second*30, func() { if !sessions.IsConnected(player.SteamID) { //player may have changed lobbies during this time //fetch lobby ID again id, err := player.GetLobbyID(true) if err != nil { return } lobby := &models.Lobby{} db.DB.First(lobby, id) lobby.RemovePlayer(player) } }) } } }
func playerCanKick(lobbyId uint, steamId string) (bool, *helpers.TPError) { lob, tperr := models.GetLobbyByID(lobbyId) if tperr != nil { return false, tperr } player, tperr2 := models.GetPlayerBySteamID(steamId) if tperr2 != nil { return false, tperr2 } if steamId != lob.CreatedBySteamID && player.Role != helpers.RoleAdmin { return false, helpers.NewTPError("Not authorized to kick players", 1) } return true, nil }
func playerDisc(playerID, lobbyID uint) { player, _ := models.GetPlayerByID(playerID) lobby, _ := models.GetLobbyByID(lobbyID) lobby.SetNotInGame(player) models.SendNotification(fmt.Sprintf("%s has disconected from the server.", player.Name), int(lobby.ID)) time.AfterFunc(time.Minute*2, func() { ingame, err := lobby.IsPlayerInGame(player) if err != nil { logrus.Error(err.Error()) } if !ingame && lobby.CurrentState() != models.LobbyStateEnded { lobby.Substitute(player) } }) }
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 (Lobby) LobbySpectatorJoin(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 } player := chelpers.GetPlayerFromSocket(so.ID) var specSameLobby bool arr, tperr := player.GetSpectatingIds() if len(arr) != 0 { for _, id := range arr { if id == *args.Id { specSameLobby = true continue } //a socket should only spectate one lobby, remove socket from //any other lobby room //multiple sockets from one player can spectatte multiple lobbies socket.AuthServer.RemoveClient(so, 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(false); id != *args.Id && !specSameLobby { tperr = lob.AddSpectator(player) if tperr != nil { return tperr } } hooks.AfterLobbySpec(socket.AuthServer, so, lob) models.BroadcastLobbyToUser(lob, player.SteamID) return chelpers.EmptySuccessJS }
func (Lobby) LobbySpectatorLeave(so *wsevent.Client, args struct { Id *uint `json:"id"` }) interface{} { player := chelpers.GetPlayerFromSocket(so.ID) lob, tperr := models.GetLobbyByID(*args.Id) if tperr != nil { return tperr } if !player.IsSpectatingID(lob.ID) { if id, _ := player.GetLobbyID(false); id == *args.Id { hooks.AfterLobbySpecLeave(so, lob) return chelpers.EmptySuccessJS } } lob.RemoveSpectator(player, true) hooks.AfterLobbySpecLeave(so, lob) return chelpers.EmptySuccessJS }
func (Lobby) LobbyJoin(so *wsevent.Client, args struct { Id *uint `json:"id"` Class *string `json:"class"` Team *string `json:"team" valid:"red,blu"` Password *string `json:"password" empty:"-"` }) interface{} { player := chelpers.GetPlayerFromSocket(so.ID) if banned, until := player.IsBannedWithTime(models.PlayerBanJoin); banned { str := fmt.Sprintf("You have been banned from joining lobbies till %s", until.Format(time.RFC822)) return helpers.NewTPError(str, -1) } //logrus.Debug("id %d class %s team %s", *args.Id, *args.Class, *args.Team) lob, tperr := models.GetLobbyByID(*args.Id) if tperr != nil { return tperr } if lob.State == models.LobbyStateEnded { return helpers.NewTPError("Cannot join a closed lobby.", -1) } //Check if player is in the same lobby var sameLobby bool if id, err := player.GetLobbyID(false); err == nil && id == *args.Id { sameLobby = true } slot, tperr := models.LobbyGetPlayerSlot(lob.Type, *args.Team, *args.Class) if tperr != nil { return tperr } if prevId, _ := player.GetLobbyID(false); prevId != 0 && !sameLobby { lobby, _ := models.GetLobbyByID(prevId) hooks.AfterLobbyLeave(lobby, player) } tperr = lob.AddPlayer(player, slot, *args.Password) if tperr != nil { return tperr } if !sameLobby { hooks.AfterLobbyJoin(so, lob, player) } //check if lobby isn't already in progress (which happens when the player is subbing) if lob.IsFull() && lob.State != models.LobbyStateInProgress { lob.State = models.LobbyStateReadyingUp lob.ReadyUpTimestamp = time.Now().Unix() + 30 lob.Save() time.AfterFunc(time.Second*30, func() { lobby := &models.Lobby{} db.DB.First(lobby, lob.ID) //if all player's haven't readied up, //remove unreadied players and unready the //rest. if lobby.State != models.LobbyStateInProgress && lobby.State != models.LobbyStateEnded { removeUnreadyPlayers(lobby) lobby.State = models.LobbyStateWaiting lobby.Save() } }) room := fmt.Sprintf("%s_private", hooks.GetLobbyRoom(lob.ID)) broadcaster.SendMessageToRoom(room, "lobbyReadyUp", struct { Timeout int `json:"timeout"` }{30}) models.BroadcastLobbyList() } if lob.State == models.LobbyStateInProgress { //this happens when the player is a substitute db.DB.Preload("ServerInfo").First(lob, lob.ID) so.EmitJSON(helpers.NewRequest("lobbyStart", models.DecorateLobbyConnect(lob, player.Name, slot))) } return chelpers.EmptySuccessJS }