From c7fd3b63cca7e6e6a03164ceda2419f4641b8a93 Mon Sep 17 00:00:00 2001 From: abrunasso Date: Mon, 14 Aug 2017 12:49:54 -0700 Subject: [PATCH 01/14] Added is_powered to the protocol and its conversion. --- include/sc2api/sc2_unit.h | 2 ++ protocol | 2 +- src/sc2api/sc2_proto_to_pods.cc | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/sc2api/sc2_unit.h b/include/sc2api/sc2_unit.h index 857ccdc4..23a847c1 100644 --- a/include/sc2api/sc2_unit.h +++ b/include/sc2api/sc2_unit.h @@ -174,6 +174,8 @@ class Unit { Tag engaged_target_tag; //! Buffs on this unit. Only valid for this player's units. std::vector buffs; + //! Whether the unit is powered by a pylon. + bool is_powered; Unit(); diff --git a/protocol b/protocol index dca8b683..e34651ee 160000 --- a/protocol +++ b/protocol @@ -1 +1 @@ -Subproject commit dca8b6831a84747c2cd6e0c33d6416e14838d886 +Subproject commit e34651eec90a4e17b08aa44d7c470cdcb954b22a diff --git a/src/sc2api/sc2_proto_to_pods.cc b/src/sc2api/sc2_proto_to_pods.cc index cfe2f5bd..e99b0bf4 100644 --- a/src/sc2api/sc2_proto_to_pods.cc +++ b/src/sc2api/sc2_proto_to_pods.cc @@ -252,6 +252,8 @@ bool Convert(const ObservationRawPtr& observation_raw, Units& units) { unit.buffs.push_back(observation_unit.buff_ids(buff_index)); } + unit.is_powered = observation_unit.is_powered(); + units.push_back(unit); } From 107d3a3d8e14fdd2a5e10f8cd151c1a1b808aff8 Mon Sep 17 00:00:00 2001 From: abrunasso Date: Tue, 15 Aug 2017 14:14:07 -0700 Subject: [PATCH 02/14] Added resource cost, upgrade time and ability id to UpgradeData. --- include/sc2api/sc2_data.h | 3 +++ protocol | 2 +- src/sc2api/sc2_data.cc | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/sc2api/sc2_data.h b/include/sc2api/sc2_data.h index adcb0e71..a5d2148c 100644 --- a/include/sc2api/sc2_data.h +++ b/include/sc2api/sc2_data.h @@ -189,6 +189,9 @@ typedef std::vector UnitTypes; struct UpgradeData { uint32_t upgrade_id; // Stable ID. std::string name; // Catalog name of the upgrade. + uint32_t mineral_cost; + uint32_t vespene_cost; + AbilityID ability_id; UpgradeData(); diff --git a/protocol b/protocol index e34651ee..db0c0792 160000 --- a/protocol +++ b/protocol @@ -1 +1 @@ -Subproject commit e34651eec90a4e17b08aa44d7c470cdcb954b22a +Subproject commit db0c0792ccaf7d42cf41d9e217c06ea185ce2fae diff --git a/src/sc2api/sc2_data.cc b/src/sc2api/sc2_data.cc index 0cd09637..6a34fb14 100644 --- a/src/sc2api/sc2_data.cc +++ b/src/sc2api/sc2_data.cc @@ -295,6 +295,10 @@ void UpgradeData::ReadFromProto(const SC2APIProtocol::UpgradeData& upgrade_data) // name_ name = upgrade_data.name(); + + mineral_cost = upgrade_data.mineral_cost(); + vespene_cost = upgrade_data.vespene_cost(); + ability_id = upgrade_data.ability_id(); } std::string UpgradeData::Log() const { From 3c8fd93a0532cb7cb4964318e38393b9dcdffbc5 Mon Sep 17 00:00:00 2001 From: "BLIZZARD\\kcalderone" Date: Tue, 15 Aug 2017 17:10:11 -0700 Subject: [PATCH 03/14] Updating protocol submodule. --- protocol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol b/protocol index db0c0792..e3772283 160000 --- a/protocol +++ b/protocol @@ -1 +1 @@ -Subproject commit db0c0792ccaf7d42cf41d9e217c06ea185ce2fae +Subproject commit e3772283e56491854c672f7396873a39a005f912 From 3e8ab1ab6a590bb3161e2dbfffbb524cd05155c2 Mon Sep 17 00:00:00 2001 From: "BLIZZARD\\kcalderone" Date: Wed, 16 Aug 2017 11:03:56 -0700 Subject: [PATCH 04/14] Fixed bug where update loop would exit if replay observer relaunched. Move relaunch to separate function. --- src/sc2api/sc2_coordinator.cc | 63 ++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/src/sc2api/sc2_coordinator.cc b/src/sc2api/sc2_coordinator.cc index f471ce2e..bc57ef3a 100644 --- a/src/sc2api/sc2_coordinator.cc +++ b/src/sc2api/sc2_coordinator.cc @@ -187,6 +187,8 @@ class CoordinatorImp { bool WaitForAllResponses(); void AddAgent(Agent* agent); + bool Relaunch(ReplayObserver* replay_observer); + int window_width_ = 1024; int window_height_ = 768; @@ -528,6 +530,36 @@ bool CoordinatorImp::StartGame() { return true; } +bool CoordinatorImp::Relaunch(ReplayObserver* replay_observer) { + ControlInterface* control = replay_observer->Control(); + const ProcessInfo& pi = control->GetProcessInfo(); + + // Try to kill SC2 then relaunch it + sc2::TerminateProcess(pi.process_id); + + // Reset the control interface so internal state gets reset. + replay_observer->Reset(); + + // ReplayObserver needs the control interface from Client. + replay_observer->SetControl(replay_observer->Control()); + + // Control interface has been reconstructed. + control = replay_observer->Control(); + + last_port_ = LaunchProcess(process_settings_, + replay_observer, + window_width_, + window_height_, + window_start_x_, + window_start_y_, + last_port_ + 1 + ); + + const ProcessInfo& pi_new = control->GetProcessInfo(); + + return control->Connect(process_settings_.net_address, pi_new.port, process_settings_.timeout_ms); +} + // Coordinator. Coordinator::Coordinator() { @@ -652,6 +684,7 @@ bool Coordinator::Update() { } } + bool relaunched = false; for (auto replay_observer : imp_->replay_observers_) { ControlInterface* control = replay_observer->Control(); const std::vector& client_errors = control->GetClientErrors(); @@ -659,35 +692,11 @@ bool Coordinator::Update() { replay_observer->OnError(client_errors, control->GetProtocolErrors()); error_occurred = true; if (imp_->replay_recovery_) { - const ProcessInfo& pi = control->GetProcessInfo(); - - // Try to kill SC2 then relaunch it - sc2::TerminateProcess(pi.process_id); - - // Reset the control interface so internal state gets reset. - replay_observer->Reset(); - - // ReplayObserver needs the control interface from Client. - replay_observer->SetControl(replay_observer->Control()); - - // Control interface has been reconstructed. - control = replay_observer->Control(); - - imp_->last_port_ = LaunchProcess(imp_->process_settings_, - replay_observer, - imp_->window_width_, - imp_->window_height_, - imp_->window_start_x_, - imp_->window_start_y_, - imp_->last_port_ + 1); - - const ProcessInfo& pi_new = control->GetProcessInfo(); - - bool connected = control->Connect(imp_->process_settings_.net_address, pi_new.port, imp_->process_settings_.timeout_ms); - // An error did occur but if we succesfully recovered ignore it. The client will still gets its event + bool connected = imp_->Relaunch(replay_observer); if (connected) { error_occurred = false; + relaunched = true; } } } @@ -699,7 +708,7 @@ bool Coordinator::Update() { return false; } - return !AllGamesEnded(); + return !AllGamesEnded() || relaunched; } bool Coordinator::AllGamesEnded() const { From 3f8632b7d63635cfd5f385cd47bbb16eb4667adf Mon Sep 17 00:00:00 2001 From: "BLIZZARD\\kcalderone" Date: Wed, 16 Aug 2017 14:26:37 -0700 Subject: [PATCH 05/14] Old version replay support. Coordinator will now download/relaunch into the correct game version. --- include/sc2api/sc2_client.h | 1 + include/sc2api/sc2_control_interfaces.h | 2 +- include/sc2api/sc2_game_settings.h | 1 + include/sc2api/sc2_gametypes.h | 1 + include/sc2api/sc2_proto_interface.h | 6 ++ include/sc2utils/sc2_manage_process.h | 3 + src/sc2api/sc2_args.cc | 42 ------------- src/sc2api/sc2_coordinator.cc | 79 ++++++++++++++++--------- src/sc2api/sc2_proto_interface.cc | 10 +++- src/sc2api/sc2_replay_observer.cc | 7 ++- src/sc2utils/sc2_manage_process.cc | 65 ++++++++++++++++++++ 11 files changed, 140 insertions(+), 77 deletions(-) diff --git a/include/sc2api/sc2_client.h b/include/sc2api/sc2_client.h index 7eb00ec1..d8f522da 100644 --- a/include/sc2api/sc2_client.h +++ b/include/sc2api/sc2_client.h @@ -37,6 +37,7 @@ enum class ClientError { SC2AppFailure, /*! SC2 has either crashed or been forcibly terminated by this library because it was not responding to requests. */ SC2ProtocolError, /*! The response from SC2 contains errors, most likely meaning the API was not used in a correct way. */ SC2ProtocolTimeout, /*! A request was made and a response was not received in the amount of time given by the timeout. */ + WrongGameVersion, /*! A replay was attempted to be loaded in the wrong game version. */ }; //! A set of common events a user can override in their derived bot or replay observer class. diff --git a/include/sc2api/sc2_control_interfaces.h b/include/sc2api/sc2_control_interfaces.h index 331fe58a..5b4ec81d 100644 --- a/include/sc2api/sc2_control_interfaces.h +++ b/include/sc2api/sc2_control_interfaces.h @@ -79,7 +79,7 @@ class ReplayControlInterface { public: virtual ~ReplayControlInterface() = default; - virtual bool GatherReplayInfo(const std::string& path) = 0; + virtual bool GatherReplayInfo(const std::string& path, bool download_data = false) = 0; virtual bool LoadReplay(const std::string& replay_path, const InterfaceSettings& settings, uint32_t player_id) = 0; virtual bool WaitForReplay() = 0; diff --git a/include/sc2api/sc2_game_settings.h b/include/sc2api/sc2_game_settings.h index 432b297e..2786cdaf 100644 --- a/include/sc2api/sc2_game_settings.h +++ b/include/sc2api/sc2_game_settings.h @@ -27,6 +27,7 @@ struct ProcessSettings { bool realtime; int step_size; std::string process_path; + std::string data_version; std::string net_address; int timeout_ms; int port_start; diff --git a/include/sc2api/sc2_gametypes.h b/include/sc2api/sc2_gametypes.h index 711717fa..41c50bb1 100644 --- a/include/sc2api/sc2_gametypes.h +++ b/include/sc2api/sc2_gametypes.h @@ -165,6 +165,7 @@ struct ReplayInfo { std::string map_path; std::string replay_path; std::string version; + std::string data_version; ReplayPlayerInfo players[max_num_players]; ReplayInfo() : diff --git a/include/sc2api/sc2_proto_interface.h b/include/sc2api/sc2_proto_interface.h index b9bf4b2e..0fd275d8 100644 --- a/include/sc2api/sc2_proto_interface.h +++ b/include/sc2api/sc2_proto_interface.h @@ -101,6 +101,9 @@ class ProtoInterface { const std::vector& GetStats() const { return count_uses_; } void SetControl(ControlInterface* control) { control_ = control; } + uint32_t GetBaseBuild() const { return base_build_; } + const std::string& GetDataVersion() const { return data_version_; } + protected: Connection connection_; std::string address_; @@ -111,6 +114,9 @@ class ProtoInterface { SC2APIProtocol::Response::ResponseCase response_pending_; std::vector count_uses_; ControlInterface* control_; + + uint32_t base_build_; + std::string data_version_; }; // Helper to produce a string for the proto type. diff --git a/include/sc2utils/sc2_manage_process.h b/include/sc2utils/sc2_manage_process.h index 12cd51b4..66c83730 100644 --- a/include/sc2utils/sc2_manage_process.h +++ b/include/sc2utils/sc2_manage_process.h @@ -18,4 +18,7 @@ std::string GetUserDirectory(); std::string GetLibraryMapsDirectory(); std::string GetGameMapsDirectory(const std::string& process_path); +bool FindLatestExe(std::string& path); +bool FindBaseExe(std::string& path, uint32_t base_build); + } diff --git a/src/sc2api/sc2_args.cc b/src/sc2api/sc2_args.cc index 70716b19..89afe403 100644 --- a/src/sc2api/sc2_args.cc +++ b/src/sc2api/sc2_args.cc @@ -3,11 +3,9 @@ #include "sc2utils/sc2_arg_parser.h" #include "sc2utils/sc2_manage_process.h" #include "sc2utils/sc2_property_reader.h" -#include "sc2utils/sc2_scan_directory.h" #include #include -#include namespace sc2 { @@ -36,46 +34,6 @@ bool ParseFromFile(ProcessSettings& process_settings, GameSettings& game_setting return true; } -bool FindLatestExe(std::string& path) { - if (path.length() < 4) - return false; - - static const char VersionsFolder[] = "Versions\\"; - static std::size_t BaseFolderNameLen = 10; // "Base00000\" - std::size_t versions_pos = path.find(VersionsFolder); - if (versions_pos == std::string::npos) { - return DoesFileExist(path); - } - - // Get the versions path. - std::string versions_path = path; - versions_path.erase(versions_path.begin() + versions_pos + sizeof(VersionsFolder) - 1, versions_path.end()); - - // Get the exe name. - std::string exe_name = path; - exe_name.erase(exe_name.begin(), exe_name.begin() + versions_pos + sizeof(VersionsFolder) + BaseFolderNameLen - 1); - - // Get a list of all subfolders. - std::vector subfolders; - scan_directory(versions_path.c_str(), subfolders, true, true); - if (subfolders.size() < 1) { - return DoesFileExist(path); - } - - // Sort the subfolders list. - std::sort(subfolders.begin(), subfolders.end()); - - for (int folder_index = static_cast(subfolders.size()) - 1; folder_index >= 0; --folder_index) { - std::string test_path = subfolders[folder_index] + "\\" + exe_name; - if (DoesFileExist(test_path)) { - path = test_path; - return true; - } - } - - return DoesFileExist(path); -} - #if defined(_WIN32) const char kDirectoryDivider = '\\'; #else diff --git a/src/sc2api/sc2_coordinator.cc b/src/sc2api/sc2_coordinator.cc index bc57ef3a..0cabf3a0 100644 --- a/src/sc2api/sc2_coordinator.cc +++ b/src/sc2api/sc2_coordinator.cc @@ -48,13 +48,8 @@ int LaunchProcess(ProcessSettings& process_settings, Client* client, int window_ // DirectX will fail if multiple games try to launch in fullscreen mode. Force them into windowed mode. cl.push_back("-displayMode"); cl.push_back("0"); - // TODO: This is deprecated. Remove this. - cl.push_back("-simulationSpeed"); - if (process_settings.realtime) { - cl.push_back("1"); - } - else { - cl.push_back("0"); + if (process_settings.data_version.size() > 0) { + cl.push_back("-dataVersion"); cl.push_back(process_settings.data_version); } for (const std::string& command : process_settings.extra_command_lines) @@ -177,6 +172,8 @@ class CoordinatorImp { bool StartGame(); void StartReplay(); + bool ShouldIgnore(ReplayObserver* r, const std::string& file); + bool ShouldRelaunch(ReplayObserver* r, const std::string& file); void StepAgents(); void StepAgentsRealtime(); @@ -222,6 +219,36 @@ bool CoordinatorImp::AnyObserverAvailable() const { }); } +bool CoordinatorImp::ShouldIgnore(ReplayObserver* r, const std::string& file) { + if (file.empty()) + return true; + + // Gather replay information with the available observer. + r->ReplayControl()->GatherReplayInfo(file, true); + + // If the replay isn't being pruned based on replay info start it. + return r->IgnoreReplay(r->ReplayControl()->GetReplayInfo(), replay_settings_.player_id); +} + +bool CoordinatorImp::ShouldRelaunch(ReplayObserver* r, const std::string& file) { + const ReplayInfo& replay_info = r->ReplayControl()->GetReplayInfo(); + + bool version_match = replay_info.base_build == r->Control()->Proto().GetBaseBuild() && + replay_info.data_version == r->Control()->Proto().GetDataVersion(); + if (version_match) + return false; + + // Version failed to download. Just continue with trying to load in current version. + // It will likely fail, and then just skip past this replay. + if (!FindBaseExe(process_settings_.process_path, replay_info.base_build)) + return false; + + std::cout << "Replay is from a different version. Relaunching client into the correct version..." << std::endl; + process_settings_.data_version = replay_info.data_version; + r->Control()->Error(ClientError::WrongGameVersion); + return true; +} + void CoordinatorImp::StartReplay() { // If no replays given in the settings don't try. if (replay_settings_.replay_file.empty()) { @@ -236,33 +263,28 @@ void CoordinatorImp::StartReplay() { // Run a replay with each available replay observer. for (auto r : replay_observers_) { - bool loaded_replay = false; - while (!loaded_replay) { - if (replay_settings_.replay_file.empty()) { - break; - } + // If the replay observer is idle or out of game use it for a new replay. + if (!r->Control()->IsReadyForCreateGame()) { + continue; + } + auto& replays = replay_settings_.replay_file; + while (replays.size() != 0) { const std::string& file = replay_settings_.replay_file.front(); - if (!file.empty()) { - // If the replay observer is idle or out of game use it for a new replay. - if (!r->Control()->IsReadyForCreateGame()) { - loaded_replay = true; - continue; - } - - // Gather replay information with the available observer. - r->ReplayControl()->GatherReplayInfo(file); + if (ShouldIgnore(r, file)) { + replays.erase(replays.begin()); + continue; + } - // If the replay isn't being pruned based on replay info start it. - if (!r->IgnoreReplay(r->ReplayControl()->GetReplayInfo(), replay_settings_.player_id)) { - loaded_replay = r->ReplayControl()->LoadReplay(file, interface_settings_, replay_settings_.player_id); - } + if (ShouldRelaunch(r, file)) { + break; } - // Front to back ordering more important than remove from back speedup. - replay_settings_.replay_file.erase( - replay_settings_.replay_file.begin(), replay_settings_.replay_file.begin() + 1); + bool launched = r->ReplayControl()->LoadReplay(file, interface_settings_, replay_settings_.player_id); + replays.erase(replays.begin()); + if (launched) + break; } } @@ -702,7 +724,6 @@ bool Coordinator::Update() { } } - // End the coordinator update on the idea that an error in the API should mean it's time to stop. if (error_occurred) { return false; diff --git a/src/sc2api/sc2_proto_interface.cc b/src/sc2api/sc2_proto_interface.cc index 1bde564e..d086f673 100644 --- a/src/sc2api/sc2_proto_interface.cc +++ b/src/sc2api/sc2_proto_interface.cc @@ -167,10 +167,14 @@ bool ProtoInterface::PingGame() { // Wait for the return of the ping. // TODO: Implement a time out here. GameResponsePtr response = WaitForResponseInternal(); - if (response.get()) { - return true; + if (!response.get() || !response->has_ping()) { + return false; } - return false; + + const auto& response_ping = response->ping(); + base_build_ = response_ping.base_build(); + data_version_ = response_ping.data_version(); + return true; } void ProtoInterface::Quit() { diff --git a/src/sc2api/sc2_replay_observer.cc b/src/sc2api/sc2_replay_observer.cc index 3aa716c3..0f9831dc 100644 --- a/src/sc2api/sc2_replay_observer.cc +++ b/src/sc2api/sc2_replay_observer.cc @@ -19,7 +19,7 @@ class ReplayControlImp : public ReplayControlInterface { ReplayControlImp(ControlInterface* control_interface, ReplayObserver* replay_observer); - virtual bool GatherReplayInfo(const std::string& path) override; + virtual bool GatherReplayInfo(const std::string& path, bool download_data) override; virtual bool LoadReplay(const std::string& replay_path, const InterfaceSettings& settings, uint32_t player_id) override; virtual bool WaitForReplay() override; @@ -31,13 +31,14 @@ ReplayControlImp::ReplayControlImp(ControlInterface* control_interface, ReplayOb replay_observer_(replay_observer) { } -bool ReplayControlImp::GatherReplayInfo(const std::string& path) { +bool ReplayControlImp::GatherReplayInfo(const std::string& path, bool download_data) { replay_info_.num_players = 0; // Request the replay info. GameRequestPtr request = control_interface_->Proto().MakeRequest(); SC2APIProtocol::RequestReplayInfo* request_replay_info = request->mutable_replay_info(); request_replay_info->set_replay_path(path); + request_replay_info->set_download_data(download_data); if (!control_interface_->Proto().SendRequest(request)) { return false; } @@ -61,6 +62,7 @@ bool ReplayControlImp::GatherReplayInfo(const std::string& path) { std::string map_name = proto_replay_info.map_name(); std::string map_path = proto_replay_info.local_map_path(); std::string version = proto_replay_info.game_version(); + std::string data_version = proto_replay_info.data_version(); if (map_name.length() >= max_path_size) { std::cerr << "Map name is too long: " << map_name << std::endl; @@ -79,6 +81,7 @@ bool ReplayControlImp::GatherReplayInfo(const std::string& path) { replay_info_.map_path = map_path.c_str(); replay_info_.replay_path = path.c_str(); replay_info_.version = version.c_str(); + replay_info_.data_version = data_version.c_str(); replay_info_.duration = proto_replay_info.game_duration_seconds(); replay_info_.duration_gameloops = proto_replay_info.game_duration_loops(); diff --git a/src/sc2utils/sc2_manage_process.cc b/src/sc2utils/sc2_manage_process.cc index cf9bf246..d7ce8661 100644 --- a/src/sc2utils/sc2_manage_process.cc +++ b/src/sc2utils/sc2_manage_process.cc @@ -1,5 +1,7 @@ #include "sc2utils/sc2_manage_process.h" +#include "sc2utils/sc2_scan_directory.h" +#include #include #include #include @@ -467,4 +469,67 @@ bool PollKeyPress() { return false; } +bool FindLatestExe(std::string& path) { + if (path.length() < 4) + return false; + + static const char VersionsFolder[] = "Versions\\"; + static std::size_t BaseFolderNameLen = 10; // "Base00000\" + std::size_t versions_pos = path.find(VersionsFolder); + if (versions_pos == std::string::npos) { + return DoesFileExist(path); + } + + // Get the versions path. + std::string versions_path = path; + versions_path.erase(versions_path.begin() + versions_pos + sizeof(VersionsFolder) - 1, versions_path.end()); + + // Get the exe name. + std::string exe_name = path; + exe_name.erase(exe_name.begin(), exe_name.begin() + versions_pos + sizeof(VersionsFolder) + BaseFolderNameLen - 1); + + // Get a list of all subfolders. + std::vector subfolders; + scan_directory(versions_path.c_str(), subfolders, true, true); + if (subfolders.size() < 1) { + return DoesFileExist(path); + } + + // Sort the subfolders list. + std::sort(subfolders.begin(), subfolders.end()); + + for (int folder_index = static_cast(subfolders.size()) - 1; folder_index >= 0; --folder_index) { + std::string test_path = subfolders[folder_index] + "\\" + exe_name; + if (DoesFileExist(test_path)) { + path = test_path; + return true; + } + } + + return DoesFileExist(path); +} + +bool FindBaseExe(std::string& path, uint32_t base_build) { + const std::string base_folder = "Base"; + + std::string new_path = path; + std::string new_num = std::to_string(base_build); + + auto folder_start = new_path.find(base_folder); + if (folder_start == std::string::npos) + return false; + + auto num_start = folder_start + base_folder.size(); + auto num_end = num_start + new_num.size(); + if (num_end > new_path.size()) + return false; + + new_path.replace(new_path.begin() + num_start, new_path.begin() + num_end, new_num.begin(), new_num.end()); + if (!DoesFileExist(new_path)) + return false; + + path = new_path; + return true; +} + } From f75d156a028c936d1de30d92f384f942e4854eca Mon Sep 17 00:00:00 2001 From: abrunasso Date: Wed, 16 Aug 2017 17:37:32 -0700 Subject: [PATCH 06/14] Added food required/provided/ability/race/build to UnitTypeData. --- include/sc2api/sc2_data.h | 10 ++++++++++ protocol | 2 +- src/sc2api/sc2_data.cc | 11 +++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/include/sc2api/sc2_data.h b/include/sc2api/sc2_data.h index a5d2148c..eab36a6d 100644 --- a/include/sc2api/sc2_data.h +++ b/include/sc2api/sc2_data.h @@ -172,6 +172,16 @@ struct UnitTypeData { float armor; //! Weapons on this unit type. std::vector weapons; + //! How much food the unit requires. + float food_required; + //! How much food the unit provides. + float food_provided; + //! Which ability id creates the unit. + AbilityID ability_id; + //! The race the unit belongs to. + Race race; + //! How long the unit takes to build. + float build_time; //! Constructor. UnitTypeData(); diff --git a/protocol b/protocol index e3772283..a4384ba4 160000 --- a/protocol +++ b/protocol @@ -1 +1 @@ -Subproject commit e3772283e56491854c672f7396873a39a005f912 +Subproject commit a4384ba490ab7feaa48df611c193faaae9b9b9e6 diff --git a/src/sc2api/sc2_data.cc b/src/sc2api/sc2_data.cc index 6a34fb14..f17a6995 100644 --- a/src/sc2api/sc2_data.cc +++ b/src/sc2api/sc2_data.cc @@ -1,5 +1,6 @@ #include "sc2api/sc2_data.h" #include "sc2api/sc2_interfaces.h" +#include "sc2api/sc2_proto_to_pods.h" #include #include @@ -275,6 +276,16 @@ void UnitTypeData::ReadFromProto(const SC2APIProtocol::UnitTypeData& unit_data) weapon.ReadFromProto(unit_data.weapons(i)); weapons.push_back(weapon); } + + food_provided = unit_data.food_provided(); + + food_required = unit_data.food_required(); + + ability_id = unit_data.ability_id(); + + race = ConvertRaceFromProto(unit_data.race()); + + build_time = unit_data.build_time(); } std::string UnitTypeData::Log() const { From 04c8977cc77bdfae02986325a7976418832964bc Mon Sep 17 00:00:00 2001 From: abrunasso Date: Wed, 16 Aug 2017 19:29:45 -0700 Subject: [PATCH 07/14] Added has_minerals and has_vespene to UnitTypeData. --- include/sc2api/sc2_data.h | 4 ++++ protocol | 2 +- src/sc2api/sc2_data.cc | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/sc2api/sc2_data.h b/include/sc2api/sc2_data.h index eab36a6d..e56fd715 100644 --- a/include/sc2api/sc2_data.h +++ b/include/sc2api/sc2_data.h @@ -182,6 +182,10 @@ struct UnitTypeData { Race race; //! How long the unit takes to build. float build_time; + //! Whether the unit can have minerals (mineral patches). + bool has_minerals; + //! Whether the unit can have vespene (vespene geysers). + bool has_vespene; //! Constructor. UnitTypeData(); diff --git a/protocol b/protocol index a4384ba4..f048d7df 160000 --- a/protocol +++ b/protocol @@ -1 +1 @@ -Subproject commit a4384ba490ab7feaa48df611c193faaae9b9b9e6 +Subproject commit f048d7df893c8a40570718298042ebb24c26201b diff --git a/src/sc2api/sc2_data.cc b/src/sc2api/sc2_data.cc index f17a6995..381dbc3c 100644 --- a/src/sc2api/sc2_data.cc +++ b/src/sc2api/sc2_data.cc @@ -286,6 +286,10 @@ void UnitTypeData::ReadFromProto(const SC2APIProtocol::UnitTypeData& unit_data) race = ConvertRaceFromProto(unit_data.race()); build_time = unit_data.build_time(); + + has_minerals = unit_data.has_minerals(); + + has_vespene = unit_data.has_vespene(); } std::string UnitTypeData::Log() const { From a76b1224619a340be3d3fa85eaa9afdcbefaabad Mon Sep 17 00:00:00 2001 From: "BLIZZARD\\kcalderone" Date: Mon, 21 Aug 2017 13:11:01 -0700 Subject: [PATCH 08/14] Updated protocol for tech requirement data. --- protocol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol b/protocol index f048d7df..f1b97386 160000 --- a/protocol +++ b/protocol @@ -1 +1 @@ -Subproject commit f048d7df893c8a40570718298042ebb24c26201b +Subproject commit f1b973867693b703b3c79552246cb1d2ac28eb19 From 3027f4290700540b810fcee2d4095710708ed25e Mon Sep 17 00:00:00 2001 From: "BLIZZARD\\kcalderone" Date: Mon, 21 Aug 2017 14:12:20 -0700 Subject: [PATCH 09/14] Exposed tech requirement data. --- include/sc2api/sc2_data.h | 9 +++++++++ src/sc2api/sc2_data.cc | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/sc2api/sc2_data.h b/include/sc2api/sc2_data.h index e56fd715..8ebad501 100644 --- a/include/sc2api/sc2_data.h +++ b/include/sc2api/sc2_data.h @@ -187,6 +187,15 @@ struct UnitTypeData { //! Whether the unit can have vespene (vespene geysers). bool has_vespene; + //! Units this is equivalent to in terms of satisfying tech requirements. + std::vector tech_alias; + //! Units that are morphed variants of the same unit. + UnitTypeID unit_alias; + //! Structure required to build this unit. (Or any with the same tech_alias) + UnitTypeID tech_requirement; + //! Whether tech_requirement is an add-on. + bool require_attached; + //! Constructor. UnitTypeData(); diff --git a/src/sc2api/sc2_data.cc b/src/sc2api/sc2_data.cc index 381dbc3c..03de6eb2 100644 --- a/src/sc2api/sc2_data.cc +++ b/src/sc2api/sc2_data.cc @@ -290,6 +290,16 @@ void UnitTypeData::ReadFromProto(const SC2APIProtocol::UnitTypeData& unit_data) has_minerals = unit_data.has_minerals(); has_vespene = unit_data.has_vespene(); + + for (int i = 0; i < unit_data.tech_alias_size(); ++i) { + tech_alias.push_back(unit_data.tech_alias(i)); + } + + unit_alias = unit_data.unit_alias(); + + tech_requirement = unit_data.tech_requirement(); + + require_attached = unit_data.require_attached(); } std::string UnitTypeData::Log() const { From 98cdb27ac4d2885fcef4e1212dcf888556bb00ed Mon Sep 17 00:00:00 2001 From: "BLIZZARD\\kcalderone" Date: Tue, 22 Aug 2017 16:13:16 -0700 Subject: [PATCH 10/14] Added invalid entry to typeenums. --- include/sc2api/sc2_typeenums.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/include/sc2api/sc2_typeenums.h b/include/sc2api/sc2_typeenums.h index dafa07ff..4e12f4ee 100644 --- a/include/sc2api/sc2_typeenums.h +++ b/include/sc2api/sc2_typeenums.h @@ -23,6 +23,8 @@ namespace sc2 { typedef SC2Type BuffID; enum class UNIT_TYPEID { + INVALID = 0, + // Terran TERRAN_ARMORY = 29, // CANCEL, HALT, CANCEL_LAST, RESEARCH_TERRANSHIPWEAPONS, RESEARCH_TERRANVEHICLEANDSHIPPLATING, RESEARCH_TERRANVEHICLEWEAPONS TERRAN_AUTOTURRET = 31, // SMART, STOP, ATTACK @@ -76,7 +78,7 @@ namespace sc2 { TERRAN_WIDOWMINE = 498, // SMART, MOVE, PATROL, HOLDPOSITION, BURROWDOWN, STOP, ATTACK TERRAN_WIDOWMINEBURROWED = 500, // SMART, EFFECT_WIDOWMINEATTACK, BURROWUP - // Terran non-interactive + // Terran non-interactive TERRAN_KD8CHARGE = 830, TERRAN_NUKE = 58, TERRAN_POINTDEFENSEDRONE = 11, @@ -154,7 +156,7 @@ namespace sc2 { ZERG_ZERGLING = 105, // SMART, MOVE, PATROL, HOLDPOSITION, TRAIN_BANELING, BURROWDOWN, STOP, ATTACK ZERG_ZERGLINGBURROWED = 119, // BURROWUP - // Zerg non-interactive + // Zerg non-interactive ZERG_PARASITICBOMBDUMMY = 824, // Protoss @@ -200,9 +202,9 @@ namespace sc2 { PROTOSS_WARPPRISMPHASING = 136, // SMART, MORPH_WARPPRISMTRANSPORTMODE, STOP, LOAD, UNLOADALLAT PROTOSS_ZEALOT = 73, // SMART, MOVE, PATROL, HOLDPOSITION, EFFECT_CHARGE, STOP, RALLY_UNITS, ATTACK - // Protoss non-interactive + // Protoss non-interactive - // Neutral + // Neutral NEUTRAL_COLLAPSIBLEROCKTOWERDEBRIS = 490, NEUTRAL_COLLAPSIBLEROCKTOWERDIAGONAL = 588, NEUTRAL_COLLAPSIBLEROCKTOWERPUSHUNIT = 561, @@ -239,6 +241,7 @@ namespace sc2 { }; enum class ABILITY_ID { + INVALID = 0, SMART = 1, // Target: Unit, Point. ATTACK = 3674, // Target: Unit, Point. @@ -705,6 +708,7 @@ namespace sc2 { }; enum class UPGRADE_ID { + INVALID = 0, CARRIERLAUNCHSPEEDUPGRADE = 1, GLIALRECONSTITUTION = 2, TUNNELINGCLAWS = 3, @@ -793,6 +797,7 @@ namespace sc2 { }; enum class BUFF_ID { + INVALID = 0, GRAVITONBEAM = 5, GHOSTCLOAK = 6, BANSHEECLOAK = 7, From fc6ce52cf0ae3abc1c5ac704c99e00197f34540b Mon Sep 17 00:00:00 2001 From: "BLIZZARD\\kcalderone" Date: Mon, 28 Aug 2017 11:20:11 -0700 Subject: [PATCH 11/14] Exposing research_time. Updated documentation. --- include/sc2api/sc2_data.h | 17 +++++++++++++---- src/sc2api/sc2_data.cc | 1 + 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/include/sc2api/sc2_data.h b/include/sc2api/sc2_data.h index 8ebad501..eaf64b8f 100644 --- a/include/sc2api/sc2_data.h +++ b/include/sc2api/sc2_data.h @@ -210,11 +210,18 @@ typedef std::vector UnitTypes; //! Upgrade data. struct UpgradeData { - uint32_t upgrade_id; // Stable ID. - std::string name; // Catalog name of the upgrade. + //! Stable ID. This ID will not change between patches. + uint32_t upgrade_id; + //! Upgrade name, corresponds to the game's catalog. + std::string name; + //! Mineral cost of researching the upgrade. uint32_t mineral_cost; + //! Vespene cost of researching the upgrade. uint32_t vespene_cost; + //! Ability that researches this upgrade. AbilityID ability_id; + //! Time in GameLoops to research this upgrade. + float research_time; UpgradeData(); @@ -226,8 +233,10 @@ typedef std::vector Upgrades; //! Buff data. struct BuffData { - uint32_t buff_id; // Stable ID. - std::string name; // Catalog name of the buff. + //! Stable ID. This ID will not change between patches. + uint32_t buff_id; + //! Buff name, corresponds to the game's catalog. + std::string name; BuffData(); diff --git a/src/sc2api/sc2_data.cc b/src/sc2api/sc2_data.cc index 03de6eb2..7163f07a 100644 --- a/src/sc2api/sc2_data.cc +++ b/src/sc2api/sc2_data.cc @@ -324,6 +324,7 @@ void UpgradeData::ReadFromProto(const SC2APIProtocol::UpgradeData& upgrade_data) mineral_cost = upgrade_data.mineral_cost(); vespene_cost = upgrade_data.vespene_cost(); ability_id = upgrade_data.ability_id(); + research_time = upgrade_data.research_time(); } std::string UpgradeData::Log() const { From afe5608474f1ac9c833413ac696ccf04ff8583cf Mon Sep 17 00:00:00 2001 From: "BLIZZARD\\kcalderone" Date: Thu, 31 Aug 2017 15:16:13 -0700 Subject: [PATCH 12/14] Updating protocol submodule to SC2.3.17 version. --- protocol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol b/protocol index f1b97386..08309d86 160000 --- a/protocol +++ b/protocol @@ -1 +1 @@ -Subproject commit f1b973867693b703b3c79552246cb1d2ac28eb19 +Subproject commit 08309d8640fc6a3ce6f3673fa6df58122958ac46 From 63c60d55c10937e0b89a4c298ba46ae07179cf64 Mon Sep 17 00:00:00 2001 From: "BLIZZARD\\kcalderone" Date: Thu, 31 Aug 2017 15:24:03 -0700 Subject: [PATCH 13/14] Regenerated doxygen docs. --- ...ction_feature_layer_interface-members.html | 1 + ...classsc2_1_1_action_interface-members.html | 1 + docs/html/classsc2_1_1_agent-members.html | 14 +- docs/html/classsc2_1_1_agent.html | 32 +- ...2_1_1_agent_control_interface-members.html | 1 + docs/html/classsc2_1_1_client-members.html | 14 +- docs/html/classsc2_1_1_client.html | 32 +- .../classsc2_1_1_client_events-members.html | 14 +- docs/html/classsc2_1_1_client_events.html | 68 +- .../html/classsc2_1_1_connection-members.html | 21 +- docs/html/classsc2_1_1_connection.html | 4 + ...lasssc2_1_1_control_interface-members.html | 1 + .../classsc2_1_1_debug_interface-members.html | 1 + ...sc2_1_1_observation_interface-members.html | 1 + .../classsc2_1_1_proto_interface-members.html | 12 +- docs/html/classsc2_1_1_proto_interface.html | 12 + .../classsc2_1_1_query_interface-members.html | 1 + ..._1_1_replay_control_interface-members.html | 3 +- ...classsc2_1_1_replay_control_interface.html | 6 +- .../classsc2_1_1_replay_observer-members.html | 14 +- docs/html/classsc2_1_1_replay_observer.html | 32 +- docs/html/classsc2_1_1_unit-members.html | 43 +- docs/html/classsc2_1_1_unit.html | 4 + docs/html/functions.html | 8 +- docs/html/functions_b.html | 6 + docs/html/functions_d.html | 5 +- docs/html/functions_f.html | 6 + docs/html/functions_func.html | 17 +- docs/html/functions_h.html | 6 + docs/html/functions_i.html | 3 + docs/html/functions_m.html | 1 + docs/html/functions_n.html | 4 +- docs/html/functions_o.html | 14 +- docs/html/functions_r.html | 7 + docs/html/functions_t.html | 6 + docs/html/functions_u.html | 8 +- docs/html/functions_v.html | 1 + docs/html/functions_vars.html | 48 +- docs/html/sc2__agent_8h_source.html | 8 +- docs/html/sc2__client_8h.html | 3 +- docs/html/sc2__client_8h_source.html | 34 +- docs/html/sc2__connection_8h_source.html | 6 +- .../sc2__control__interfaces_8h_source.html | 8 +- docs/html/sc2__coordinator_8h_source.html | 4 +- docs/html/sc2__data_8h_source.html | 33 +- docs/html/sc2__game__settings_8h_source.html | 10 +- docs/html/sc2__gametypes_8h_source.html | 2 +- docs/html/sc2__interfaces_8h_source.html | 14 +- docs/html/sc2__manage__process_8h_source.html | 2 +- .../html/sc2__proto__interface_8h_source.html | 2 +- docs/html/sc2__renderer_8h_source.html | 2 +- .../html/sc2__replay__observer_8h_source.html | 4 +- docs/html/sc2__search_8h_source.html | 4 +- docs/html/sc2__typeenums_8h.html | 798 +++++++++--------- docs/html/sc2__typeenums_8h_source.html | 2 +- docs/html/sc2__unit_8h_source.html | 7 +- docs/html/search/all_0.js | 2 +- docs/html/search/all_1.js | 2 + docs/html/search/all_11.js | 2 + docs/html/search/all_12.js | 2 + docs/html/search/all_13.js | 2 +- docs/html/search/all_3.js | 1 + docs/html/search/all_5.js | 2 + docs/html/search/all_7.js | 2 + docs/html/search/all_8.js | 1 + docs/html/search/all_a.js | 2 +- docs/html/search/all_b.js | 2 +- docs/html/search/all_c.js | 14 +- docs/html/search/all_f.js | 6 +- docs/html/search/functions_3.js | 1 + docs/html/search/functions_9.js | 14 +- docs/html/search/variables_0.js | 2 +- docs/html/search/variables_1.js | 2 + docs/html/search/variables_11.js | 2 + docs/html/search/variables_12.js | 4 +- docs/html/search/variables_13.js | 2 +- docs/html/search/variables_5.js | 2 + docs/html/search/variables_7.js | 2 + docs/html/search/variables_8.js | 1 + docs/html/search/variables_a.js | 2 +- docs/html/search/variables_b.js | 2 +- docs/html/search/variables_f.js | 6 +- .../html/structsc2_1_1_buff_data-members.html | 4 +- docs/html/structsc2_1_1_buff_data.html | 6 +- ...tructsc2_1_1_process_settings-members.html | 21 +- docs/html/structsc2_1_1_process_settings.html | 3 + .../structsc2_1_1_replay_info-members.html | 23 +- docs/html/structsc2_1_1_replay_info.html | 3 + .../structsc2_1_1_unit_type_data-members.html | 27 +- docs/html/structsc2_1_1_unit_type_data.html | 44 + .../structsc2_1_1_upgrade_data-members.html | 12 +- docs/html/structsc2_1_1_upgrade_data.html | 22 +- docs/latex/classsc2_1_1_client_events.tex | 40 +- docs/latex/classsc2_1_1_connection.tex | 3 + docs/latex/classsc2_1_1_proto_interface.tex | 12 + .../classsc2_1_1_replay_control_interface.tex | 4 +- docs/latex/classsc2_1_1_unit.tex | 5 +- docs/latex/sc2__client_8h.tex | 3 +- docs/latex/sc2__typeenums_8h.tex | 396 ++++----- docs/latex/structsc2_1_1_buff_data.tex | 8 +- docs/latex/structsc2_1_1_process_settings.tex | 3 + docs/latex/structsc2_1_1_replay_info.tex | 3 + docs/latex/structsc2_1_1_unit_type_data.tex | 35 +- docs/latex/structsc2_1_1_upgrade_data.tex | 20 +- 104 files changed, 1272 insertions(+), 922 deletions(-) diff --git a/docs/html/classsc2_1_1_action_feature_layer_interface-members.html b/docs/html/classsc2_1_1_action_feature_layer_interface-members.html index cfcb60a2..5b9e3c7e 100644 --- a/docs/html/classsc2_1_1_action_feature_layer_interface-members.html +++ b/docs/html/classsc2_1_1_action_feature_layer_interface-members.html @@ -77,6 +77,7 @@ SendActions()=0sc2::ActionFeatureLayerInterfacepure virtual UnitCommand(AbilityID ability)=0sc2::ActionFeatureLayerInterfacepure virtual UnitCommand(AbilityID ability, const Point2DI &point, bool minimap=false)=0sc2::ActionFeatureLayerInterfacepure virtual + ~ActionFeatureLayerInterface()=default (defined in sc2::ActionFeatureLayerInterface)sc2::ActionFeatureLayerInterfacevirtual