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 (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) LobbyCreate(so *wsevent.Client, args struct { Map *string `json:"map"` Type *string `json:"type" valid:"debug,6s,highlander,4v4,ultiduo,bball"` League *string `json:"league" valid:"ugc,etf2l,esea,asiafortress,ozfortress"` Server *string `json:"server"` RconPwd *string `json:"rconpwd"` WhitelistID *string `json:"whitelistID"` Mumble *bool `json:"mumbleRequired"` Password *string `json:"password" empty:"-"` SteamGroupWhitelist *string `json:"steamGroupWhitelist" empty:"-"` Requirements *struct { Classes map[string]Requirement `json:"classes,omitempty"` General Requirement `json:"general,omitempty"` } `json:"requirements" empty:"-"` }) interface{} { player := chelpers.GetPlayerFromSocket(so.ID) if banned, until := player.IsBannedWithTime(models.PlayerBanCreate); banned { str := fmt.Sprintf("You've been banned from creating lobbies till %s", until.Format(time.RFC822)) return helpers.NewTPError(str, -1) } var steamGroup string if *args.SteamGroupWhitelist != "" && !rSteamGroup.MatchString(*args.SteamGroupWhitelist) { return helpers.NewTPError("Invalid Steam group URL", -1) } else if rSteamGroup.MatchString(*args.SteamGroupWhitelist) { steamGroup = rSteamGroup.FindStringSubmatch(*args.SteamGroupWhitelist)[1] } var playermap = map[string]models.LobbyType{ "debug": models.LobbyTypeDebug, "6s": models.LobbyTypeSixes, "highlander": models.LobbyTypeHighlander, "ultiduo": models.LobbyTypeUltiduo, "bball": models.LobbyTypeBball, "4v4": models.LobbyTypeFours, } lobbyType := playermap[*args.Type] 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) } randBytes := make([]byte, 6) rand.Read(randBytes) serverPwd := base64.URLEncoding.EncodeToString(randBytes) //TODO what if playermap[lobbytype] is nil? info := models.ServerRecord{ Host: *args.Server, RconPassword: *args.RconPwd, ServerPassword: serverPwd} // err = models.VerifyInfo(info) // if err != nil { // bytes, _ := helpers.NewTPErrorFromError(err).Encode() // return string(bytes) // } lob := models.NewLobby(*args.Map, lobbyType, *args.League, info, *args.WhitelistID, *args.Mumble, steamGroup, *args.Password) lob.CreatedBySteamID = player.SteamID lob.RegionCode, lob.RegionName = chelpers.GetRegion(*args.Server) if (lob.RegionCode == "" || lob.RegionName == "") && config.Constants.GeoIP != "" { return helpers.NewTPError("Couldn't find region server.", 1) } lob.Save() err := lob.SetupServer() if err != nil { //lobby setup failed, delete lobby and corresponding server record qerr := db.DB.Where("id = ?", lob.ID).Delete(&models.Lobby{}).Error if qerr != nil { logrus.Warning(qerr.Error()) } db.DB.Delete(&lob.ServerInfo) return helpers.NewTPErrorFromError(err) } lob.State = models.LobbyStateWaiting lob.Save() models.FumbleLobbyCreated(lob) if args.Requirements != nil { for class, requirement := range (*args.Requirements).Classes { if requirement.Restricted.Blu { err := newRequirement("blu", class, requirement, lob) if err != nil { return err } } if requirement.Restricted.Red { err := newRequirement("red", class, requirement, lob) if err != nil { return err } } } if args.Requirements.General.Hours != 0 || args.Requirements.General.Lobbies != 0 { general := &models.Requirement{ LobbyID: lob.ID, Hours: args.Requirements.General.Hours, Lobbies: args.Requirements.General.Lobbies, Slot: -1, } general.Save() } } return chelpers.NewResponse( struct { ID uint `json:"id"` }{lob.ID}) }
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 }