예제 #1
0
파일: player.go 프로젝트: gpittarelli/Helen
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
}
예제 #2
0
파일: lobby.go 프로젝트: gpittarelli/Helen
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

}
예제 #3
0
파일: player.go 프로젝트: gpittarelli/Helen
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
}
예제 #4
0
파일: lobby.go 프로젝트: gpittarelli/Helen
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)
}
예제 #5
0
파일: event.go 프로젝트: gpittarelli/Helen
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))
}
예제 #6
0
파일: event.go 프로젝트: gpittarelli/Helen
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))
}
예제 #7
0
파일: socket.go 프로젝트: gpittarelli/Helen
//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)
				}
			})
		}
	}

}
예제 #8
0
파일: lobby.go 프로젝트: gpittarelli/Helen
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
}
예제 #9
0
파일: event.go 프로젝트: gpittarelli/Helen
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)
		}
	})
}
예제 #10
0
파일: server.go 프로젝트: gpittarelli/Helen
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

}
예제 #11
0
파일: lobby.go 프로젝트: gpittarelli/Helen
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
}
예제 #12
0
파일: lobby.go 프로젝트: gpittarelli/Helen
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
}
예제 #13
0
파일: lobby.go 프로젝트: gpittarelli/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{} {

	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
}