func (Lobby) ServerVerify(so *wsevent.Client, args struct { Server *string `json:"server"` Rconpwd *string `json:"rconpwd"` }) interface{} { if !validAddress.MatchString(*args.Server) { return helpers.NewTPError("Invalid Server Address", -1) } var count int db.DB.Table("server_records").Where("host = ?", *args.Server).Count(&count) if count != 0 { return helpers.NewTPError("A lobby is already using this server.", -1) } info := &models.ServerRecord{ Host: *args.Server, RconPassword: *args.Rconpwd, } db.DB.Save(info) defer db.DB.Where("host = ?", info.Host).Delete(models.ServerRecord{}) err := models.VerifyInfo(*info) if err != nil { return helpers.NewTPErrorFromError(err) } return chelpers.EmptySuccessJS }
func (lobby *Lobby) TrySettingUp() *helpers.TPError { if _, ok := LobbyServerSettingUp[lobby.ID]; ok { return helpers.NewTPError("Lobby setup already in progress", -1) } if lobby.Server == nil { return helpers.NewTPError("Lobby doesn't have a server attached", -1) } LobbyServerSettingUp[lobby.ID] = time.Now() err := lobby.Server.Setup() delete(LobbyServerSettingUp, lobby.ID) if err != nil { lobby.Close() return helpers.NewTPError(err.Error(), -1) } lobby.State = LobbyStateWaiting db.DB.Save(lobby) return nil }
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 (Lobby) LobbyClose(so *wsevent.Client, args struct { Id *uint `json:"id"` }) interface{} { player := chelpers.GetPlayerFromSocket(so.ID) lob, tperr := models.GetLobbyByIDServer(uint(*args.Id)) if tperr != nil { return tperr } if player.SteamID != lob.CreatedBySteamID && player.Role != helpers.RoleAdmin { return helpers.NewTPError("Player not authorized to close lobby.", -1) } if lob.State == models.LobbyStateEnded { return helpers.NewTPError("Lobby already closed.", -1) } lob.Close(true) notify := fmt.Sprintf("Lobby closed by %s", player.Name) models.SendNotification(notify, int(lob.ID)) 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 (Chat) ChatDelete(so *wsevent.Client, args struct { ID *int `json:"id"` Room *uint `json:"room"` }) interface{} { if err := chelpers.CheckPrivilege(so, helpers.ActionDeleteChat); err != nil { return err } message := &models.ChatMessage{} err := db.DB.Table("chat_messages").Where("room = ? AND id = ?", args.Room, args.ID).First(message).Error if message.Bot { return helpers.NewTPError("Cannot delete notification messages", -1) } if err != nil { return helpers.NewTPError("Can't find message", -1) } player, _ := models.GetPlayerByID(message.PlayerID) message.Deleted = true message.Timestamp = message.CreatedAt.Unix() message.Save() message.Message = "<deleted>" message.Player = models.DecoratePlayerSummary(player) message.Player.Tags = append(message.Player.Tags, "deleted") message.Send() return chelpers.EmptySuccessJS }
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 (Chat) ChatSend(so *wsevent.Client, args struct { Message *string `json:"message"` Room *int `json:"room"` }) interface{} { playerID := chelpers.GetPlayerID(so.ID) now := time.Now().Unix() if now-lastChatTime[playerID] == 0 { return helpers.NewTPError("You're sending messages too quickly", -1) } lastChatTime[playerID] = now player, _ := models.GetPlayerByID(playerID) //logrus.Debug("received chat message: %s %s", *args.Message, player.Name) if *args.Room > 0 { var count int spec := player.IsSpectatingID(uint(*args.Room)) //Check if player has either joined, or is spectating lobby db.DB.Table("lobby_slots").Where("lobby_id = ? AND player_id = ?", *args.Room, player.ID).Count(&count) if !spec && count == 0 { return helpers.NewTPError("Player is not in the lobby.", 5) } } else { // else room is the lobby list room *args.Room, _ = strconv.Atoi(config.GlobalChatRoom) } switch { case len(*args.Message) == 0: return helpers.NewTPError("Cannot send an empty message", 4) case (*args.Message)[0] == '\n': return helpers.NewTPError("Cannot send messages prefixed with newline", 4) case len(*args.Message) > 150: return helpers.NewTPError("Message too long", 4) } message := models.NewChatMessage(*args.Message, *args.Room, player) message.Save() if strings.HasPrefix(*args.Message, "!admin") { chelpers.SendToSlack(*args.Message, player.Name, player.SteamID) return chelpers.EmptySuccessJS } message.Send() return chelpers.EmptySuccessJS }
func LobbyGetPlayerSlot(lobbytype LobbyType, teamStr string, classStr string) (int, *helpers.TPError) { team, ok := teamMap[teamStr] if !ok { return -1, helpers.NewTPError("Invalid team", -1) } class, ok := TypeClassMap[lobbytype][classStr] if !ok { return -1, helpers.NewTPError("Invalid class", -1) } return team*NumberOfClassesMap[lobbytype] + class, nil }
func (Lobby) LobbyBan(so *wsevent.Client, args struct { Id *uint `json:"id"` Steamid *string `json:"steamid"` }) interface{} { steamId := *args.Steamid selfSteamId := chelpers.GetSteamId(so.ID) if steamId == selfSteamId { return helpers.NewTPError("Player can't kick himself.", -1) } if ok, tperr := playerCanKick(*args.Id, selfSteamId); !ok { return tperr } lob, player, tperr := removePlayerFromLobby(*args.Id, steamId) if tperr != nil { return tperr } lob.BanPlayer(player) hooks.AfterLobbyLeave(lob, player) // broadcaster.SendMessage(steamId, "sendNotification", // fmt.Sprintf(`{"notification": "You have been removed from Lobby #%d"}`, *args.Id)) return chelpers.EmptySuccessJS }
func (lobby *Lobby) RemoveSpectator(player *Player) *helpers.TPError { err := db.DB.Model(lobby).Association("Spectators").Delete(player).Error if err != nil { return helpers.NewTPError(err.Error(), -1) } return nil }
func (Lobby) ServerVerify(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 { Server *string `json:"server"` Rconpwd *string `json:"rconpwd"` } if err := chelpers.GetParams(data, &args); err != nil { return helpers.NewTPErrorFromError(err).Encode() } var count int db.DB.Table("server_records").Where("host = ?", *args.Server).Count(&count) if count != 0 { return helpers.NewTPError("A lobby is already using this server.", -1).Encode() } info := models.ServerRecord{ Host: *args.Server, RconPassword: *args.Rconpwd, } err := models.VerifyInfo(info) if err != nil { return helpers.NewTPErrorFromError(err).Encode() } 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) 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 *Lobby) AddSpectator(player *Player) *helpers.TPError { err := db.DB.Model(lobby).Association("Spectators").Append(player).Error if err != nil { return helpers.NewTPError(err.Error(), -1) } lobby.OnChange(false) return nil }
func (lobby *Lobby) IsPlayerReady(player *Player) (bool, *helpers.TPError) { var ready []bool err := db.DB.Table("lobby_slots").Where("lobby_id = ? AND player_id = ?", lobby.ID, player.ID).Pluck("ready", &ready).Error if err != nil { return false, helpers.NewTPError("Player is not in the lobby.", 5) } return (len(ready) != 0 && ready[0]), nil }
func (lobby *Lobby) ReadyPlayer(player *Player) *helpers.TPError { err := db.DB.Table("lobby_slots").Where("lobby_id = ? AND player_id = ?", lobby.ID, player.ID).UpdateColumn("ready", true).Error if err != nil { return helpers.NewTPError("Player is not in the lobby.", 5) } lobby.OnChange(false) return nil }
func GetPlayerBySteamId(steamid string) (*Player, *helpers.TPError) { var player = Player{} err := db.DB.Where("steam_id = ?", steamid).First(&player).Error if err != nil { return nil, helpers.NewTPError("Player is not in the database", -1) } return &player, nil }
func (lobby *Lobby) IsPlayerReady(player *Player) (bool, *helpers.TPError) { slot := &LobbySlot{} err := db.DB.Where("lobby_id = ? AND player_id = ?", lobby.ID, player.ID).First(slot).Error if err != nil { return false, helpers.NewTPError("Player is not in the lobby.", 5) } return slot.Ready, nil }
func (lobby *Lobby) RemovePlayer(player *Player) *helpers.TPError { err := db.DB.Where("player_id = ? AND lobby_id = ?", player.ID, lobby.ID).Delete(&LobbySlot{}).Error lobby.updateServerAllowedPlayers() if err != nil { return helpers.NewTPError(err.Error(), -1) } return nil }
// shitlord func CheckPrivilege(so *wsevent.Client, action authority.AuthAction) (err *helpers.TPError) { //Checks if the client has the neccesary authority to perform action player, _ := models.GetPlayerBySteamID(GetSteamId(so.ID)) if !player.Role.Can(action) { return helpers.NewTPError("You are not authorized to perform this action", -1) } return }
func (lobby *Lobby) RemovePlayer(player *Player) *helpers.TPError { err := db.DB.Where("player_id = ? AND lobby_id = ?", player.ID, lobby.ID).Delete(&LobbySlot{}).Error if err != nil { return helpers.NewTPError(err.Error(), -1) } lobby.OnChange(true) return nil }
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 }
func (lobby *Lobby) RemoveSpectator(player *Player, broadcast bool) *helpers.TPError { err := db.DB.Model(lobby).Association("Spectators").Delete(player).Error if err != nil { return helpers.NewTPError(err.Error(), -1) } if broadcast { lobby.OnChange(false) } return nil }
func (lobby *Lobby) ReadyPlayer(player *Player) *helpers.TPError { slot := &LobbySlot{} err := db.DB.Where("lobby_id = ? AND player_id = ?", lobby.ID, player.ID).First(slot).Error if err != nil { return helpers.NewTPError("Player is not in the lobby.", 5) } slot.Ready = true db.DB.Save(slot) return nil }
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 (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 LobbyGetSlotInfo(lobbytype LobbyType, slot int) (int, int, *helpers.TPError) { classList := TypeClassList[lobbytype] if slot < len(classList) { return 0, slot, nil } else if slot < 2*len(classList) { return 1, slot - len(classList), nil } else { return 0, 0, helpers.NewTPError("Invalid slot", -1) } }
func (lobby *Lobby) SetupServer() error { if lobby.State == LobbyStateEnded { return nil } err := SetupServer(lobby.ID, lobby.ServerInfo, lobby.Type, lobby.League, lobby.Whitelist, lobby.MapName) if err != nil { return helpers.NewTPError(err.Error(), 0) } return nil }
func (lobby *Lobby) AddSpectator(player *Player) *helpers.TPError { if _, err := lobby.GetPlayerSlot(player); err == nil { return lobby.RemovePlayer(player) } err := db.DB.Model(lobby).Association("Spectators").Append(player).Error if err != nil { return helpers.NewTPError(err.Error(), -1) } return nil }