/// <summary> /// Create a practice or tournament or custom lobby. /// </summary> /// <param name="pass_key">Password for the lobby.</param> /// <param name="details">Lobby options.</param> /// <param name="tournament_game">Is this a tournament game?</param> /// <param name="tournament">Tournament ID</param> /// <param name="tournament_game_id">Tournament game ID</param> public void CreateLobby(string pass_key, CMsgPracticeLobbySetDetails details, bool tournament_game = false, uint tournament = 0, uint tournament_game_id = 0) { var create = new ClientGCMsgProtobuf <CMsgPracticeLobbyCreate>((uint)EDOTAGCMsg.k_EMsgGCPracticeLobbyCreate); create.Body.pass_key = pass_key; create.Body.tournament_game_id = tournament_game_id; create.Body.tournament_game = tournament_game; create.Body.tournament_id = tournament; create.Body.lobby_details = details; create.Body.lobby_details.pass_key = pass_key; Send(create, 570); }
/// <summary> /// Create a practice or tournament or custom lobby. /// </summary> /// <param name="passKey">Password for the lobby.</param> /// <param name="details">Lobby options.</param> public void CreateLobby(string passKey, CMsgPracticeLobbySetDetails details) { var create = new ClientGCMsgProtobuf <CMsgPracticeLobbyCreate>((uint)EDOTAGCMsg.k_EMsgGCPracticeLobbyCreate); create.Body.pass_key = passKey; create.Body.lobby_details = details; create.Body.lobby_details.pass_key = passKey; create.Body.lobby_details.visibility = DOTALobbyVisibility.DOTALobbyVisibility_Public; if (string.IsNullOrWhiteSpace(create.Body.search_key)) { create.Body.search_key = ""; } Send(create); }
// this happens after telling steam that we launched dota (with the ClientGamesPlayed message) // this can also happen after the GC has restarted (due to a crash or new version) void OnClientWelcome(IPacketGCMsg packetMsg) { // in order to get at the contents of the message, we need to create a ClientGCMsgProtobuf from the packet message we recieve // note here the difference between ClientGCMsgProtobuf and the ClientMsgProtobuf used when sending ClientGamesPlayed // this message is used for the GC, while the other is used for general steam messages var msg = new ClientGCMsgProtobuf <CMsgClientWelcome>(packetMsg); Console.WriteLine("GC is welcoming us. Version: {0}", msg.Body.version); // at this point, the GC is now ready to accept messages from us // so now we'll request the details of the match we're looking for CMsgPracticeLobbySetDetails details = new CMsgPracticeLobbySetDetails(); details.game_name = "LOBBY"; details.pass_key = "bscal"; details.game_mode = (uint)DOTA_GameMode.DOTA_GAMEMODE_AP; // game mode details.server_region = (uint)ERegionCode.USEast; details.dota_tv_delay = LobbyDotaTVDelay.LobbyDotaTV_300; details.game_version = DOTAGameVersion.GAME_VERSION_CURRENT; details.visibility = DOTALobbyVisibility.DOTALobbyVisibility_Public; CreateLobby("bscal", details); }
/// <summary> /// Creates a custom lobby and waits for the specified DotaLobbyParams to be met. /// Starts the match. /// Waits for the match to complete. /// </summary> /// <param name="LobbyName">Name of lobby</param> /// <param name="LobbyPassword">Lobby Password</param> /// <param name="parameters">Lobby Start Parameters</param> public void CreateLobby(string LobbyName, string LobbyPassword, DotaLobbyParams parameters) { if (dota.Lobby != null) { UpdateStatus(DotaClientStatus.Warning, "Lobby: Creating a lobby when already in one."); } CMsgPracticeLobbySetDetails details = new CMsgPracticeLobbySetDetails(); details.game_name = LobbyName; details.pass_key = LobbyPassword; details.game_mode = (uint)DOTA_GameMode.DOTA_GAMEMODE_AP; // game mode details.server_region = (uint)ERegionCode.USEast; details.dota_tv_delay = LobbyDotaTVDelay.LobbyDotaTV_300; details.game_version = DOTAGameVersion.GAME_VERSION_CURRENT; details.visibility = DOTALobbyVisibility.DOTALobbyVisibility_Public; dota.CreateLobby(LobbyPassword, details); // wait for lobby to be created while (dota.Lobby == null) { Thread.Sleep(10); } UpdateStatus(DotaClientStatus.Normal, "Lobby: Lobby Created."); UpdateStatus(DotaClientStatus.Normal, "Lobby: Lobby Name: " + LobbyName); UpdateStatus(DotaClientStatus.Normal, "Lobby: Lobby Password: "******"Lobby: Lobby ID: " + dota.Lobby.lobby_id.ToString()); Thread.Sleep(1000); dota.JoinTeam(DOTA_GC_TEAM.DOTA_GC_TEAM_PLAYER_POOL); // move bot to unassigned UpdateStatus(DotaClientStatus.Normal, "Lobby: Moved bot to player pool."); if (OnLobbyCreated != null) { OnLobbyCreated(dota.Lobby.lobby_id); } UpdateStatus(DotaClientStatus.Normal, "Lobby: Waiting for players to connect...."); List <DateTime> NotificationTimeouts = new List <DateTime>(); NotificationTimeouts.Add(DateTime.Now.AddMinutes(1)); NotificationTimeouts.Add(NotificationTimeouts.Last().AddMinutes(1)); NotificationTimeouts.Add(NotificationTimeouts.Last().AddMinutes(1)); NotificationTimeouts.Add(NotificationTimeouts.Last().AddMinutes(1)); NotificationTimeouts.Add(NotificationTimeouts.Last().AddMinutes(1)); NotificationTimeouts.Reverse(); while (true) { List <CDOTALobbyMember> members = dota.Lobby.members; int count = 0; foreach (CDOTALobbyMember member in members) { if (parameters.isReadyPlayer(member)) { count++; } } if (parameters.hasAllPlayers(count)) { break; } Thread.Sleep(1000); if (NotificationTimeouts.Count == 0) { continue; //TODO: cancel the match and reset bot } if (DateTime.Now > NotificationTimeouts[0]) { dota.SendChannelMessage(dota.Lobby.lobby_id, "Players have " + NotificationTimeouts.Count.ToString() + " minute" + (NotificationTimeouts.Count == 1 ? "" : "s") + " to join the lobby."); NotificationTimeouts.RemoveAt(0); } } UpdateStatus(DotaClientStatus.Normal, "Lobby: Starting Lobby."); dota.LaunchLobby(); UpdateStatus(DotaClientStatus.Normal, "Match: Waiting for MatchID."); while (dota.Lobby.match_id == 0) { Thread.Sleep(10); } MatchID = dota.Lobby.match_id; if (OnGameStarted != null) { OnGameStarted(MatchID); } EMatchOutcome outcome = WaitForMatchEnd(); UpdateStatus(DotaClientStatus.Normal, "Match: Result: " + Enum.GetName(typeof(EMatchOutcome), dota.Lobby.match_outcome)); //publish game result if (OnGameFinished != null) { DotaGameResult result = DotaGameResult.Unknown; if (outcome == EMatchOutcome.k_EMatchOutcome_RadVictory) { result = DotaGameResult.Radiant; } else if (outcome == EMatchOutcome.k_EMatchOutcome_DireVictory) { result = DotaGameResult.Dire; } OnGameFinished(result); } }
void SendCreateLobby(bool reWait = false) { string pass_key = loginInfo.pass_key; ulong custom_game_mode = loginInfo.custom_game_mode; string custom_map_name = loginInfo.custom_map_name; string game_name = loginInfo.game_name; uint custom_min_players = loginInfo.custom_min_players; uint custom_max_players = loginInfo.custom_max_players; uint game_mode = loginInfo.game_mode; uint server_region = loginInfo.server_region; uint customGameTimestamp = (uint)(new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds()); uint teams = 1; //ulong custom_game_crc = 1; ??? var details = new CMsgPracticeLobbySetDetails { server_region = server_region, game_mode = game_mode, allow_spectating = true, cm_pick = DOTA_CM_PICK.DOTA_CM_RANDOM, bot_difficulty_radiant = DOTABotDifficulty.BOT_DIFFICULTY_HARD, bot_difficulty_dire = DOTABotDifficulty.BOT_DIFFICULTY_HARD, game_version = DOTAGameVersion.GAME_VERSION_STABLE, dota_tv_delay = LobbyDotaTVDelay.LobbyDotaTV_120, lan = false, pass_key = pass_key, custom_game_mode = custom_game_mode.ToString(), custom_map_name = custom_map_name, custom_game_id = custom_game_mode, custom_min_players = custom_min_players, custom_max_players = custom_max_players, //lan_host_ping_to_server_region = 12, visibility = DOTALobbyVisibility.DOTALobbyVisibility_Public, //custom_game_crc = custom_game_crc, custom_game_timestamp = customGameTimestamp, // 2020-06-19 14:35:17 未定义 //league_selection_priority_choice = SelectionPriorityType.UNDEFINED, //league_non_selection_priority_choice = SelectionPriorityType.UNDEFINED, pause_setting = LobbyDotaPauseSetting.LobbyDotaPauseSetting_Limited, allchat = false, allow_cheats = false, custom_difficulty = 0, dire_series_wins = 0, fill_with_bots = false, game_name = game_name, intro_mode = false, leagueid = 0, // 2020-06-19 14:35:33 未定义 //league_game_id = 0, //league_selection_priority_team = 0, //league_series_id = 0, load_game_id = 0, lobby_id = 0, penalty_level_dire = 0, penalty_level_radiant = 0, previous_match_override = 0, radiant_series_wins = 0, series_type = 0, bot_radiant = 0, bot_dire = 0, }; for (var i = 0; i < teams; i++) { details.team_details.Add(new CLobbyTeamDetails() { team_name = "", team_tag = "", guild_name = "", guild_tag = "", guild_banner_logo = 0, guild_base_logo = 0, guild_id = 0, guild_logo = 0, is_home_team = false, rank = 0, rank_change = 0, team_banner_logo = 0, team_base_logo = 0, team_complete = false, team_id = 0, team_logo = 0 }); } var lobbyCreate = new ClientGCMsgProtobuf <CMsgPracticeLobbyCreate>((uint)EDOTAGCMsg.k_EMsgGCPracticeLobbyCreate); lobbyCreate.Body.pass_key = pass_key; lobbyCreate.Body.search_key = ""; lobbyCreate.Body.lobby_details = details; lobbyCreate.Body.lobby_details.pass_key = pass_key; lobbyCreate.Body.lobby_details.visibility = DOTALobbyVisibility.DOTALobbyVisibility_Public; gameCoordinator.Send(lobbyCreate, APPID); waitTime = 1; checkTime = 5; checkCreateLobby = true; if (reWait) { Console.WriteLine("Resend create lobby."); Wait(); } else { Console.WriteLine("send create lobby."); } }