Пример #1
0
func (s *Server) PlayerGlobalMessage(data TF2RconWrapper.PlayerData, text string) {
	switch {
	case strings.HasPrefix(text, "!rep"):
		s.report(data)
	case strings.HasPrefix(text, "!sub"):
		if rFirstSubArg.FindStringSubmatch(text) != nil {
			// If they tried to use !sub with an argument, they
			// probably meant to !rep
			s.rcon.Say("!sub is for replacing yourself, !rep reports others.")
		} else {
			commID, _ := steamid.SteamIdToCommId(data.SteamId)

			publishEvent(Event{
				Name:    PlayerSubstituted,
				LobbyID: s.LobbyId,
				SteamID: commID,
				Self:    true})

			say := fmt.Sprintf("Reporting player %s (%s)",
				data.Username, data.SteamId)
			s.rcon.Say(say)
		}
	case strings.HasPrefix(text, "!soapoff"):
		ExecFile("soap_off.cfg", s.rcon)
	case strings.HasPrefix(text, "!help"):
		s.rcon.Say(`Use !rep for reporting, !sub for substituting yourself.`)
	case strings.HasPrefix(text, "!kick"):

	}
}
Пример #2
0
func (s *Server) PlayerDisconnected(data TF2RconWrapper.PlayerData) {
	commID, _ := steamid.SteamIdToCommId(data.SteamId)
	allowed, _ := database.IsAllowed(s.LobbyId, commID)
	if allowed {
		publishEvent(Event{
			Name:    PlayerDisconnected,
			LobbyID: s.LobbyId,
			SteamID: commID})
	}
}
Пример #3
0
func (s *Server) LogListener() {
	//Steam IDs used in Source logs are of the form [C:U:A]
	//We convert these into a 64-bit Steam Community ID, which
	//is what Helen uses (and is sent in RPC calls)
	for {
		message := <-s.ServerListener.Messages

		switch message.Parsed.Type {
		case TF2RconWrapper.WorldGameOver:
			PushEvent(EventMatchEnded, s.LobbyId)
			close(s.StopVerifier)
			return
		case TF2RconWrapper.PlayerGlobalMessage:
			text := message.Parsed.Data.Text
			if strings.HasPrefix(text, "!rep") {
				s.report(message.Parsed.Data)
			} else if strings.HasPrefix(text, "!sub") {
				commID, _ := steamid.SteamIdToCommId(message.Parsed.Data.SteamId)
				PushEvent(EventSubstitute, s.LobbyId, commID)
				say := fmt.Sprintf("Reporting player %s (%s)",
					message.Parsed.Data.Username, message.Parsed.Data.SteamId)
				s.Rcon.Say(say)
			}
		case TF2RconWrapper.WorldPlayerConnected:
			commID, _ := steamid.SteamIdToCommId(message.Parsed.Data.SteamId)
			if s.IsPlayerAllowed(commID) {
				PushEvent(EventPlayerConnected, s.LobbyId, commID)
			} else {
				s.Rcon.KickPlayerID(message.Parsed.Data.UserId,
					"[tf2stadium.com] You're not in the lobby...")
			}
		case TF2RconWrapper.WorldPlayerDisconnected:
			commID, _ := steamid.SteamIdToCommId(message.Parsed.Data.SteamId)
			if s.IsPlayerAllowed(commID) {
				PushEvent(EventPlayerConnected, s.LobbyId, commID)
			}
		}

	}
}
Пример #4
0
// check if the given commId is in the server
func (s *Server) IsPlayerInServer(playerCommId string) (bool, error) {
	for i := range s.Players {
		commId, idErr := steamid.SteamIdToCommId(s.Players[i].SteamID)

		if idErr != nil {
			return false, idErr
		}

		if playerCommId == commId {
			return true, nil
		}
	}

	return false, nil
}
Пример #5
0
func (lobby *Lobby) UpdateHours(logsID int) error {
	db.DB.Model(&Lobby{}).Where("id = ?", lobby.ID).UpdateColumn("logstf_id", logsID)

	logs, err := logstf.GetLogs(logsID)
	if err != nil {
		return err
	}

	for steamID, playerStats := range logs.Players {
		commid, _ := steamid.SteamIdToCommId(steamID)
		player, err := player.GetPlayerWithStats(commid)
		if err != nil {
			logrus.Error("Couldn't find player with SteamID ", commid)
			continue
		}

		for _, class := range playerStats.ClassStats {
			totalTime := time.Second * time.Duration(class.TotalTime)

			switch class.Type {
			case "scout":
				player.Stats.ScoutHours += totalTime
			case "soldier":
				player.Stats.SoldierHours += totalTime
			case "demoman":
				player.Stats.DemoHours += totalTime
			case "heavyweapons":
				player.Stats.HeavyHours += totalTime
			case "pyro":
				player.Stats.PyroHours += totalTime
			case "engineer":
				player.Stats.EngineerHours += totalTime
			case "spy":
				player.Stats.SpyHours += totalTime
			case "sniper":
				player.Stats.SniperHours += totalTime
			case "medic":
				player.Stats.MedicHours += totalTime
			}
		}

		player.Stats.Save()
	}

	return nil
}
Пример #6
0
// check if the given commId is in the server
func (s *Server) IsPlayerInServer(playerCommId string) (bool, error) {
	s.Players.RLock()
	defer s.Players.RUnlock()

	for _, player := range s.Players.Slice {
		commId, idErr := steamid.SteamIdToCommId(player.SteamID)

		if idErr != nil {
			return false, idErr
		}

		if playerCommId == commId {
			return true, nil
		}
	}

	return false, nil
}
Пример #7
0
func (s *Server) PlayerConnected(data TF2RconWrapper.PlayerData) {
	commID, _ := steamid.SteamIdToCommId(data.SteamId)
	allowed, reason := database.IsAllowed(s.LobbyId, commID)
	if allowed {
		publishEvent(Event{
			Name:    PlayerConnected,
			LobbyID: s.LobbyId,
			SteamID: commID,
		})

		atomic.AddInt32(s.curplayers, 1)
		if int(atomic.LoadInt32(s.curplayers)) == 2*format.NumberOfClassesMap[s.Type] {
			ExecFile("soap_off.cfg", s.rcon)
		}
	} else {
		s.rcon.KickPlayerID(data.UserId, "[tf2stadium.com] "+reason)
	}
}
Пример #8
0
func playersList(players []TF2RconWrapper.Player) {
	for _, player := range players {
		commid, _ := steamid.SteamIdToCommId(player.SteamID)
		player, err := playerpackage.GetPlayerBySteamID(commid)
		if err != nil {
			continue
		}

		id, _ := player.GetLobbyID(false)
		if id == 0 {
			continue
		}

		lobby, _ := lobbypackage.GetLobbyByID(id)
		if !lobby.IsPlayerInGame(player) {
			lobby.SetInGame(player)
		}
	}
}
Пример #9
0
// runs each 10 sec
func (s *Server) Verify() {
	if config.Constants.ServerMockUp || s.Rcon == nil {
		return
	}
	helpers.Logger.Debug("[Server.Verify]: Verifing server -> [" + s.Info.Host + "] from lobby [" + fmt.Sprint(s.LobbyId) + "]")

	// check if all players in server are in lobby
	var err error
	s.Players, err = s.Rcon.GetPlayers()

	for err != nil {
		time.Sleep(time.Second)
		helpers.Logger.Warning("Failed to get players in server %s: %s", s.LobbyId, err.Error())
		s.Players, err = s.Rcon.GetPlayers()
	}

	for i := range s.Players {
		if s.Players[i].SteamID != "BOT" {
			commId, idErr := steamid.SteamIdToCommId(s.Players[i].SteamID)

			if idErr != nil {
				helpers.Logger.Debug("[Server.Verify]: ERROR -> %s", idErr)
			}

			isPlayerAllowed := s.IsPlayerAllowed(commId)

			if isPlayerAllowed == false {
				helpers.Logger.Debug("[Server.Verify]: Kicking player not allowed -> Username [" +
					s.Players[i].Username + "] CommID [" + commId + "] SteamID [" + s.Players[i].SteamID + "] ")

				kickErr := s.Rcon.KickPlayer(s.Players[i], "[tf2stadium.com]: You're not in this lobby...")

				if kickErr != nil {
					helpers.Logger.Debug("[Server.Verify]: ERROR -> %s", kickErr)
				}
			}
		}
	}
}
Пример #10
0
func (s *Server) report(data TF2RconWrapper.PlayerData) {
	var team string

	matches := rReport.FindStringSubmatch(data.Text)
	if len(matches) != 3 {
		s.rcon.Say("Usage: !rep our/their/red/blu " + slot(s.Type))
		return
	}

	argTeam := strings.ToLower(matches[1])
	argSlot := strings.ToLower(matches[2])

	source, _ := steamid.SteamIdToCommId(data.SteamId)

	team = database.GetTeam(s.LobbyId, s.Type, source)
	//	helpers.Logger.Debug(team)

	switch argTeam {
	case "their":
		if team == "red" {
			team = "blu"
		} else {
			team = "red"
		}
	case "our":
		// team = team
	case "blu", "red":
		team = argTeam
	case "blue":
		team = "blu"
	default:
		s.rcon.Say("Usage: !rep our/their/red/blu slotname")
		return
	}

	target, err := database.GetSteamIDFromSlot(team, argSlot, s.LobbyId, s.Type)
	if err != nil {
		var slots string

		s.rcon.Say("!rep: valid slots - " + slots)
		return
	}

	if database.IsReported(s.LobbyId, target) {
		s.rcon.Say("!rep: Player has already been reported")
		return
	}

	if target == source {
		// !rep'ing themselves
		publishEvent(Event{
			Name:    PlayerSubstituted,
			LobbyID: s.LobbyId,
			SteamID: source,
			Self:    true})

		say := fmt.Sprintf("Reporting player %s (%s)", data.Username, data.SteamId)
		s.rcon.Say(say)
		return
	}

	err = newReport(source, target, s.LobbyId)

	if err != nil {
		if _, ok := err.(*repError); ok {
			s.rcon.Say("!rep: You have already voted.")
		} else {
			s.rcon.Say(err.Error())
			helpers.Logger.Errorf("#%d: %v", s.LobbyId, err)
		}
		return
	}

	curReps := countReports(target, s.LobbyId)
	name := database.GetNameFromSteamID(target)

	switch curReps {
	case repsNeeded[s.Type]:
		//Got needed number of reports, ask helen to substitute player
		publishEvent(Event{
			Name:    PlayerSubstituted,
			SteamID: target,
			LobbyID: s.LobbyId})

		// tell timeout goroutine to stop (It is possible that the map
		// entry will not exist if only 1 report is needed (such as debug
		// lobbies))
		s.mapMu.RLock()
		timer, ok := s.repTimer[team+argSlot]
		s.mapMu.RUnlock()

		if ok && timer.Stop() {
			s.mapMu.Lock()
			delete(s.repTimer, team+argSlot)
			s.mapMu.Unlock()

		}

		say := fmt.Sprintf("Reporting %s %s: %s", strings.ToUpper(team), strings.ToUpper(argSlot), name)
		s.rcon.Say(say)

	case 1:
		//first report happened, reset reps two minute later to 0, unless told to stop
		timer := time.AfterFunc(2*time.Minute, func() {
			ResetReportCount(target, s.LobbyId)
			say := fmt.Sprintf("Reporting %s %s failed, couldn't get enough votes in 2 minutes.", strings.ToUpper(team), strings.ToUpper(argSlot))
			s.rcon.Say(say)

		})

		s.mapMu.Lock()
		s.repTimer[team+argSlot] = timer
		s.mapMu.Unlock()
	}
	say := fmt.Sprintf("Got %d votes for reporting %s (%d needed)", curReps, name, repsNeeded[s.Type])
	s.rcon.Say(say)

	return
}