示例#1
0
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
}
示例#2
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
}
示例#3
0
文件: lobby.go 项目: TF2Stadium/Helen
func (Lobby) LobbySetTeamName(so *wsevent.Client, args struct {
	Id      uint   `json:"id"`
	Team    string `json:"team"`
	NewName string `json:"name"`
}) interface{} {
	player := chelpers.GetPlayer(so.Token)

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

	if player.SteamID != lob.CreatedBySteamID && (player.Role != helpers.RoleAdmin && player.Role != helpers.RoleMod) {
		return errors.New("You aren't authorized to do this.")
	}

	if len(args.NewName) == 0 || len(args.NewName) > 12 {
		return errors.New("team name must be between 1-12 characters long.")
	}

	if args.Team == "red" {
		lob.RedTeamName = args.NewName
	} else if args.Team == "blu" {
		lob.BluTeamName = args.NewName
	} else {
		return errors.New("team must be red or blu.")
	}

	lob.Save()
	lobby.BroadcastLobby(lob)
	return emptySuccess
}
示例#4
0
文件: lobby.go 项目: TF2Stadium/Helen
func (Lobby) LobbyChangeOwner(so *wsevent.Client, args struct {
	ID      *uint   `json:"id"`
	SteamID *string `json:"steamid"`
}) interface{} {
	lob, err := lobby.GetLobbyByID(*args.ID)
	if err != nil {
		return err
	}

	// current owner
	player1 := chelpers.GetPlayer(so.Token)
	if lob.CreatedBySteamID != player1.SteamID {
		return errors.New("You aren't authorized to change lobby owner.")
	}

	// to be owner
	player2, err := player.GetPlayerBySteamID(*args.SteamID)
	if err != nil {
		return err
	}

	lob.CreatedBySteamID = player2.SteamID
	lob.Save()
	lobby.BroadcastLobby(lob)
	lobby.BroadcastLobbyList()
	chat.NewBotMessage(fmt.Sprintf("Lobby leader changed to %s", player2.Alias()), int(*args.ID)).Send()

	return emptySuccess
}
示例#5
0
文件: lobby.go 项目: TF2Stadium/Helen
func (Lobby) LobbySetRequirement(so *wsevent.Client, args struct {
	ID *uint `json:"id"` // lobby ID

	Slot     *int         `json:"slot"` // -1 if to set for all slots
	Type     *string      `json:"type"`
	Value    *json.Number `json:"value"`
	Password *string      `json:"password" empty:"-"`
}) interface{} {

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

	player := chelpers.GetPlayer(so.Token)
	if lob.CreatedBySteamID != player.SteamID {
		return errors.New("Only lobby owners can change requirements.")
	}

	if !(*args.Slot >= 0 && *args.Slot < 2*format.NumberOfClassesMap[lob.Type]) {
		return errors.New("Invalid slot.")
	}

	req, err := lob.GetSlotRequirement(*args.Slot)
	if err != nil { //requirement doesn't exist. create one
		req.Slot = *args.Slot
		req.LobbyID = *args.ID
	}

	var n int64
	var f float64

	switch *args.Type {
	case "hours":
		n, err = args.Value.Int64()
		req.Hours = int(n)
	case "lobbies":
		n, err = args.Value.Int64()
		req.Lobbies = int(n)
	case "reliability":
		f, err = args.Value.Float64()
		req.Reliability = f
	case "password":
		req.Password = *args.Password
	default:
		return errors.New("Invalid requirement type.")
	}

	if err != nil {
		return errors.New("Invalid requirement.")
	}

	req.Save()
	lobby.BroadcastLobby(lob)
	lobby.BroadcastLobbyList()

	return emptySuccess
}
示例#6
0
文件: lobby.go 项目: TF2Stadium/Helen
func (Lobby) LobbyRemoveSteamRestriction(so *wsevent.Client, args struct {
	ID uint `json:"id"`
}) interface{} {
	player := chelpers.GetPlayer(so.Token)

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

	if player.SteamID != lob.CreatedBySteamID && (player.Role != helpers.RoleAdmin && player.Role != helpers.RoleMod) {
		return errors.New("You aren't authorized to do this.")
	}

	lob.PlayerWhitelist = ""
	lob.Save()

	lobby.BroadcastLobby(lob)
	lobby.BroadcastLobbyList()

	return emptySuccess
}
示例#7
0
文件: lobby.go 项目: TF2Stadium/Helen
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
}