Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 3
0
func (Player) PlayerNotReady(so *wsevent.Client, _ struct{}) interface{} {
	player := chelpers.GetPlayer(so.Token)
	lobbyid, tperr := player.GetLobbyID(false)
	if tperr != nil {
		return tperr
	}

	lob, err := lobby.GetLobbyByID(lobbyid)
	if err != nil {
		return err
	}

	if lob.State != lobby.ReadyingUp {
		return errors.New("Lobby hasn't been filled up yet.")
	}

	err = lob.UnreadyPlayer(player)
	lob.RemovePlayer(player)
	hooks.AfterLobbyLeave(lob, player, false, false)
	if spec := sessions.IsSpectating(so.ID, lob.ID); spec {
		// IsSpectating checks if the player has joined the lobby's public room
		lob.AddSpectator(player)
	}

	if tperr != nil {
		return tperr
	}

	lob.SetState(lobby.Waiting)
	lob.UnreadyAllPlayers()
	lobby.BroadcastLobby(lob)
	return emptySuccess
}
Ejemplo n.º 4
0
func (Lobby) LobbyBan(so *wsevent.Client, args struct {
	Id      *uint   `json:"id"`
	Steamid *string `json:"steamid"`
}) interface{} {

	steamId := *args.Steamid
	selfSteamId := so.Token.Claims.(*chelpers.TF2StadiumClaims).SteamID

	if steamId == selfSteamId {
		return errors.New("Player can't kick himself.")
	}
	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, true, false)

	// broadcaster.SendMessage(steamId, "sendNotification",
	// 	fmt.Sprintf(`{"notification": "You have been removed from Lobby #%d"}`, *args.Id))

	return emptySuccess
}
Ejemplo n.º 5
0
//get list of unready players, remove them from lobby (and add them as spectators)
//plus, call the after lobby leave hook for each player removed
func removeUnreadyPlayers(lobby *lobby.Lobby) {
	players := lobby.GetUnreadyPlayers()
	lobby.RemoveUnreadyPlayers(true)

	for _, player := range players {
		hooks.AfterLobbyLeave(lobby, player, false, true)
	}
}
Ejemplo n.º 6
0
func removeUnreadyPlayers(lobby *models.Lobby) {
	var players []*models.Player

	db.DB.Table("players").Joins("INNER JOIN lobby_slots ON lobby_slots.player_id = players.id").Where("lobby_slots.lobby_id = ? AND lobby_slots.ready = ?", lobby.ID, false).Find(&players)
	lobby.RemoveUnreadyPlayers(true)

	for _, player := range players {
		hooks.AfterLobbyLeave(lobby, player)
	}
}
Ejemplo n.º 7
0
func (Lobby) LobbyLeave(so *wsevent.Client, args struct {
	Id *uint `json:"id"`
}) interface{} {

	steamId := so.Token.Claims.(*chelpers.TF2StadiumClaims).SteamID

	lob, player, tperr := removePlayerFromLobby(*args.Id, steamId)
	if tperr != nil {
		return tperr
	}

	hooks.AfterLobbyLeave(lob, player, false, false)

	return emptySuccess
}
Ejemplo n.º 8
0
func (Lobby) LobbyLeave(so *wsevent.Client, args struct {
	Id *uint `json:"id"`
}) interface{} {

	steamId := chelpers.GetSteamId(so.ID)

	lob, player, tperr := removePlayerFromLobby(*args.Id, steamId)
	if tperr != nil {
		return tperr
	}

	hooks.AfterLobbyLeave(lob, player)

	return chelpers.EmptySuccessJS
}
Ejemplo n.º 9
0
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{} {

	p := chelpers.GetPlayer(so.Token)
	if banned, until := p.IsBannedWithTime(player.BanJoin); banned {
		ban, _ := p.GetActiveBan(player.BanJoin)
		return fmt.Errorf("You have been banned from joining lobbies till %s (%s)", until.Format(time.RFC822), ban.Reason)
	}

	//logrus.Debug("id %d class %s team %s", *args.Id, *args.Class, *args.Team)
	lob, tperr := lobby.GetLobbyByID(*args.Id)

	if tperr != nil {
		return tperr
	}

	if lob.Mumble {
		if banned, until := p.IsBannedWithTime(player.BanJoinMumble); banned {
			ban, _ := p.GetActiveBan(player.BanJoinMumble)
			return fmt.Errorf("You have been banned from joining Mumble lobbies till %s (%s)", until.Format(time.RFC822), ban.Reason)
		}
	}

	if lob.State == lobby.Ended {
		return errors.New("Cannot join a closed lobby.")

	}
	if lob.State == lobby.Initializing {
		return errors.New("Lobby is being setup right now.")
	}

	if lob.RegionLock {
		region, _ := helpers.GetRegion(chelpers.GetIPAddr(so.Request))
		if region != lob.RegionCode {
			return errors.New("This lobby is region locked.")
		}
	}

	//Check if player is in the same lobby
	var sameLobby bool
	if id, err := p.GetLobbyID(false); err == nil && id == *args.Id {
		sameLobby = true
	}

	slot, tperr := format.GetSlot(lob.Type, *args.Team, *args.Class)
	if tperr != nil {
		return tperr
	}

	if prevId, _ := p.GetLobbyID(false); prevId != 0 && !sameLobby {
		lob, _ := lobby.GetLobbyByID(prevId)
		hooks.AfterLobbyLeave(lob, p, false, false)
	}

	tperr = lob.AddPlayer(p, slot, *args.Password)

	if tperr != nil {
		return tperr
	}

	if !sameLobby {
		hooks.AfterLobbyJoin(so, lob, p)
	}

	playersCnt := lob.GetPlayerNumber()
	lastNotif, timerExists := lobbyJoinLastNotif[lob.ID]
	if playersCnt >= notifThreshold[lob.Type] && !lob.IsEnoughPlayers(playersCnt) && (!timerExists || time.Since(lastNotif).Minutes() > 5) {
		lob.DiscordNotif(fmt.Sprintf("Almost ready [%d/%d]", playersCnt, lob.RequiredPlayers()))
		lobbyJoinLastNotif[lob.ID] = time.Now()
	}

	//check if lobby isn't already in progress (which happens when the player is subbing)
	lob.Lock()
	if lob.IsEnoughPlayers(playersCnt) && lob.State != lobby.InProgress && lob.State != lobby.ReadyingUp {
		lob.State = lobby.ReadyingUp
		lob.ReadyUpTimestamp = time.Now().Unix() + 30
		lob.Save()

		helpers.GlobalWait.Add(1)
		time.AfterFunc(time.Second*30, func() {
			state := lob.CurrentState()
			//if all player's haven't readied up,
			//remove unreadied players and unready the
			//rest.
			//don't do this when:
			//  lobby.State == Waiting (someone already unreadied up, so all players have been unreadied)
			// lobby.State == InProgress (all players have readied up, so the lobby has started)
			// lobby.State == Ended (the lobby has been closed)
			if state != lobby.Waiting && state != lobby.InProgress && state != lobby.Ended {
				lob.SetState(lobby.Waiting)
				removeUnreadyPlayers(lob)
				lob.UnreadyAllPlayers()
				//get updated lobby object
				lob, _ = lobby.GetLobbyByID(lob.ID)
				lobby.BroadcastLobby(lob)
			}
			helpers.GlobalWait.Done()
		})

		room := fmt.Sprintf("%s_private",
			hooks.GetLobbyRoom(lob.ID))
		broadcaster.SendMessageToRoom(room, "lobbyReadyUp",
			struct {
				Timeout int `json:"timeout"`
			}{30})
		lobby.BroadcastLobbyList()
	}
	lob.Unlock()

	if lob.State == lobby.InProgress { //this happens when the player is a substitute
		db.DB.Preload("ServerInfo").First(lob, lob.ID)
		so.EmitJSON(helpers.NewRequest("lobbyStart", lobby.DecorateLobbyConnect(lob, p, slot)))
	}

	return emptySuccess
}
Ejemplo n.º 10
0
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
}