From 85adbf990e1b6a0a7706052a6352543711d312c0 Mon Sep 17 00:00:00 2001 From: Thad House Date: Fri, 6 Feb 2026 21:38:15 -0800 Subject: [PATCH] [hal,wpilib] Switch to new game data (#8584) Game data is now limited to 8 bytes, and comes through the UDP packets. --- glass/src/lib/native/cpp/other/FMS.cpp | 17 +- .../native/include/wpi/glass/other/FMS.hpp | 4 +- glass/src/libnt/native/cpp/NTFMS.cpp | 12 +- .../include/wpi/glass/networktables/NTFMS.hpp | 10 +- hal/robotpy_pybind_build_info.bzl | 1 + .../native/cpp/mrc/protobuf/MrcComm.npb.cpp | 916 +++++++++--------- .../native/cpp/mrc/protobuf/MrcComm.npb.h | 9 +- .../wpilib/hardware/hal/DriverStationJNI.java | 9 + .../wpilib/hardware/hal/MatchInfoData.java | 12 +- .../hal/simulation/DriverStationDataJNI.java | 10 +- .../main/native/cpp/jni/DriverStationJNI.cpp | 23 + hal/src/main/native/cpp/jni/HALUtil.cpp | 15 +- .../jni/simulation/DriverStationDataJNI.cpp | 40 +- .../native/cpp/proto/ControlDataProto.cpp | 11 + .../native/include/wpi/hal/DriverStation.h | 8 + .../include/wpi/hal/DriverStationTypes.h | 7 +- .../wpi/hal/simulation/DriverStationData.h | 10 +- hal/src/main/native/sim/DriverStation.cpp | 11 + .../native/sim/mockdata/DriverStationData.cpp | 59 +- .../sim/mockdata/DriverStationDataInternal.h | 13 +- .../native/systemcore/FRCDriverStation.cpp | 26 +- .../systemcore/mockdata/DriverStationData.cpp | 13 +- .../main/python/semiwrap/DriverStation.yml | 1 + .../python/semiwrap/DriverStationTypes.yml | 5 +- .../semiwrap/simulation/DriverStationData.yml | 9 +- hal/src/mrc/include/mrc/NetComm.h | 53 +- hal/src/mrc/include/mrc/NtNetComm.h | 6 +- hal/src/mrc/proto/MrcComm.proto | 1 + .../cpp/mockdata/DriverStationDataTest.cpp | 9 - .../src/main/native/cpp/DSCommPacket.cpp | 20 - .../wpi/halsim/ds_socket/DSCommPacket.hpp | 1 - .../src/test/native/cpp/DSCommPacketTest.cpp | 26 - .../src/main/native/cpp/DriverStationGui.cpp | 18 +- .../native/cpp/WSProvider_DriverStation.cpp | 2 +- .../cpp/driverstation/DriverStation.cpp | 24 +- .../cpp/simulation/DriverStationSim.cpp | 4 +- .../wpi/driverstation/DriverStation.hpp | 2 +- .../wpi/simulation/DriverStationSim.hpp | 2 +- .../main/python/semiwrap/DriverStation.yml | 2 +- .../semiwrap/simulation/DriverStationSim.yml | 2 +- .../cpp/simulation/DriverStationSimTest.cpp | 20 +- .../wpilib/driverstation/DriverStation.java | 33 +- .../wpilib/simulation/DriverStationSim.java | 4 +- .../org/wpilib/hal/MatchInfoDataTest.java | 5 +- .../simulation/DriverStationSimTest.java | 30 +- 45 files changed, 820 insertions(+), 695 deletions(-) diff --git a/glass/src/lib/native/cpp/other/FMS.cpp b/glass/src/lib/native/cpp/other/FMS.cpp index fb6ca4c1a0..1fd6ef5701 100644 --- a/glass/src/lib/native/cpp/other/FMS.cpp +++ b/glass/src/lib/native/cpp/other/FMS.cpp @@ -81,12 +81,12 @@ void wpi::glass::DisplayFMS(FMSModel* model, bool editableDsAttached) { } } - // Game Specific Message - if (auto data = model->GetGameSpecificMessageData()) { - std::string gameSpecificMessage = data->GetValue(); + // Game Data + if (auto data = model->GetGameData()) { + std::string gameData = data->GetValue(); ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); - if (ImGui::InputText("Game Specific", &gameSpecificMessage)) { - model->SetGameSpecificMessage(gameSpecificMessage); + if (ImGui::InputText("Game Data", &gameData)) { + model->SetGameData(gameData); } } } @@ -145,14 +145,13 @@ void wpi::glass::DisplayFMSReadOnly(FMSModel* model) { ImGui::TextUnformatted("?"); } } - if (auto data = model->GetGameSpecificMessageData()) { + if (auto data = model->GetGameData()) { if (exists) { wpi::util::SmallString<64> gsmBuf; std::string_view gsm = data->GetValue(gsmBuf); - ImGui::Text("Game Specific: %.*s", static_cast(gsm.size()), - gsm.data()); + ImGui::Text("Game Data: %.*s", static_cast(gsm.size()), gsm.data()); } else { - ImGui::TextUnformatted("Game Specific: ?"); + ImGui::TextUnformatted("Game Data: ?"); } } diff --git a/glass/src/lib/native/include/wpi/glass/other/FMS.hpp b/glass/src/lib/native/include/wpi/glass/other/FMS.hpp index ed392f2d7c..b0e4c701b5 100644 --- a/glass/src/lib/native/include/wpi/glass/other/FMS.hpp +++ b/glass/src/lib/native/include/wpi/glass/other/FMS.hpp @@ -36,7 +36,7 @@ class FMSModel : public Model { virtual BooleanSource* GetEStopData() = 0; virtual BooleanSource* GetEnabledData() = 0; virtual IntegerSource* GetRobotModeData() = 0; - virtual StringSource* GetGameSpecificMessageData() = 0; + virtual StringSource* GetGameData() = 0; virtual void SetFmsAttached(bool val) = 0; virtual void SetDsAttached(bool val) = 0; @@ -45,7 +45,7 @@ class FMSModel : public Model { virtual void SetEStop(bool val) = 0; virtual void SetEnabled(bool val) = 0; virtual void SetRobotMode(RobotMode val) = 0; - virtual void SetGameSpecificMessage(std::string_view val) = 0; + virtual void SetGameData(std::string_view val) = 0; }; /** diff --git a/glass/src/libnt/native/cpp/NTFMS.cpp b/glass/src/libnt/native/cpp/NTFMS.cpp index ddbf0c76b6..e6a0cedf43 100644 --- a/glass/src/libnt/native/cpp/NTFMS.cpp +++ b/glass/src/libnt/native/cpp/NTFMS.cpp @@ -30,9 +30,8 @@ NTFMSModel::NTFMSModel(std::string_view path) NTFMSModel::NTFMSModel(wpi::nt::NetworkTableInstance inst, std::string_view path) : m_inst{inst}, - m_gameSpecificMessage{ - inst.GetStringTopic(fmt::format("{}/GameSpecificMessage", path)) - .Subscribe("")}, + m_gameDataSubscriber{ + inst.GetStringTopic(fmt::format("{}/GameData", path)).Subscribe("")}, m_alliance{inst.GetBooleanTopic(fmt::format("{}/IsRedAlliance", path)) .Subscribe(false)}, m_station{inst.GetIntegerTopic(fmt::format("{}/StationNumber", path)) @@ -45,8 +44,7 @@ NTFMSModel::NTFMSModel(wpi::nt::NetworkTableInstance inst, m_estop{fmt::format("NT_FMS:EStop:{}", path)}, m_enabled{fmt::format("NT_FMS:RobotEnabled:{}", path)}, m_robotMode{fmt::format("NT_FMS:RobotMode:{}", path)}, - m_gameSpecificMessageData{ - fmt::format("NT_FMS:GameSpecificMessage:{}", path)} {} + m_gameData{fmt::format("NT_FMS:GameData:{}", path)} {} void NTFMSModel::Update() { for (auto&& v : m_alliance.ReadQueue()) { @@ -82,8 +80,8 @@ void NTFMSModel::Update() { ((controlWord & HAL_CONTROLWORD_DS_ATTACHED_MASK) != 0) ? 1 : 0, v.time); } - for (auto&& v : m_gameSpecificMessage.ReadQueue()) { - m_gameSpecificMessageData.SetValue(std::move(v.value), v.time); + for (auto&& v : m_gameDataSubscriber.ReadQueue()) { + m_gameData.SetValue(std::move(v.value), v.time); } } diff --git a/glass/src/libnt/native/include/wpi/glass/networktables/NTFMS.hpp b/glass/src/libnt/native/include/wpi/glass/networktables/NTFMS.hpp index 5de9fcb396..c2e7178c9a 100644 --- a/glass/src/libnt/native/include/wpi/glass/networktables/NTFMS.hpp +++ b/glass/src/libnt/native/include/wpi/glass/networktables/NTFMS.hpp @@ -34,9 +34,7 @@ class NTFMSModel : public FMSModel { BooleanSource* GetEStopData() override { return &m_estop; } BooleanSource* GetEnabledData() override { return &m_enabled; } IntegerSource* GetRobotModeData() override { return &m_robotMode; } - StringSource* GetGameSpecificMessageData() override { - return &m_gameSpecificMessageData; - } + StringSource* GetGameData() override { return &m_gameData; } // NT is read-only (it's continually set by robot code) void SetFmsAttached(bool val) override {} @@ -46,7 +44,7 @@ class NTFMSModel : public FMSModel { void SetEStop(bool val) override {} void SetEnabled(bool val) override {} void SetRobotMode(RobotMode val) override {} - void SetGameSpecificMessage(std::string_view val) override {} + void SetGameData(std::string_view val) override {} void Update() override; bool Exists() override; @@ -54,7 +52,7 @@ class NTFMSModel : public FMSModel { private: wpi::nt::NetworkTableInstance m_inst; - wpi::nt::StringSubscriber m_gameSpecificMessage; + wpi::nt::StringSubscriber m_gameDataSubscriber; wpi::nt::BooleanSubscriber m_alliance; wpi::nt::IntegerSubscriber m_station; wpi::nt::RawSubscriber m_controlWord; @@ -65,7 +63,7 @@ class NTFMSModel : public FMSModel { BooleanSource m_estop; BooleanSource m_enabled; IntegerSource m_robotMode; - StringSource m_gameSpecificMessageData; + StringSource m_gameData; }; } // namespace wpi::glass diff --git a/hal/robotpy_pybind_build_info.bzl b/hal/robotpy_pybind_build_info.bzl index eac6f28fcc..a437dd7cb2 100644 --- a/hal/robotpy_pybind_build_info.bzl +++ b/hal/robotpy_pybind_build_info.bzl @@ -172,6 +172,7 @@ def wpihal_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includ ("HAL_JoystickTouchpads", "__HAL_JoystickTouchpads.hpp"), ("HAL_OpModeOption", "__HAL_OpModeOption.hpp"), ("wpi::hal::ControlWord", "wpi__hal__ControlWord.hpp"), + ("HAL_GameData", "__HAL_GameData.hpp"), ], ), struct( diff --git a/hal/src/generated/main/native/cpp/mrc/protobuf/MrcComm.npb.cpp b/hal/src/generated/main/native/cpp/mrc/protobuf/MrcComm.npb.cpp index 14bb7a7418..2b4745e466 100644 --- a/hal/src/generated/main/native/cpp/mrc/protobuf/MrcComm.npb.cpp +++ b/hal/src/generated/main/native/cpp/mrc/protobuf/MrcComm.npb.cpp @@ -56,7 +56,7 @@ static const uint8_t file_descriptor[] { 0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x54,0x6f, 0x75,0x63,0x68,0x70,0x61,0x64,0x44,0x61,0x74,0x61, 0x52,0x09,0x54,0x6f,0x75,0x63,0x68,0x70,0x61,0x64, -0x73,0x22,0xba,0x01,0x0a,0x13,0x50,0x72,0x6f,0x74, +0x73,0x22,0xd6,0x01,0x0a,0x13,0x50,0x72,0x6f,0x74, 0x6f,0x62,0x75,0x66,0x43,0x6f,0x6e,0x74,0x72,0x6f, 0x6c,0x44,0x61,0x74,0x61,0x12,0x20,0x0a,0x0b,0x43, 0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x57,0x6f,0x72,0x64, @@ -75,467 +75,475 @@ static const uint8_t file_descriptor[] { 0x65,0x6e,0x74,0x4f,0x70,0x4d,0x6f,0x64,0x65,0x18, 0x04,0x20,0x01,0x28,0x06,0x52,0x0d,0x43,0x75,0x72, 0x72,0x65,0x6e,0x74,0x4f,0x70,0x4d,0x6f,0x64,0x65, -0x22,0xac,0x01,0x0a,0x1a,0x50,0x72,0x6f,0x74,0x6f, -0x62,0x75,0x66,0x4a,0x6f,0x79,0x73,0x74,0x69,0x63, -0x6b,0x44,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x6f, -0x72,0x12,0x22,0x0a,0x0c,0x4a,0x6f,0x79,0x73,0x74, -0x69,0x63,0x6b,0x4e,0x61,0x6d,0x65,0x18,0x01,0x20, -0x01,0x28,0x09,0x52,0x0c,0x4a,0x6f,0x79,0x73,0x74, -0x69,0x63,0x6b,0x4e,0x61,0x6d,0x65,0x12,0x1c,0x0a, -0x09,0x49,0x73,0x47,0x61,0x6d,0x65,0x70,0x61,0x64, -0x18,0x02,0x20,0x01,0x28,0x08,0x52,0x09,0x49,0x73, -0x47,0x61,0x6d,0x65,0x70,0x61,0x64,0x12,0x20,0x0a, -0x0b,0x47,0x61,0x6d,0x65,0x70,0x61,0x64,0x54,0x79, -0x70,0x65,0x18,0x03,0x20,0x01,0x28,0x0d,0x52,0x0b, -0x47,0x61,0x6d,0x65,0x70,0x61,0x64,0x54,0x79,0x70, -0x65,0x12,0x2a,0x0a,0x10,0x53,0x75,0x70,0x70,0x6f, -0x72,0x74,0x65,0x64,0x4f,0x75,0x74,0x70,0x75,0x74, -0x73,0x18,0x04,0x20,0x01,0x28,0x0d,0x52,0x10,0x53, -0x75,0x70,0x70,0x6f,0x72,0x74,0x65,0x64,0x4f,0x75, -0x74,0x70,0x75,0x74,0x73,0x22,0x66,0x0a,0x1b,0x50, -0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4a,0x6f,0x79, -0x73,0x74,0x69,0x63,0x6b,0x44,0x65,0x73,0x63,0x72, -0x69,0x70,0x74,0x6f,0x72,0x73,0x12,0x47,0x0a,0x0b, -0x44,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x6f,0x72, -0x73,0x18,0x01,0x20,0x03,0x28,0x0b,0x32,0x25,0x2e, -0x6d,0x72,0x63,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x2e, -0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4a,0x6f, -0x79,0x73,0x74,0x69,0x63,0x6b,0x44,0x65,0x73,0x63, -0x72,0x69,0x70,0x74,0x6f,0x72,0x52,0x0b,0x44,0x65, -0x73,0x63,0x72,0x69,0x70,0x74,0x6f,0x72,0x73,0x22, -0x6a,0x0a,0x16,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75, -0x66,0x4a,0x6f,0x79,0x73,0x74,0x69,0x63,0x6b,0x4f, -0x75,0x74,0x70,0x75,0x74,0x12,0x12,0x0a,0x04,0x4c, -0x45,0x44,0x73,0x18,0x01,0x20,0x01,0x28,0x0d,0x52, -0x04,0x4c,0x45,0x44,0x73,0x12,0x16,0x0a,0x06,0x52, -0x75,0x6d,0x62,0x6c,0x65,0x18,0x02,0x20,0x01,0x28, -0x0d,0x52,0x06,0x52,0x75,0x6d,0x62,0x6c,0x65,0x12, -0x24,0x0a,0x0d,0x54,0x72,0x69,0x67,0x67,0x65,0x72, -0x52,0x75,0x6d,0x62,0x6c,0x65,0x18,0x03,0x20,0x01, -0x28,0x0d,0x52,0x0d,0x54,0x72,0x69,0x67,0x67,0x65, -0x72,0x52,0x75,0x6d,0x62,0x6c,0x65,0x22,0x56,0x0a, -0x17,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4a, +0x12,0x1a,0x0a,0x08,0x47,0x61,0x6d,0x65,0x44,0x61, +0x74,0x61,0x18,0x06,0x20,0x01,0x28,0x09,0x52,0x08, +0x47,0x61,0x6d,0x65,0x44,0x61,0x74,0x61,0x22,0xac, +0x01,0x0a,0x1a,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75, +0x66,0x4a,0x6f,0x79,0x73,0x74,0x69,0x63,0x6b,0x44, +0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x6f,0x72,0x12, +0x22,0x0a,0x0c,0x4a,0x6f,0x79,0x73,0x74,0x69,0x63, +0x6b,0x4e,0x61,0x6d,0x65,0x18,0x01,0x20,0x01,0x28, +0x09,0x52,0x0c,0x4a,0x6f,0x79,0x73,0x74,0x69,0x63, +0x6b,0x4e,0x61,0x6d,0x65,0x12,0x1c,0x0a,0x09,0x49, +0x73,0x47,0x61,0x6d,0x65,0x70,0x61,0x64,0x18,0x02, +0x20,0x01,0x28,0x08,0x52,0x09,0x49,0x73,0x47,0x61, +0x6d,0x65,0x70,0x61,0x64,0x12,0x20,0x0a,0x0b,0x47, +0x61,0x6d,0x65,0x70,0x61,0x64,0x54,0x79,0x70,0x65, +0x18,0x03,0x20,0x01,0x28,0x0d,0x52,0x0b,0x47,0x61, +0x6d,0x65,0x70,0x61,0x64,0x54,0x79,0x70,0x65,0x12, +0x2a,0x0a,0x10,0x53,0x75,0x70,0x70,0x6f,0x72,0x74, +0x65,0x64,0x4f,0x75,0x74,0x70,0x75,0x74,0x73,0x18, +0x04,0x20,0x01,0x28,0x0d,0x52,0x10,0x53,0x75,0x70, +0x70,0x6f,0x72,0x74,0x65,0x64,0x4f,0x75,0x74,0x70, +0x75,0x74,0x73,0x22,0x66,0x0a,0x1b,0x50,0x72,0x6f, +0x74,0x6f,0x62,0x75,0x66,0x4a,0x6f,0x79,0x73,0x74, +0x69,0x63,0x6b,0x44,0x65,0x73,0x63,0x72,0x69,0x70, +0x74,0x6f,0x72,0x73,0x12,0x47,0x0a,0x0b,0x44,0x65, +0x73,0x63,0x72,0x69,0x70,0x74,0x6f,0x72,0x73,0x18, +0x01,0x20,0x03,0x28,0x0b,0x32,0x25,0x2e,0x6d,0x72, +0x63,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x2e,0x50,0x72, +0x6f,0x74,0x6f,0x62,0x75,0x66,0x4a,0x6f,0x79,0x73, +0x74,0x69,0x63,0x6b,0x44,0x65,0x73,0x63,0x72,0x69, +0x70,0x74,0x6f,0x72,0x52,0x0b,0x44,0x65,0x73,0x63, +0x72,0x69,0x70,0x74,0x6f,0x72,0x73,0x22,0x6a,0x0a, +0x16,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4a, 0x6f,0x79,0x73,0x74,0x69,0x63,0x6b,0x4f,0x75,0x74, -0x70,0x75,0x74,0x73,0x12,0x3b,0x0a,0x07,0x4f,0x75, -0x74,0x70,0x75,0x74,0x73,0x18,0x01,0x20,0x03,0x28, -0x0b,0x32,0x21,0x2e,0x6d,0x72,0x63,0x2e,0x70,0x72, -0x6f,0x74,0x6f,0x2e,0x50,0x72,0x6f,0x74,0x6f,0x62, -0x75,0x66,0x4a,0x6f,0x79,0x73,0x74,0x69,0x63,0x6b, -0x4f,0x75,0x74,0x70,0x75,0x74,0x52,0x07,0x4f,0x75, -0x74,0x70,0x75,0x74,0x73,0x22,0x95,0x01,0x0a,0x11, -0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4d,0x61, -0x74,0x63,0x68,0x49,0x6e,0x66,0x6f,0x12,0x1c,0x0a, -0x09,0x45,0x76,0x65,0x6e,0x74,0x4e,0x61,0x6d,0x65, -0x18,0x01,0x20,0x01,0x28,0x09,0x52,0x09,0x45,0x76, -0x65,0x6e,0x74,0x4e,0x61,0x6d,0x65,0x12,0x20,0x0a, -0x0b,0x4d,0x61,0x74,0x63,0x68,0x4e,0x75,0x6d,0x62, -0x65,0x72,0x18,0x02,0x20,0x01,0x28,0x05,0x52,0x0b, -0x4d,0x61,0x74,0x63,0x68,0x4e,0x75,0x6d,0x62,0x65, -0x72,0x12,0x22,0x0a,0x0c,0x52,0x65,0x70,0x6c,0x61, -0x79,0x4e,0x75,0x6d,0x62,0x65,0x72,0x18,0x03,0x20, -0x01,0x28,0x05,0x52,0x0c,0x52,0x65,0x70,0x6c,0x61, -0x79,0x4e,0x75,0x6d,0x62,0x65,0x72,0x12,0x1c,0x0a, -0x09,0x4d,0x61,0x74,0x63,0x68,0x54,0x79,0x70,0x65, -0x18,0x04,0x20,0x01,0x28,0x05,0x52,0x09,0x4d,0x61, -0x74,0x63,0x68,0x54,0x79,0x70,0x65,0x22,0x9f,0x01, -0x0a,0x11,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66, -0x45,0x72,0x72,0x6f,0x72,0x49,0x6e,0x66,0x6f,0x12, -0x18,0x0a,0x07,0x49,0x73,0x45,0x72,0x72,0x6f,0x72, -0x18,0x01,0x20,0x01,0x28,0x08,0x52,0x07,0x49,0x73, -0x45,0x72,0x72,0x6f,0x72,0x12,0x1c,0x0a,0x09,0x45, -0x72,0x72,0x6f,0x72,0x43,0x6f,0x64,0x65,0x18,0x02, -0x20,0x01,0x28,0x11,0x52,0x09,0x45,0x72,0x72,0x6f, -0x72,0x43,0x6f,0x64,0x65,0x12,0x18,0x0a,0x07,0x44, -0x65,0x74,0x61,0x69,0x6c,0x73,0x18,0x03,0x20,0x01, -0x28,0x09,0x52,0x07,0x44,0x65,0x74,0x61,0x69,0x6c, -0x73,0x12,0x1a,0x0a,0x08,0x4c,0x6f,0x63,0x61,0x74, -0x69,0x6f,0x6e,0x18,0x04,0x20,0x01,0x28,0x09,0x52, -0x08,0x4c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x12, -0x1c,0x0a,0x09,0x43,0x61,0x6c,0x6c,0x53,0x74,0x61, -0x63,0x6b,0x18,0x05,0x20,0x01,0x28,0x09,0x52,0x09, -0x43,0x61,0x6c,0x6c,0x53,0x74,0x61,0x63,0x6b,0x22, -0xb8,0x01,0x0a,0x0e,0x50,0x72,0x6f,0x74,0x6f,0x62, -0x75,0x66,0x4f,0x70,0x4d,0x6f,0x64,0x65,0x12,0x12, -0x0a,0x04,0x48,0x61,0x73,0x68,0x18,0x01,0x20,0x01, -0x28,0x06,0x52,0x04,0x48,0x61,0x73,0x68,0x12,0x12, -0x0a,0x04,0x4e,0x61,0x6d,0x65,0x18,0x02,0x20,0x01, -0x28,0x09,0x52,0x04,0x4e,0x61,0x6d,0x65,0x12,0x14, -0x0a,0x05,0x47,0x72,0x6f,0x75,0x70,0x18,0x03,0x20, -0x01,0x28,0x09,0x52,0x05,0x47,0x72,0x6f,0x75,0x70, -0x12,0x20,0x0a,0x0b,0x44,0x65,0x73,0x63,0x72,0x69, -0x70,0x74,0x69,0x6f,0x6e,0x18,0x04,0x20,0x01,0x28, -0x09,0x52,0x0b,0x44,0x65,0x73,0x63,0x72,0x69,0x70, -0x74,0x69,0x6f,0x6e,0x12,0x1c,0x0a,0x09,0x54,0x65, -0x78,0x74,0x43,0x6f,0x6c,0x6f,0x72,0x18,0x05,0x20, -0x01,0x28,0x05,0x52,0x09,0x54,0x65,0x78,0x74,0x43, -0x6f,0x6c,0x6f,0x72,0x12,0x28,0x0a,0x0f,0x42,0x61, -0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x43,0x6f, -0x6c,0x6f,0x72,0x18,0x06,0x20,0x01,0x28,0x05,0x52, -0x0f,0x42,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e, -0x64,0x43,0x6f,0x6c,0x6f,0x72,0x22,0x4b,0x0a,0x18, -0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x41,0x76, -0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x4f,0x70,0x4d, -0x6f,0x64,0x65,0x73,0x12,0x2f,0x0a,0x05,0x4d,0x6f, -0x64,0x65,0x73,0x18,0x01,0x20,0x03,0x28,0x0b,0x32, -0x19,0x2e,0x6d,0x72,0x63,0x2e,0x70,0x72,0x6f,0x74, +0x70,0x75,0x74,0x12,0x12,0x0a,0x04,0x4c,0x45,0x44, +0x73,0x18,0x01,0x20,0x01,0x28,0x0d,0x52,0x04,0x4c, +0x45,0x44,0x73,0x12,0x16,0x0a,0x06,0x52,0x75,0x6d, +0x62,0x6c,0x65,0x18,0x02,0x20,0x01,0x28,0x0d,0x52, +0x06,0x52,0x75,0x6d,0x62,0x6c,0x65,0x12,0x24,0x0a, +0x0d,0x54,0x72,0x69,0x67,0x67,0x65,0x72,0x52,0x75, +0x6d,0x62,0x6c,0x65,0x18,0x03,0x20,0x01,0x28,0x0d, +0x52,0x0d,0x54,0x72,0x69,0x67,0x67,0x65,0x72,0x52, +0x75,0x6d,0x62,0x6c,0x65,0x22,0x56,0x0a,0x17,0x50, +0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4a,0x6f,0x79, +0x73,0x74,0x69,0x63,0x6b,0x4f,0x75,0x74,0x70,0x75, +0x74,0x73,0x12,0x3b,0x0a,0x07,0x4f,0x75,0x74,0x70, +0x75,0x74,0x73,0x18,0x01,0x20,0x03,0x28,0x0b,0x32, +0x21,0x2e,0x6d,0x72,0x63,0x2e,0x70,0x72,0x6f,0x74, 0x6f,0x2e,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66, -0x4f,0x70,0x4d,0x6f,0x64,0x65,0x52,0x05,0x4d,0x6f, -0x64,0x65,0x73,0x22,0xc6,0x01,0x0a,0x1a,0x50,0x72, -0x6f,0x74,0x6f,0x62,0x75,0x66,0x45,0x72,0x72,0x6f, -0x72,0x49,0x6e,0x66,0x6f,0x54,0x69,0x6d,0x65,0x73, -0x74,0x61,0x6d,0x70,0x12,0x3a,0x0a,0x09,0x45,0x72, -0x72,0x6f,0x72,0x49,0x6e,0x66,0x6f,0x18,0x01,0x20, -0x01,0x28,0x0b,0x32,0x1c,0x2e,0x6d,0x72,0x63,0x2e, -0x70,0x72,0x6f,0x74,0x6f,0x2e,0x50,0x72,0x6f,0x74, +0x4a,0x6f,0x79,0x73,0x74,0x69,0x63,0x6b,0x4f,0x75, +0x74,0x70,0x75,0x74,0x52,0x07,0x4f,0x75,0x74,0x70, +0x75,0x74,0x73,0x22,0x95,0x01,0x0a,0x11,0x50,0x72, +0x6f,0x74,0x6f,0x62,0x75,0x66,0x4d,0x61,0x74,0x63, +0x68,0x49,0x6e,0x66,0x6f,0x12,0x1c,0x0a,0x09,0x45, +0x76,0x65,0x6e,0x74,0x4e,0x61,0x6d,0x65,0x18,0x01, +0x20,0x01,0x28,0x09,0x52,0x09,0x45,0x76,0x65,0x6e, +0x74,0x4e,0x61,0x6d,0x65,0x12,0x20,0x0a,0x0b,0x4d, +0x61,0x74,0x63,0x68,0x4e,0x75,0x6d,0x62,0x65,0x72, +0x18,0x02,0x20,0x01,0x28,0x05,0x52,0x0b,0x4d,0x61, +0x74,0x63,0x68,0x4e,0x75,0x6d,0x62,0x65,0x72,0x12, +0x22,0x0a,0x0c,0x52,0x65,0x70,0x6c,0x61,0x79,0x4e, +0x75,0x6d,0x62,0x65,0x72,0x18,0x03,0x20,0x01,0x28, +0x05,0x52,0x0c,0x52,0x65,0x70,0x6c,0x61,0x79,0x4e, +0x75,0x6d,0x62,0x65,0x72,0x12,0x1c,0x0a,0x09,0x4d, +0x61,0x74,0x63,0x68,0x54,0x79,0x70,0x65,0x18,0x04, +0x20,0x01,0x28,0x05,0x52,0x09,0x4d,0x61,0x74,0x63, +0x68,0x54,0x79,0x70,0x65,0x22,0x9f,0x01,0x0a,0x11, +0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x45,0x72, +0x72,0x6f,0x72,0x49,0x6e,0x66,0x6f,0x12,0x18,0x0a, +0x07,0x49,0x73,0x45,0x72,0x72,0x6f,0x72,0x18,0x01, +0x20,0x01,0x28,0x08,0x52,0x07,0x49,0x73,0x45,0x72, +0x72,0x6f,0x72,0x12,0x1c,0x0a,0x09,0x45,0x72,0x72, +0x6f,0x72,0x43,0x6f,0x64,0x65,0x18,0x02,0x20,0x01, +0x28,0x11,0x52,0x09,0x45,0x72,0x72,0x6f,0x72,0x43, +0x6f,0x64,0x65,0x12,0x18,0x0a,0x07,0x44,0x65,0x74, +0x61,0x69,0x6c,0x73,0x18,0x03,0x20,0x01,0x28,0x09, +0x52,0x07,0x44,0x65,0x74,0x61,0x69,0x6c,0x73,0x12, +0x1a,0x0a,0x08,0x4c,0x6f,0x63,0x61,0x74,0x69,0x6f, +0x6e,0x18,0x04,0x20,0x01,0x28,0x09,0x52,0x08,0x4c, +0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x12,0x1c,0x0a, +0x09,0x43,0x61,0x6c,0x6c,0x53,0x74,0x61,0x63,0x6b, +0x18,0x05,0x20,0x01,0x28,0x09,0x52,0x09,0x43,0x61, +0x6c,0x6c,0x53,0x74,0x61,0x63,0x6b,0x22,0xb8,0x01, +0x0a,0x0e,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66, +0x4f,0x70,0x4d,0x6f,0x64,0x65,0x12,0x12,0x0a,0x04, +0x48,0x61,0x73,0x68,0x18,0x01,0x20,0x01,0x28,0x06, +0x52,0x04,0x48,0x61,0x73,0x68,0x12,0x12,0x0a,0x04, +0x4e,0x61,0x6d,0x65,0x18,0x02,0x20,0x01,0x28,0x09, +0x52,0x04,0x4e,0x61,0x6d,0x65,0x12,0x14,0x0a,0x05, +0x47,0x72,0x6f,0x75,0x70,0x18,0x03,0x20,0x01,0x28, +0x09,0x52,0x05,0x47,0x72,0x6f,0x75,0x70,0x12,0x20, +0x0a,0x0b,0x44,0x65,0x73,0x63,0x72,0x69,0x70,0x74, +0x69,0x6f,0x6e,0x18,0x04,0x20,0x01,0x28,0x09,0x52, +0x0b,0x44,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69, +0x6f,0x6e,0x12,0x1c,0x0a,0x09,0x54,0x65,0x78,0x74, +0x43,0x6f,0x6c,0x6f,0x72,0x18,0x05,0x20,0x01,0x28, +0x05,0x52,0x09,0x54,0x65,0x78,0x74,0x43,0x6f,0x6c, +0x6f,0x72,0x12,0x28,0x0a,0x0f,0x42,0x61,0x63,0x6b, +0x67,0x72,0x6f,0x75,0x6e,0x64,0x43,0x6f,0x6c,0x6f, +0x72,0x18,0x06,0x20,0x01,0x28,0x05,0x52,0x0f,0x42, +0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x43, +0x6f,0x6c,0x6f,0x72,0x22,0x4b,0x0a,0x18,0x50,0x72, +0x6f,0x74,0x6f,0x62,0x75,0x66,0x41,0x76,0x61,0x69, +0x6c,0x61,0x62,0x6c,0x65,0x4f,0x70,0x4d,0x6f,0x64, +0x65,0x73,0x12,0x2f,0x0a,0x05,0x4d,0x6f,0x64,0x65, +0x73,0x18,0x01,0x20,0x03,0x28,0x0b,0x32,0x19,0x2e, +0x6d,0x72,0x63,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x2e, +0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4f,0x70, +0x4d,0x6f,0x64,0x65,0x52,0x05,0x4d,0x6f,0x64,0x65, +0x73,0x22,0xc6,0x01,0x0a,0x1a,0x50,0x72,0x6f,0x74, 0x6f,0x62,0x75,0x66,0x45,0x72,0x72,0x6f,0x72,0x49, -0x6e,0x66,0x6f,0x52,0x09,0x45,0x72,0x72,0x6f,0x72, -0x49,0x6e,0x66,0x6f,0x12,0x1c,0x0a,0x09,0x54,0x69, -0x6d,0x65,0x73,0x74,0x61,0x6d,0x70,0x18,0x02,0x20, -0x01,0x28,0x04,0x52,0x09,0x54,0x69,0x6d,0x65,0x73, -0x74,0x61,0x6d,0x70,0x12,0x26,0x0a,0x0e,0x53,0x65, +0x6e,0x66,0x6f,0x54,0x69,0x6d,0x65,0x73,0x74,0x61, +0x6d,0x70,0x12,0x3a,0x0a,0x09,0x45,0x72,0x72,0x6f, +0x72,0x49,0x6e,0x66,0x6f,0x18,0x01,0x20,0x01,0x28, +0x0b,0x32,0x1c,0x2e,0x6d,0x72,0x63,0x2e,0x70,0x72, +0x6f,0x74,0x6f,0x2e,0x50,0x72,0x6f,0x74,0x6f,0x62, +0x75,0x66,0x45,0x72,0x72,0x6f,0x72,0x49,0x6e,0x66, +0x6f,0x52,0x09,0x45,0x72,0x72,0x6f,0x72,0x49,0x6e, +0x66,0x6f,0x12,0x1c,0x0a,0x09,0x54,0x69,0x6d,0x65, +0x73,0x74,0x61,0x6d,0x70,0x18,0x02,0x20,0x01,0x28, +0x04,0x52,0x09,0x54,0x69,0x6d,0x65,0x73,0x74,0x61, +0x6d,0x70,0x12,0x26,0x0a,0x0e,0x53,0x65,0x71,0x75, +0x65,0x6e,0x63,0x65,0x4e,0x75,0x6d,0x62,0x65,0x72, +0x18,0x03,0x20,0x01,0x28,0x05,0x52,0x0e,0x53,0x65, 0x71,0x75,0x65,0x6e,0x63,0x65,0x4e,0x75,0x6d,0x62, -0x65,0x72,0x18,0x03,0x20,0x01,0x28,0x05,0x52,0x0e, -0x53,0x65,0x71,0x75,0x65,0x6e,0x63,0x65,0x4e,0x75, -0x6d,0x62,0x65,0x72,0x12,0x26,0x0a,0x0e,0x4e,0x75, +0x65,0x72,0x12,0x26,0x0a,0x0e,0x4e,0x75,0x6d,0x4f, +0x63,0x63,0x75,0x72,0x72,0x65,0x6e,0x63,0x65,0x73, +0x18,0x04,0x20,0x01,0x28,0x05,0x52,0x0e,0x4e,0x75, 0x6d,0x4f,0x63,0x63,0x75,0x72,0x72,0x65,0x6e,0x63, -0x65,0x73,0x18,0x04,0x20,0x01,0x28,0x05,0x52,0x0e, -0x4e,0x75,0x6d,0x4f,0x63,0x63,0x75,0x72,0x72,0x65, -0x6e,0x63,0x65,0x73,0x22,0x86,0x01,0x0a,0x1c,0x50, -0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x43,0x6f,0x6e, -0x73,0x6f,0x6c,0x65,0x4c,0x69,0x6e,0x65,0x54,0x69, -0x6d,0x65,0x73,0x74,0x61,0x6d,0x70,0x12,0x20,0x0a, -0x0b,0x43,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x4c,0x69, -0x6e,0x65,0x18,0x01,0x20,0x01,0x28,0x09,0x52,0x0b, -0x43,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x4c,0x69,0x6e, -0x65,0x12,0x1c,0x0a,0x09,0x54,0x69,0x6d,0x65,0x73, -0x74,0x61,0x6d,0x70,0x18,0x02,0x20,0x01,0x28,0x04, -0x52,0x09,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,0x6d, -0x70,0x12,0x26,0x0a,0x0e,0x53,0x65,0x71,0x75,0x65, -0x6e,0x63,0x65,0x4e,0x75,0x6d,0x62,0x65,0x72,0x18, -0x03,0x20,0x01,0x28,0x05,0x52,0x0e,0x53,0x65,0x71, -0x75,0x65,0x6e,0x63,0x65,0x4e,0x75,0x6d,0x62,0x65, -0x72,0x42,0x0f,0x0a,0x0d,0x63,0x6f,0x6d,0x2e,0x6d, -0x72,0x63,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x4a,0xef, -0x18,0x0a,0x06,0x12,0x04,0x00,0x00,0x5f,0x01,0x0a, -0x08,0x0a,0x01,0x0c,0x12,0x03,0x00,0x00,0x12,0x0a, -0x08,0x0a,0x01,0x02,0x12,0x03,0x02,0x00,0x12,0x0a, -0x08,0x0a,0x01,0x08,0x12,0x03,0x04,0x00,0x26,0x0a, -0x09,0x0a,0x02,0x08,0x01,0x12,0x03,0x04,0x00,0x26, -0x0a,0x0a,0x0a,0x02,0x04,0x00,0x12,0x04,0x06,0x00, -0x0a,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x00,0x01,0x12, -0x03,0x06,0x08,0x1a,0x0a,0x0b,0x0a,0x04,0x04,0x00, -0x02,0x00,0x12,0x03,0x07,0x04,0x11,0x0a,0x0c,0x0a, -0x05,0x04,0x00,0x02,0x00,0x05,0x12,0x03,0x07,0x04, -0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02,0x00,0x01, -0x12,0x03,0x07,0x0b,0x0c,0x0a,0x0c,0x0a,0x05,0x04, -0x00,0x02,0x00,0x03,0x12,0x03,0x07,0x0f,0x10,0x0a, -0x0b,0x0a,0x04,0x04,0x00,0x02,0x01,0x12,0x03,0x08, -0x04,0x11,0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02,0x01, -0x05,0x12,0x03,0x08,0x04,0x0a,0x0a,0x0c,0x0a,0x05, -0x04,0x00,0x02,0x01,0x01,0x12,0x03,0x08,0x0b,0x0c, -0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02,0x01,0x03,0x12, -0x03,0x08,0x0f,0x10,0x0a,0x0b,0x0a,0x04,0x04,0x00, -0x02,0x02,0x12,0x03,0x09,0x04,0x12,0x0a,0x0c,0x0a, -0x05,0x04,0x00,0x02,0x02,0x05,0x12,0x03,0x09,0x04, -0x08,0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02,0x02,0x01, -0x12,0x03,0x09,0x09,0x0d,0x0a,0x0c,0x0a,0x05,0x04, -0x00,0x02,0x02,0x03,0x12,0x03,0x09,0x10,0x11,0x0a, -0x0a,0x0a,0x02,0x04,0x01,0x12,0x04,0x0c,0x00,0x0e, -0x01,0x0a,0x0a,0x0a,0x03,0x04,0x01,0x01,0x12,0x03, -0x0c,0x08,0x1c,0x0a,0x0b,0x0a,0x04,0x04,0x01,0x02, -0x00,0x12,0x03,0x0d,0x04,0x2c,0x0a,0x0c,0x0a,0x05, -0x04,0x01,0x02,0x00,0x04,0x12,0x03,0x0d,0x04,0x0c, -0x0a,0x0c,0x0a,0x05,0x04,0x01,0x02,0x00,0x06,0x12, -0x03,0x0d,0x0d,0x1f,0x0a,0x0c,0x0a,0x05,0x04,0x01, -0x02,0x00,0x01,0x12,0x03,0x0d,0x20,0x27,0x0a,0x0c, -0x0a,0x05,0x04,0x01,0x02,0x00,0x03,0x12,0x03,0x0d, -0x2a,0x2b,0x0a,0x0a,0x0a,0x02,0x04,0x02,0x12,0x04, -0x10,0x00,0x1a,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x02, -0x01,0x12,0x03,0x10,0x08,0x1c,0x0a,0x0b,0x0a,0x04, -0x04,0x02,0x02,0x00,0x12,0x03,0x11,0x04,0x20,0x0a, -0x0c,0x0a,0x05,0x04,0x02,0x02,0x00,0x05,0x12,0x03, -0x11,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02, -0x00,0x01,0x12,0x03,0x11,0x0b,0x1b,0x0a,0x0c,0x0a, -0x05,0x04,0x02,0x02,0x00,0x03,0x12,0x03,0x11,0x1e, -0x1f,0x0a,0x0b,0x0a,0x04,0x04,0x02,0x02,0x01,0x12, -0x03,0x12,0x04,0x17,0x0a,0x0c,0x0a,0x05,0x04,0x02, -0x02,0x01,0x05,0x12,0x03,0x12,0x04,0x0a,0x0a,0x0c, -0x0a,0x05,0x04,0x02,0x02,0x01,0x01,0x12,0x03,0x12, -0x0b,0x12,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x01, -0x03,0x12,0x03,0x12,0x15,0x16,0x0a,0x0b,0x0a,0x04, -0x04,0x02,0x02,0x02,0x12,0x03,0x13,0x04,0x1d,0x0a, -0x0c,0x0a,0x05,0x04,0x02,0x02,0x02,0x05,0x12,0x03, -0x13,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02, -0x02,0x01,0x12,0x03,0x13,0x0b,0x18,0x0a,0x0c,0x0a, -0x05,0x04,0x02,0x02,0x02,0x03,0x12,0x03,0x13,0x1b, -0x1c,0x0a,0x0b,0x0a,0x04,0x04,0x02,0x02,0x03,0x12, -0x03,0x14,0x04,0x1d,0x0a,0x0c,0x0a,0x05,0x04,0x02, -0x02,0x03,0x04,0x12,0x03,0x14,0x04,0x0c,0x0a,0x0c, -0x0a,0x05,0x04,0x02,0x02,0x03,0x05,0x12,0x03,0x14, -0x0d,0x13,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x03, -0x01,0x12,0x03,0x14,0x14,0x18,0x0a,0x0c,0x0a,0x05, -0x04,0x02,0x02,0x03,0x03,0x12,0x03,0x14,0x1b,0x1c, -0x0a,0x3e,0x0a,0x04,0x04,0x02,0x02,0x04,0x12,0x03, -0x17,0x04,0x18,0x1a,0x31,0x20,0x45,0x61,0x63,0x68, -0x20,0x50,0x4f,0x56,0x20,0x74,0x61,0x6b,0x65,0x73, -0x20,0x75,0x70,0x20,0x34,0x20,0x62,0x69,0x74,0x73, -0x0a,0x20,0x57,0x65,0x20,0x63,0x61,0x6e,0x20,0x66, -0x69,0x74,0x20,0x38,0x20,0x69,0x6e,0x20,0x68,0x65, -0x72,0x65,0x2e,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02, -0x02,0x04,0x05,0x12,0x03,0x17,0x04,0x0a,0x0a,0x0c, -0x0a,0x05,0x04,0x02,0x02,0x04,0x01,0x12,0x03,0x17, -0x0b,0x13,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x04, -0x03,0x12,0x03,0x17,0x16,0x17,0x0a,0x0b,0x0a,0x04, -0x04,0x02,0x02,0x05,0x12,0x03,0x18,0x04,0x14,0x0a, -0x0c,0x0a,0x05,0x04,0x02,0x02,0x05,0x05,0x12,0x03, -0x18,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02, -0x05,0x01,0x12,0x03,0x18,0x0b,0x0f,0x0a,0x0c,0x0a, -0x05,0x04,0x02,0x02,0x05,0x03,0x12,0x03,0x18,0x12, -0x13,0x0a,0x0b,0x0a,0x04,0x04,0x02,0x02,0x06,0x12, -0x03,0x19,0x04,0x30,0x0a,0x0c,0x0a,0x05,0x04,0x02, -0x02,0x06,0x04,0x12,0x03,0x19,0x04,0x0c,0x0a,0x0c, -0x0a,0x05,0x04,0x02,0x02,0x06,0x06,0x12,0x03,0x19, -0x0d,0x21,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x06, -0x01,0x12,0x03,0x19,0x22,0x2b,0x0a,0x0c,0x0a,0x05, -0x04,0x02,0x02,0x06,0x03,0x12,0x03,0x19,0x2e,0x2f, -0x0a,0x0a,0x0a,0x02,0x04,0x03,0x12,0x04,0x1c,0x00, -0x21,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x03,0x01,0x12, -0x03,0x1c,0x08,0x1b,0x0a,0x0b,0x0a,0x04,0x04,0x03, -0x02,0x00,0x12,0x03,0x1d,0x04,0x1b,0x0a,0x0c,0x0a, -0x05,0x04,0x03,0x02,0x00,0x05,0x12,0x03,0x1d,0x04, -0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x00,0x01, -0x12,0x03,0x1d,0x0b,0x16,0x0a,0x0c,0x0a,0x05,0x04, -0x03,0x02,0x00,0x03,0x12,0x03,0x1d,0x19,0x1a,0x0a, -0x0b,0x0a,0x04,0x04,0x03,0x02,0x01,0x12,0x03,0x1e, -0x04,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x01, -0x05,0x12,0x03,0x1e,0x04,0x09,0x0a,0x0c,0x0a,0x05, -0x04,0x03,0x02,0x01,0x01,0x12,0x03,0x1e,0x0a,0x13, -0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x01,0x03,0x12, -0x03,0x1e,0x16,0x17,0x0a,0x0b,0x0a,0x04,0x04,0x03, -0x02,0x02,0x12,0x03,0x1f,0x04,0x30,0x0a,0x0c,0x0a, -0x05,0x04,0x03,0x02,0x02,0x04,0x12,0x03,0x1f,0x04, -0x0c,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x02,0x06, -0x12,0x03,0x1f,0x0d,0x21,0x0a,0x0c,0x0a,0x05,0x04, -0x03,0x02,0x02,0x01,0x12,0x03,0x1f,0x22,0x2b,0x0a, -0x0c,0x0a,0x05,0x04,0x03,0x02,0x02,0x03,0x12,0x03, -0x1f,0x2e,0x2f,0x0a,0x0b,0x0a,0x04,0x04,0x03,0x02, -0x03,0x12,0x03,0x20,0x04,0x1e,0x0a,0x0c,0x0a,0x05, -0x04,0x03,0x02,0x03,0x05,0x12,0x03,0x20,0x04,0x0b, -0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x03,0x01,0x12, -0x03,0x20,0x0c,0x19,0x0a,0x0c,0x0a,0x05,0x04,0x03, -0x02,0x03,0x03,0x12,0x03,0x20,0x1c,0x1d,0x0a,0x0a, -0x0a,0x02,0x04,0x04,0x12,0x04,0x23,0x00,0x28,0x01, -0x0a,0x0a,0x0a,0x03,0x04,0x04,0x01,0x12,0x03,0x23, -0x08,0x22,0x0a,0x0b,0x0a,0x04,0x04,0x04,0x02,0x00, -0x12,0x03,0x24,0x04,0x1c,0x0a,0x0c,0x0a,0x05,0x04, -0x04,0x02,0x00,0x05,0x12,0x03,0x24,0x04,0x0a,0x0a, -0x0c,0x0a,0x05,0x04,0x04,0x02,0x00,0x01,0x12,0x03, -0x24,0x0b,0x17,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02, -0x00,0x03,0x12,0x03,0x24,0x1a,0x1b,0x0a,0x0b,0x0a, -0x04,0x04,0x04,0x02,0x01,0x12,0x03,0x25,0x04,0x17, -0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,0x01,0x05,0x12, -0x03,0x25,0x04,0x08,0x0a,0x0c,0x0a,0x05,0x04,0x04, -0x02,0x01,0x01,0x12,0x03,0x25,0x09,0x12,0x0a,0x0c, -0x0a,0x05,0x04,0x04,0x02,0x01,0x03,0x12,0x03,0x25, -0x15,0x16,0x0a,0x0b,0x0a,0x04,0x04,0x04,0x02,0x02, -0x12,0x03,0x26,0x04,0x1b,0x0a,0x0c,0x0a,0x05,0x04, -0x04,0x02,0x02,0x05,0x12,0x03,0x26,0x04,0x0a,0x0a, -0x0c,0x0a,0x05,0x04,0x04,0x02,0x02,0x01,0x12,0x03, -0x26,0x0b,0x16,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02, -0x02,0x03,0x12,0x03,0x26,0x19,0x1a,0x0a,0x0b,0x0a, -0x04,0x04,0x04,0x02,0x03,0x12,0x03,0x27,0x04,0x20, -0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,0x03,0x05,0x12, -0x03,0x27,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x04, -0x02,0x03,0x01,0x12,0x03,0x27,0x0b,0x1b,0x0a,0x0c, -0x0a,0x05,0x04,0x04,0x02,0x03,0x03,0x12,0x03,0x27, -0x1e,0x1f,0x0a,0x0a,0x0a,0x02,0x04,0x05,0x12,0x04, -0x2a,0x00,0x2c,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x05, -0x01,0x12,0x03,0x2a,0x08,0x23,0x0a,0x0b,0x0a,0x04, -0x04,0x05,0x02,0x00,0x12,0x03,0x2b,0x04,0x38,0x0a, -0x0c,0x0a,0x05,0x04,0x05,0x02,0x00,0x04,0x12,0x03, -0x2b,0x04,0x0c,0x0a,0x0c,0x0a,0x05,0x04,0x05,0x02, -0x00,0x06,0x12,0x03,0x2b,0x0d,0x27,0x0a,0x0c,0x0a, -0x05,0x04,0x05,0x02,0x00,0x01,0x12,0x03,0x2b,0x28, -0x33,0x0a,0x0c,0x0a,0x05,0x04,0x05,0x02,0x00,0x03, -0x12,0x03,0x2b,0x36,0x37,0x0a,0x0a,0x0a,0x02,0x04, -0x06,0x12,0x04,0x2e,0x00,0x32,0x01,0x0a,0x0a,0x0a, -0x03,0x04,0x06,0x01,0x12,0x03,0x2e,0x08,0x1e,0x0a, -0x0b,0x0a,0x04,0x04,0x06,0x02,0x00,0x12,0x03,0x2f, -0x04,0x14,0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02,0x00, -0x05,0x12,0x03,0x2f,0x04,0x0a,0x0a,0x0c,0x0a,0x05, -0x04,0x06,0x02,0x00,0x01,0x12,0x03,0x2f,0x0b,0x0f, -0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02,0x00,0x03,0x12, -0x03,0x2f,0x12,0x13,0x0a,0x2b,0x0a,0x04,0x04,0x06, -0x02,0x01,0x12,0x03,0x30,0x04,0x16,0x22,0x1e,0x20, +0x65,0x73,0x22,0x86,0x01,0x0a,0x1c,0x50,0x72,0x6f, +0x74,0x6f,0x62,0x75,0x66,0x43,0x6f,0x6e,0x73,0x6f, +0x6c,0x65,0x4c,0x69,0x6e,0x65,0x54,0x69,0x6d,0x65, +0x73,0x74,0x61,0x6d,0x70,0x12,0x20,0x0a,0x0b,0x43, +0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x4c,0x69,0x6e,0x65, +0x18,0x01,0x20,0x01,0x28,0x09,0x52,0x0b,0x43,0x6f, +0x6e,0x73,0x6f,0x6c,0x65,0x4c,0x69,0x6e,0x65,0x12, +0x1c,0x0a,0x09,0x54,0x69,0x6d,0x65,0x73,0x74,0x61, +0x6d,0x70,0x18,0x02,0x20,0x01,0x28,0x04,0x52,0x09, +0x54,0x69,0x6d,0x65,0x73,0x74,0x61,0x6d,0x70,0x12, +0x26,0x0a,0x0e,0x53,0x65,0x71,0x75,0x65,0x6e,0x63, +0x65,0x4e,0x75,0x6d,0x62,0x65,0x72,0x18,0x03,0x20, +0x01,0x28,0x05,0x52,0x0e,0x53,0x65,0x71,0x75,0x65, +0x6e,0x63,0x65,0x4e,0x75,0x6d,0x62,0x65,0x72,0x42, +0x0f,0x0a,0x0d,0x63,0x6f,0x6d,0x2e,0x6d,0x72,0x63, +0x2e,0x70,0x72,0x6f,0x74,0x6f,0x4a,0xa6,0x19,0x0a, +0x06,0x12,0x04,0x00,0x00,0x60,0x01,0x0a,0x08,0x0a, +0x01,0x0c,0x12,0x03,0x00,0x00,0x12,0x0a,0x08,0x0a, +0x01,0x02,0x12,0x03,0x02,0x00,0x12,0x0a,0x08,0x0a, +0x01,0x08,0x12,0x03,0x04,0x00,0x26,0x0a,0x09,0x0a, +0x02,0x08,0x01,0x12,0x03,0x04,0x00,0x26,0x0a,0x0a, +0x0a,0x02,0x04,0x00,0x12,0x04,0x06,0x00,0x0a,0x01, +0x0a,0x0a,0x0a,0x03,0x04,0x00,0x01,0x12,0x03,0x06, +0x08,0x1a,0x0a,0x0b,0x0a,0x04,0x04,0x00,0x02,0x00, +0x12,0x03,0x07,0x04,0x11,0x0a,0x0c,0x0a,0x05,0x04, +0x00,0x02,0x00,0x05,0x12,0x03,0x07,0x04,0x0a,0x0a, +0x0c,0x0a,0x05,0x04,0x00,0x02,0x00,0x01,0x12,0x03, +0x07,0x0b,0x0c,0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02, +0x00,0x03,0x12,0x03,0x07,0x0f,0x10,0x0a,0x0b,0x0a, +0x04,0x04,0x00,0x02,0x01,0x12,0x03,0x08,0x04,0x11, +0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02,0x01,0x05,0x12, +0x03,0x08,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x00, +0x02,0x01,0x01,0x12,0x03,0x08,0x0b,0x0c,0x0a,0x0c, +0x0a,0x05,0x04,0x00,0x02,0x01,0x03,0x12,0x03,0x08, +0x0f,0x10,0x0a,0x0b,0x0a,0x04,0x04,0x00,0x02,0x02, +0x12,0x03,0x09,0x04,0x12,0x0a,0x0c,0x0a,0x05,0x04, +0x00,0x02,0x02,0x05,0x12,0x03,0x09,0x04,0x08,0x0a, +0x0c,0x0a,0x05,0x04,0x00,0x02,0x02,0x01,0x12,0x03, +0x09,0x09,0x0d,0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02, +0x02,0x03,0x12,0x03,0x09,0x10,0x11,0x0a,0x0a,0x0a, +0x02,0x04,0x01,0x12,0x04,0x0c,0x00,0x0e,0x01,0x0a, +0x0a,0x0a,0x03,0x04,0x01,0x01,0x12,0x03,0x0c,0x08, +0x1c,0x0a,0x0b,0x0a,0x04,0x04,0x01,0x02,0x00,0x12, +0x03,0x0d,0x04,0x2c,0x0a,0x0c,0x0a,0x05,0x04,0x01, +0x02,0x00,0x04,0x12,0x03,0x0d,0x04,0x0c,0x0a,0x0c, +0x0a,0x05,0x04,0x01,0x02,0x00,0x06,0x12,0x03,0x0d, +0x0d,0x1f,0x0a,0x0c,0x0a,0x05,0x04,0x01,0x02,0x00, +0x01,0x12,0x03,0x0d,0x20,0x27,0x0a,0x0c,0x0a,0x05, +0x04,0x01,0x02,0x00,0x03,0x12,0x03,0x0d,0x2a,0x2b, +0x0a,0x0a,0x0a,0x02,0x04,0x02,0x12,0x04,0x10,0x00, +0x1a,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x02,0x01,0x12, +0x03,0x10,0x08,0x1c,0x0a,0x0b,0x0a,0x04,0x04,0x02, +0x02,0x00,0x12,0x03,0x11,0x04,0x20,0x0a,0x0c,0x0a, +0x05,0x04,0x02,0x02,0x00,0x05,0x12,0x03,0x11,0x04, +0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x00,0x01, +0x12,0x03,0x11,0x0b,0x1b,0x0a,0x0c,0x0a,0x05,0x04, +0x02,0x02,0x00,0x03,0x12,0x03,0x11,0x1e,0x1f,0x0a, +0x0b,0x0a,0x04,0x04,0x02,0x02,0x01,0x12,0x03,0x12, +0x04,0x17,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x01, +0x05,0x12,0x03,0x12,0x04,0x0a,0x0a,0x0c,0x0a,0x05, +0x04,0x02,0x02,0x01,0x01,0x12,0x03,0x12,0x0b,0x12, +0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x01,0x03,0x12, +0x03,0x12,0x15,0x16,0x0a,0x0b,0x0a,0x04,0x04,0x02, +0x02,0x02,0x12,0x03,0x13,0x04,0x1d,0x0a,0x0c,0x0a, +0x05,0x04,0x02,0x02,0x02,0x05,0x12,0x03,0x13,0x04, +0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x02,0x01, +0x12,0x03,0x13,0x0b,0x18,0x0a,0x0c,0x0a,0x05,0x04, +0x02,0x02,0x02,0x03,0x12,0x03,0x13,0x1b,0x1c,0x0a, +0x0b,0x0a,0x04,0x04,0x02,0x02,0x03,0x12,0x03,0x14, +0x04,0x1d,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x03, +0x04,0x12,0x03,0x14,0x04,0x0c,0x0a,0x0c,0x0a,0x05, +0x04,0x02,0x02,0x03,0x05,0x12,0x03,0x14,0x0d,0x13, +0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x03,0x01,0x12, +0x03,0x14,0x14,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x02, +0x02,0x03,0x03,0x12,0x03,0x14,0x1b,0x1c,0x0a,0x3e, +0x0a,0x04,0x04,0x02,0x02,0x04,0x12,0x03,0x17,0x04, +0x18,0x1a,0x31,0x20,0x45,0x61,0x63,0x68,0x20,0x50, +0x4f,0x56,0x20,0x74,0x61,0x6b,0x65,0x73,0x20,0x75, +0x70,0x20,0x34,0x20,0x62,0x69,0x74,0x73,0x0a,0x20, +0x57,0x65,0x20,0x63,0x61,0x6e,0x20,0x66,0x69,0x74, +0x20,0x38,0x20,0x69,0x6e,0x20,0x68,0x65,0x72,0x65, +0x2e,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x04, +0x05,0x12,0x03,0x17,0x04,0x0a,0x0a,0x0c,0x0a,0x05, +0x04,0x02,0x02,0x04,0x01,0x12,0x03,0x17,0x0b,0x13, +0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x04,0x03,0x12, +0x03,0x17,0x16,0x17,0x0a,0x0b,0x0a,0x04,0x04,0x02, +0x02,0x05,0x12,0x03,0x18,0x04,0x14,0x0a,0x0c,0x0a, +0x05,0x04,0x02,0x02,0x05,0x05,0x12,0x03,0x18,0x04, +0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x05,0x01, +0x12,0x03,0x18,0x0b,0x0f,0x0a,0x0c,0x0a,0x05,0x04, +0x02,0x02,0x05,0x03,0x12,0x03,0x18,0x12,0x13,0x0a, +0x0b,0x0a,0x04,0x04,0x02,0x02,0x06,0x12,0x03,0x19, +0x04,0x30,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x06, +0x04,0x12,0x03,0x19,0x04,0x0c,0x0a,0x0c,0x0a,0x05, +0x04,0x02,0x02,0x06,0x06,0x12,0x03,0x19,0x0d,0x21, +0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x06,0x01,0x12, +0x03,0x19,0x22,0x2b,0x0a,0x0c,0x0a,0x05,0x04,0x02, +0x02,0x06,0x03,0x12,0x03,0x19,0x2e,0x2f,0x0a,0x0a, +0x0a,0x02,0x04,0x03,0x12,0x04,0x1c,0x00,0x22,0x01, +0x0a,0x0a,0x0a,0x03,0x04,0x03,0x01,0x12,0x03,0x1c, +0x08,0x1b,0x0a,0x0b,0x0a,0x04,0x04,0x03,0x02,0x00, +0x12,0x03,0x1d,0x04,0x1b,0x0a,0x0c,0x0a,0x05,0x04, +0x03,0x02,0x00,0x05,0x12,0x03,0x1d,0x04,0x0a,0x0a, +0x0c,0x0a,0x05,0x04,0x03,0x02,0x00,0x01,0x12,0x03, +0x1d,0x0b,0x16,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02, +0x00,0x03,0x12,0x03,0x1d,0x19,0x1a,0x0a,0x0b,0x0a, +0x04,0x04,0x03,0x02,0x01,0x12,0x03,0x1e,0x04,0x18, +0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x01,0x05,0x12, +0x03,0x1e,0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04,0x03, +0x02,0x01,0x01,0x12,0x03,0x1e,0x0a,0x13,0x0a,0x0c, +0x0a,0x05,0x04,0x03,0x02,0x01,0x03,0x12,0x03,0x1e, +0x16,0x17,0x0a,0x0b,0x0a,0x04,0x04,0x03,0x02,0x02, +0x12,0x03,0x1f,0x04,0x30,0x0a,0x0c,0x0a,0x05,0x04, +0x03,0x02,0x02,0x04,0x12,0x03,0x1f,0x04,0x0c,0x0a, +0x0c,0x0a,0x05,0x04,0x03,0x02,0x02,0x06,0x12,0x03, +0x1f,0x0d,0x21,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02, +0x02,0x01,0x12,0x03,0x1f,0x22,0x2b,0x0a,0x0c,0x0a, +0x05,0x04,0x03,0x02,0x02,0x03,0x12,0x03,0x1f,0x2e, +0x2f,0x0a,0x0b,0x0a,0x04,0x04,0x03,0x02,0x03,0x12, +0x03,0x20,0x04,0x1e,0x0a,0x0c,0x0a,0x05,0x04,0x03, +0x02,0x03,0x05,0x12,0x03,0x20,0x04,0x0b,0x0a,0x0c, +0x0a,0x05,0x04,0x03,0x02,0x03,0x01,0x12,0x03,0x20, +0x0c,0x19,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x03, +0x03,0x12,0x03,0x20,0x1c,0x1d,0x0a,0x0b,0x0a,0x04, +0x04,0x03,0x02,0x04,0x12,0x03,0x21,0x04,0x18,0x0a, +0x0c,0x0a,0x05,0x04,0x03,0x02,0x04,0x05,0x12,0x03, +0x21,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02, +0x04,0x01,0x12,0x03,0x21,0x0b,0x13,0x0a,0x0c,0x0a, +0x05,0x04,0x03,0x02,0x04,0x03,0x12,0x03,0x21,0x16, +0x17,0x0a,0x0a,0x0a,0x02,0x04,0x04,0x12,0x04,0x24, +0x00,0x29,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x04,0x01, +0x12,0x03,0x24,0x08,0x22,0x0a,0x0b,0x0a,0x04,0x04, +0x04,0x02,0x00,0x12,0x03,0x25,0x04,0x1c,0x0a,0x0c, +0x0a,0x05,0x04,0x04,0x02,0x00,0x05,0x12,0x03,0x25, +0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,0x00, +0x01,0x12,0x03,0x25,0x0b,0x17,0x0a,0x0c,0x0a,0x05, +0x04,0x04,0x02,0x00,0x03,0x12,0x03,0x25,0x1a,0x1b, +0x0a,0x0b,0x0a,0x04,0x04,0x04,0x02,0x01,0x12,0x03, +0x26,0x04,0x17,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02, +0x01,0x05,0x12,0x03,0x26,0x04,0x08,0x0a,0x0c,0x0a, +0x05,0x04,0x04,0x02,0x01,0x01,0x12,0x03,0x26,0x09, +0x12,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,0x01,0x03, +0x12,0x03,0x26,0x15,0x16,0x0a,0x0b,0x0a,0x04,0x04, +0x04,0x02,0x02,0x12,0x03,0x27,0x04,0x1b,0x0a,0x0c, +0x0a,0x05,0x04,0x04,0x02,0x02,0x05,0x12,0x03,0x27, +0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,0x02, +0x01,0x12,0x03,0x27,0x0b,0x16,0x0a,0x0c,0x0a,0x05, +0x04,0x04,0x02,0x02,0x03,0x12,0x03,0x27,0x19,0x1a, +0x0a,0x0b,0x0a,0x04,0x04,0x04,0x02,0x03,0x12,0x03, +0x28,0x04,0x20,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02, +0x03,0x05,0x12,0x03,0x28,0x04,0x0a,0x0a,0x0c,0x0a, +0x05,0x04,0x04,0x02,0x03,0x01,0x12,0x03,0x28,0x0b, +0x1b,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,0x03,0x03, +0x12,0x03,0x28,0x1e,0x1f,0x0a,0x0a,0x0a,0x02,0x04, +0x05,0x12,0x04,0x2b,0x00,0x2d,0x01,0x0a,0x0a,0x0a, +0x03,0x04,0x05,0x01,0x12,0x03,0x2b,0x08,0x23,0x0a, +0x0b,0x0a,0x04,0x04,0x05,0x02,0x00,0x12,0x03,0x2c, +0x04,0x38,0x0a,0x0c,0x0a,0x05,0x04,0x05,0x02,0x00, +0x04,0x12,0x03,0x2c,0x04,0x0c,0x0a,0x0c,0x0a,0x05, +0x04,0x05,0x02,0x00,0x06,0x12,0x03,0x2c,0x0d,0x27, +0x0a,0x0c,0x0a,0x05,0x04,0x05,0x02,0x00,0x01,0x12, +0x03,0x2c,0x28,0x33,0x0a,0x0c,0x0a,0x05,0x04,0x05, +0x02,0x00,0x03,0x12,0x03,0x2c,0x36,0x37,0x0a,0x0a, +0x0a,0x02,0x04,0x06,0x12,0x04,0x2f,0x00,0x33,0x01, +0x0a,0x0a,0x0a,0x03,0x04,0x06,0x01,0x12,0x03,0x2f, +0x08,0x1e,0x0a,0x0b,0x0a,0x04,0x04,0x06,0x02,0x00, +0x12,0x03,0x30,0x04,0x14,0x0a,0x0c,0x0a,0x05,0x04, +0x06,0x02,0x00,0x05,0x12,0x03,0x30,0x04,0x0a,0x0a, +0x0c,0x0a,0x05,0x04,0x06,0x02,0x00,0x01,0x12,0x03, +0x30,0x0b,0x0f,0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02, +0x00,0x03,0x12,0x03,0x30,0x12,0x13,0x0a,0x2b,0x0a, +0x04,0x04,0x06,0x02,0x01,0x12,0x03,0x31,0x04,0x16, +0x22,0x1e,0x20,0x31,0x36,0x20,0x62,0x69,0x74,0x73, +0x2c,0x20,0x6c,0x65,0x66,0x74,0x20,0x6d,0x73,0x62, +0x2c,0x20,0x72,0x69,0x67,0x68,0x74,0x20,0x6c,0x73, +0x62,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02,0x01, +0x05,0x12,0x03,0x31,0x04,0x0a,0x0a,0x0c,0x0a,0x05, +0x04,0x06,0x02,0x01,0x01,0x12,0x03,0x31,0x0b,0x11, +0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02,0x01,0x03,0x12, +0x03,0x31,0x14,0x15,0x0a,0x2b,0x0a,0x04,0x04,0x06, +0x02,0x02,0x12,0x03,0x32,0x04,0x1d,0x22,0x1e,0x20, 0x31,0x36,0x20,0x62,0x69,0x74,0x73,0x2c,0x20,0x6c, 0x65,0x66,0x74,0x20,0x6d,0x73,0x62,0x2c,0x20,0x72, 0x69,0x67,0x68,0x74,0x20,0x6c,0x73,0x62,0x0a,0x0a, -0x0c,0x0a,0x05,0x04,0x06,0x02,0x01,0x05,0x12,0x03, -0x30,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02, -0x01,0x01,0x12,0x03,0x30,0x0b,0x11,0x0a,0x0c,0x0a, -0x05,0x04,0x06,0x02,0x01,0x03,0x12,0x03,0x30,0x14, -0x15,0x0a,0x2b,0x0a,0x04,0x04,0x06,0x02,0x02,0x12, -0x03,0x31,0x04,0x1d,0x22,0x1e,0x20,0x31,0x36,0x20, -0x62,0x69,0x74,0x73,0x2c,0x20,0x6c,0x65,0x66,0x74, -0x20,0x6d,0x73,0x62,0x2c,0x20,0x72,0x69,0x67,0x68, -0x74,0x20,0x6c,0x73,0x62,0x0a,0x0a,0x0c,0x0a,0x05, -0x04,0x06,0x02,0x02,0x05,0x12,0x03,0x31,0x04,0x0a, -0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02,0x02,0x01,0x12, -0x03,0x31,0x0b,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x06, -0x02,0x02,0x03,0x12,0x03,0x31,0x1b,0x1c,0x0a,0x0a, -0x0a,0x02,0x04,0x07,0x12,0x04,0x34,0x00,0x36,0x01, -0x0a,0x0a,0x0a,0x03,0x04,0x07,0x01,0x12,0x03,0x34, -0x08,0x1f,0x0a,0x0b,0x0a,0x04,0x04,0x07,0x02,0x00, -0x12,0x03,0x35,0x04,0x30,0x0a,0x0c,0x0a,0x05,0x04, -0x07,0x02,0x00,0x04,0x12,0x03,0x35,0x04,0x0c,0x0a, -0x0c,0x0a,0x05,0x04,0x07,0x02,0x00,0x06,0x12,0x03, -0x35,0x0d,0x23,0x0a,0x0c,0x0a,0x05,0x04,0x07,0x02, -0x00,0x01,0x12,0x03,0x35,0x24,0x2b,0x0a,0x0c,0x0a, -0x05,0x04,0x07,0x02,0x00,0x03,0x12,0x03,0x35,0x2e, -0x2f,0x0a,0x0a,0x0a,0x02,0x04,0x08,0x12,0x04,0x38, -0x00,0x3d,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x08,0x01, -0x12,0x03,0x38,0x08,0x19,0x0a,0x0b,0x0a,0x04,0x04, -0x08,0x02,0x00,0x12,0x03,0x39,0x04,0x19,0x0a,0x0c, -0x0a,0x05,0x04,0x08,0x02,0x00,0x05,0x12,0x03,0x39, -0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x00, -0x01,0x12,0x03,0x39,0x0b,0x14,0x0a,0x0c,0x0a,0x05, -0x04,0x08,0x02,0x00,0x03,0x12,0x03,0x39,0x17,0x18, -0x0a,0x0b,0x0a,0x04,0x04,0x08,0x02,0x01,0x12,0x03, -0x3a,0x04,0x1a,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02, -0x01,0x05,0x12,0x03,0x3a,0x04,0x09,0x0a,0x0c,0x0a, -0x05,0x04,0x08,0x02,0x01,0x01,0x12,0x03,0x3a,0x0a, -0x15,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x01,0x03, -0x12,0x03,0x3a,0x18,0x19,0x0a,0x0b,0x0a,0x04,0x04, -0x08,0x02,0x02,0x12,0x03,0x3b,0x04,0x1b,0x0a,0x0c, -0x0a,0x05,0x04,0x08,0x02,0x02,0x05,0x12,0x03,0x3b, -0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x02, -0x01,0x12,0x03,0x3b,0x0a,0x16,0x0a,0x0c,0x0a,0x05, -0x04,0x08,0x02,0x02,0x03,0x12,0x03,0x3b,0x19,0x1a, -0x0a,0x0b,0x0a,0x04,0x04,0x08,0x02,0x03,0x12,0x03, -0x3c,0x04,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02, -0x03,0x05,0x12,0x03,0x3c,0x04,0x09,0x0a,0x0c,0x0a, -0x05,0x04,0x08,0x02,0x03,0x01,0x12,0x03,0x3c,0x0a, -0x13,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x03,0x03, -0x12,0x03,0x3c,0x16,0x17,0x0a,0x0a,0x0a,0x02,0x04, -0x09,0x12,0x04,0x3f,0x00,0x45,0x01,0x0a,0x0a,0x0a, -0x03,0x04,0x09,0x01,0x12,0x03,0x3f,0x08,0x19,0x0a, -0x0b,0x0a,0x04,0x04,0x09,0x02,0x00,0x12,0x03,0x40, -0x04,0x15,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x00, -0x05,0x12,0x03,0x40,0x04,0x08,0x0a,0x0c,0x0a,0x05, -0x04,0x09,0x02,0x00,0x01,0x12,0x03,0x40,0x09,0x10, -0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x00,0x03,0x12, -0x03,0x40,0x13,0x14,0x0a,0x0b,0x0a,0x04,0x04,0x09, -0x02,0x01,0x12,0x03,0x41,0x04,0x19,0x0a,0x0c,0x0a, -0x05,0x04,0x09,0x02,0x01,0x05,0x12,0x03,0x41,0x04, -0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x01,0x01, -0x12,0x03,0x41,0x0b,0x14,0x0a,0x0c,0x0a,0x05,0x04, -0x09,0x02,0x01,0x03,0x12,0x03,0x41,0x17,0x18,0x0a, -0x0b,0x0a,0x04,0x04,0x09,0x02,0x02,0x12,0x03,0x42, -0x04,0x17,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x02, -0x05,0x12,0x03,0x42,0x04,0x0a,0x0a,0x0c,0x0a,0x05, -0x04,0x09,0x02,0x02,0x01,0x12,0x03,0x42,0x0b,0x12, -0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x02,0x03,0x12, -0x03,0x42,0x15,0x16,0x0a,0x0b,0x0a,0x04,0x04,0x09, -0x02,0x03,0x12,0x03,0x43,0x04,0x18,0x0a,0x0c,0x0a, -0x05,0x04,0x09,0x02,0x03,0x05,0x12,0x03,0x43,0x04, -0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x03,0x01, -0x12,0x03,0x43,0x0b,0x13,0x0a,0x0c,0x0a,0x05,0x04, -0x09,0x02,0x03,0x03,0x12,0x03,0x43,0x16,0x17,0x0a, -0x0b,0x0a,0x04,0x04,0x09,0x02,0x04,0x12,0x03,0x44, -0x04,0x19,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x04, -0x05,0x12,0x03,0x44,0x04,0x0a,0x0a,0x0c,0x0a,0x05, -0x04,0x09,0x02,0x04,0x01,0x12,0x03,0x44,0x0b,0x14, -0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x04,0x03,0x12, -0x03,0x44,0x17,0x18,0x0a,0x0a,0x0a,0x02,0x04,0x0a, -0x12,0x04,0x47,0x00,0x4e,0x01,0x0a,0x0a,0x0a,0x03, -0x04,0x0a,0x01,0x12,0x03,0x47,0x08,0x16,0x0a,0x0b, -0x0a,0x04,0x04,0x0a,0x02,0x00,0x12,0x03,0x48,0x04, -0x15,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x00,0x05, -0x12,0x03,0x48,0x04,0x0b,0x0a,0x0c,0x0a,0x05,0x04, -0x0a,0x02,0x00,0x01,0x12,0x03,0x48,0x0c,0x10,0x0a, -0x0c,0x0a,0x05,0x04,0x0a,0x02,0x00,0x03,0x12,0x03, -0x48,0x13,0x14,0x0a,0x0b,0x0a,0x04,0x04,0x0a,0x02, -0x01,0x12,0x03,0x49,0x04,0x14,0x0a,0x0c,0x0a,0x05, -0x04,0x0a,0x02,0x01,0x05,0x12,0x03,0x49,0x04,0x0a, -0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x01,0x01,0x12, -0x03,0x49,0x0b,0x0f,0x0a,0x0c,0x0a,0x05,0x04,0x0a, -0x02,0x01,0x03,0x12,0x03,0x49,0x12,0x13,0x0a,0x0b, -0x0a,0x04,0x04,0x0a,0x02,0x02,0x12,0x03,0x4a,0x04, -0x15,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x02,0x05, -0x12,0x03,0x4a,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04, -0x0a,0x02,0x02,0x01,0x12,0x03,0x4a,0x0b,0x10,0x0a, -0x0c,0x0a,0x05,0x04,0x0a,0x02,0x02,0x03,0x12,0x03, -0x4a,0x13,0x14,0x0a,0x0b,0x0a,0x04,0x04,0x0a,0x02, -0x03,0x12,0x03,0x4b,0x04,0x1b,0x0a,0x0c,0x0a,0x05, -0x04,0x0a,0x02,0x03,0x05,0x12,0x03,0x4b,0x04,0x0a, -0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x03,0x01,0x12, -0x03,0x4b,0x0b,0x16,0x0a,0x0c,0x0a,0x05,0x04,0x0a, -0x02,0x03,0x03,0x12,0x03,0x4b,0x19,0x1a,0x0a,0x0b, -0x0a,0x04,0x04,0x0a,0x02,0x04,0x12,0x03,0x4c,0x04, -0x18,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x04,0x05, -0x12,0x03,0x4c,0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04, -0x0a,0x02,0x04,0x01,0x12,0x03,0x4c,0x0a,0x13,0x0a, -0x0c,0x0a,0x05,0x04,0x0a,0x02,0x04,0x03,0x12,0x03, -0x4c,0x16,0x17,0x0a,0x0b,0x0a,0x04,0x04,0x0a,0x02, -0x05,0x12,0x03,0x4d,0x04,0x1e,0x0a,0x0c,0x0a,0x05, -0x04,0x0a,0x02,0x05,0x05,0x12,0x03,0x4d,0x04,0x09, -0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x05,0x01,0x12, -0x03,0x4d,0x0a,0x19,0x0a,0x0c,0x0a,0x05,0x04,0x0a, -0x02,0x05,0x03,0x12,0x03,0x4d,0x1c,0x1d,0x0a,0x0a, -0x0a,0x02,0x04,0x0b,0x12,0x04,0x50,0x00,0x52,0x01, -0x0a,0x0a,0x0a,0x03,0x04,0x0b,0x01,0x12,0x03,0x50, -0x08,0x20,0x0a,0x0b,0x0a,0x04,0x04,0x0b,0x02,0x00, -0x12,0x03,0x51,0x04,0x26,0x0a,0x0c,0x0a,0x05,0x04, -0x0b,0x02,0x00,0x04,0x12,0x03,0x51,0x04,0x0c,0x0a, -0x0c,0x0a,0x05,0x04,0x0b,0x02,0x00,0x06,0x12,0x03, -0x51,0x0d,0x1b,0x0a,0x0c,0x0a,0x05,0x04,0x0b,0x02, -0x00,0x01,0x12,0x03,0x51,0x1c,0x21,0x0a,0x0c,0x0a, -0x05,0x04,0x0b,0x02,0x00,0x03,0x12,0x03,0x51,0x24, -0x25,0x0a,0x0a,0x0a,0x02,0x04,0x0c,0x12,0x04,0x54, -0x00,0x59,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x0c,0x01, -0x12,0x03,0x54,0x08,0x22,0x0a,0x0b,0x0a,0x04,0x04, -0x0c,0x02,0x00,0x12,0x03,0x55,0x04,0x24,0x0a,0x0c, -0x0a,0x05,0x04,0x0c,0x02,0x00,0x06,0x12,0x03,0x55, -0x04,0x15,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x00, -0x01,0x12,0x03,0x55,0x16,0x1f,0x0a,0x0c,0x0a,0x05, -0x04,0x0c,0x02,0x00,0x03,0x12,0x03,0x55,0x22,0x23, -0x0a,0x0b,0x0a,0x04,0x04,0x0c,0x02,0x01,0x12,0x03, -0x56,0x04,0x19,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02, -0x01,0x05,0x12,0x03,0x56,0x04,0x0a,0x0a,0x0c,0x0a, -0x05,0x04,0x0c,0x02,0x01,0x01,0x12,0x03,0x56,0x0b, -0x14,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x01,0x03, -0x12,0x03,0x56,0x17,0x18,0x0a,0x0b,0x0a,0x04,0x04, -0x0c,0x02,0x02,0x12,0x03,0x57,0x04,0x1d,0x0a,0x0c, -0x0a,0x05,0x04,0x0c,0x02,0x02,0x05,0x12,0x03,0x57, -0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x02, -0x01,0x12,0x03,0x57,0x0a,0x18,0x0a,0x0c,0x0a,0x05, -0x04,0x0c,0x02,0x02,0x03,0x12,0x03,0x57,0x1b,0x1c, -0x0a,0x0b,0x0a,0x04,0x04,0x0c,0x02,0x03,0x12,0x03, -0x58,0x04,0x1d,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02, -0x03,0x05,0x12,0x03,0x58,0x04,0x09,0x0a,0x0c,0x0a, -0x05,0x04,0x0c,0x02,0x03,0x01,0x12,0x03,0x58,0x0a, -0x18,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x03,0x03, -0x12,0x03,0x58,0x1b,0x1c,0x0a,0x0a,0x0a,0x02,0x04, -0x0d,0x12,0x04,0x5b,0x00,0x5f,0x01,0x0a,0x0a,0x0a, -0x03,0x04,0x0d,0x01,0x12,0x03,0x5b,0x08,0x24,0x0a, -0x0b,0x0a,0x04,0x04,0x0d,0x02,0x00,0x12,0x03,0x5c, -0x04,0x1b,0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,0x00, -0x05,0x12,0x03,0x5c,0x04,0x0a,0x0a,0x0c,0x0a,0x05, -0x04,0x0d,0x02,0x00,0x01,0x12,0x03,0x5c,0x0b,0x16, -0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,0x00,0x03,0x12, -0x03,0x5c,0x19,0x1a,0x0a,0x0b,0x0a,0x04,0x04,0x0d, -0x02,0x01,0x12,0x03,0x5d,0x04,0x19,0x0a,0x0c,0x0a, -0x05,0x04,0x0d,0x02,0x01,0x05,0x12,0x03,0x5d,0x04, -0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,0x01,0x01, -0x12,0x03,0x5d,0x0b,0x14,0x0a,0x0c,0x0a,0x05,0x04, -0x0d,0x02,0x01,0x03,0x12,0x03,0x5d,0x17,0x18,0x0a, -0x0b,0x0a,0x04,0x04,0x0d,0x02,0x02,0x12,0x03,0x5e, -0x04,0x1d,0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,0x02, -0x05,0x12,0x03,0x5e,0x04,0x09,0x0a,0x0c,0x0a,0x05, -0x04,0x0d,0x02,0x02,0x01,0x12,0x03,0x5e,0x0a,0x18, -0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,0x02,0x03,0x12, -0x03,0x5e,0x1b,0x1c,0x62,0x06,0x70,0x72,0x6f,0x74, -0x6f,0x33, +0x0c,0x0a,0x05,0x04,0x06,0x02,0x02,0x05,0x12,0x03, +0x32,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02, +0x02,0x01,0x12,0x03,0x32,0x0b,0x18,0x0a,0x0c,0x0a, +0x05,0x04,0x06,0x02,0x02,0x03,0x12,0x03,0x32,0x1b, +0x1c,0x0a,0x0a,0x0a,0x02,0x04,0x07,0x12,0x04,0x35, +0x00,0x37,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x07,0x01, +0x12,0x03,0x35,0x08,0x1f,0x0a,0x0b,0x0a,0x04,0x04, +0x07,0x02,0x00,0x12,0x03,0x36,0x04,0x30,0x0a,0x0c, +0x0a,0x05,0x04,0x07,0x02,0x00,0x04,0x12,0x03,0x36, +0x04,0x0c,0x0a,0x0c,0x0a,0x05,0x04,0x07,0x02,0x00, +0x06,0x12,0x03,0x36,0x0d,0x23,0x0a,0x0c,0x0a,0x05, +0x04,0x07,0x02,0x00,0x01,0x12,0x03,0x36,0x24,0x2b, +0x0a,0x0c,0x0a,0x05,0x04,0x07,0x02,0x00,0x03,0x12, +0x03,0x36,0x2e,0x2f,0x0a,0x0a,0x0a,0x02,0x04,0x08, +0x12,0x04,0x39,0x00,0x3e,0x01,0x0a,0x0a,0x0a,0x03, +0x04,0x08,0x01,0x12,0x03,0x39,0x08,0x19,0x0a,0x0b, +0x0a,0x04,0x04,0x08,0x02,0x00,0x12,0x03,0x3a,0x04, +0x19,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x00,0x05, +0x12,0x03,0x3a,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04, +0x08,0x02,0x00,0x01,0x12,0x03,0x3a,0x0b,0x14,0x0a, +0x0c,0x0a,0x05,0x04,0x08,0x02,0x00,0x03,0x12,0x03, +0x3a,0x17,0x18,0x0a,0x0b,0x0a,0x04,0x04,0x08,0x02, +0x01,0x12,0x03,0x3b,0x04,0x1a,0x0a,0x0c,0x0a,0x05, +0x04,0x08,0x02,0x01,0x05,0x12,0x03,0x3b,0x04,0x09, +0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x01,0x01,0x12, +0x03,0x3b,0x0a,0x15,0x0a,0x0c,0x0a,0x05,0x04,0x08, +0x02,0x01,0x03,0x12,0x03,0x3b,0x18,0x19,0x0a,0x0b, +0x0a,0x04,0x04,0x08,0x02,0x02,0x12,0x03,0x3c,0x04, +0x1b,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x02,0x05, +0x12,0x03,0x3c,0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04, +0x08,0x02,0x02,0x01,0x12,0x03,0x3c,0x0a,0x16,0x0a, +0x0c,0x0a,0x05,0x04,0x08,0x02,0x02,0x03,0x12,0x03, +0x3c,0x19,0x1a,0x0a,0x0b,0x0a,0x04,0x04,0x08,0x02, +0x03,0x12,0x03,0x3d,0x04,0x18,0x0a,0x0c,0x0a,0x05, +0x04,0x08,0x02,0x03,0x05,0x12,0x03,0x3d,0x04,0x09, +0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x03,0x01,0x12, +0x03,0x3d,0x0a,0x13,0x0a,0x0c,0x0a,0x05,0x04,0x08, +0x02,0x03,0x03,0x12,0x03,0x3d,0x16,0x17,0x0a,0x0a, +0x0a,0x02,0x04,0x09,0x12,0x04,0x40,0x00,0x46,0x01, +0x0a,0x0a,0x0a,0x03,0x04,0x09,0x01,0x12,0x03,0x40, +0x08,0x19,0x0a,0x0b,0x0a,0x04,0x04,0x09,0x02,0x00, +0x12,0x03,0x41,0x04,0x15,0x0a,0x0c,0x0a,0x05,0x04, +0x09,0x02,0x00,0x05,0x12,0x03,0x41,0x04,0x08,0x0a, +0x0c,0x0a,0x05,0x04,0x09,0x02,0x00,0x01,0x12,0x03, +0x41,0x09,0x10,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02, +0x00,0x03,0x12,0x03,0x41,0x13,0x14,0x0a,0x0b,0x0a, +0x04,0x04,0x09,0x02,0x01,0x12,0x03,0x42,0x04,0x19, +0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x01,0x05,0x12, +0x03,0x42,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x09, +0x02,0x01,0x01,0x12,0x03,0x42,0x0b,0x14,0x0a,0x0c, +0x0a,0x05,0x04,0x09,0x02,0x01,0x03,0x12,0x03,0x42, +0x17,0x18,0x0a,0x0b,0x0a,0x04,0x04,0x09,0x02,0x02, +0x12,0x03,0x43,0x04,0x17,0x0a,0x0c,0x0a,0x05,0x04, +0x09,0x02,0x02,0x05,0x12,0x03,0x43,0x04,0x0a,0x0a, +0x0c,0x0a,0x05,0x04,0x09,0x02,0x02,0x01,0x12,0x03, +0x43,0x0b,0x12,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02, +0x02,0x03,0x12,0x03,0x43,0x15,0x16,0x0a,0x0b,0x0a, +0x04,0x04,0x09,0x02,0x03,0x12,0x03,0x44,0x04,0x18, +0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x03,0x05,0x12, +0x03,0x44,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x09, +0x02,0x03,0x01,0x12,0x03,0x44,0x0b,0x13,0x0a,0x0c, +0x0a,0x05,0x04,0x09,0x02,0x03,0x03,0x12,0x03,0x44, +0x16,0x17,0x0a,0x0b,0x0a,0x04,0x04,0x09,0x02,0x04, +0x12,0x03,0x45,0x04,0x19,0x0a,0x0c,0x0a,0x05,0x04, +0x09,0x02,0x04,0x05,0x12,0x03,0x45,0x04,0x0a,0x0a, +0x0c,0x0a,0x05,0x04,0x09,0x02,0x04,0x01,0x12,0x03, +0x45,0x0b,0x14,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02, +0x04,0x03,0x12,0x03,0x45,0x17,0x18,0x0a,0x0a,0x0a, +0x02,0x04,0x0a,0x12,0x04,0x48,0x00,0x4f,0x01,0x0a, +0x0a,0x0a,0x03,0x04,0x0a,0x01,0x12,0x03,0x48,0x08, +0x16,0x0a,0x0b,0x0a,0x04,0x04,0x0a,0x02,0x00,0x12, +0x03,0x49,0x04,0x15,0x0a,0x0c,0x0a,0x05,0x04,0x0a, +0x02,0x00,0x05,0x12,0x03,0x49,0x04,0x0b,0x0a,0x0c, +0x0a,0x05,0x04,0x0a,0x02,0x00,0x01,0x12,0x03,0x49, +0x0c,0x10,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x00, +0x03,0x12,0x03,0x49,0x13,0x14,0x0a,0x0b,0x0a,0x04, +0x04,0x0a,0x02,0x01,0x12,0x03,0x4a,0x04,0x14,0x0a, +0x0c,0x0a,0x05,0x04,0x0a,0x02,0x01,0x05,0x12,0x03, +0x4a,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02, +0x01,0x01,0x12,0x03,0x4a,0x0b,0x0f,0x0a,0x0c,0x0a, +0x05,0x04,0x0a,0x02,0x01,0x03,0x12,0x03,0x4a,0x12, +0x13,0x0a,0x0b,0x0a,0x04,0x04,0x0a,0x02,0x02,0x12, +0x03,0x4b,0x04,0x15,0x0a,0x0c,0x0a,0x05,0x04,0x0a, +0x02,0x02,0x05,0x12,0x03,0x4b,0x04,0x0a,0x0a,0x0c, +0x0a,0x05,0x04,0x0a,0x02,0x02,0x01,0x12,0x03,0x4b, +0x0b,0x10,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x02, +0x03,0x12,0x03,0x4b,0x13,0x14,0x0a,0x0b,0x0a,0x04, +0x04,0x0a,0x02,0x03,0x12,0x03,0x4c,0x04,0x1b,0x0a, +0x0c,0x0a,0x05,0x04,0x0a,0x02,0x03,0x05,0x12,0x03, +0x4c,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02, +0x03,0x01,0x12,0x03,0x4c,0x0b,0x16,0x0a,0x0c,0x0a, +0x05,0x04,0x0a,0x02,0x03,0x03,0x12,0x03,0x4c,0x19, +0x1a,0x0a,0x0b,0x0a,0x04,0x04,0x0a,0x02,0x04,0x12, +0x03,0x4d,0x04,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x0a, +0x02,0x04,0x05,0x12,0x03,0x4d,0x04,0x09,0x0a,0x0c, +0x0a,0x05,0x04,0x0a,0x02,0x04,0x01,0x12,0x03,0x4d, +0x0a,0x13,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x04, +0x03,0x12,0x03,0x4d,0x16,0x17,0x0a,0x0b,0x0a,0x04, +0x04,0x0a,0x02,0x05,0x12,0x03,0x4e,0x04,0x1e,0x0a, +0x0c,0x0a,0x05,0x04,0x0a,0x02,0x05,0x05,0x12,0x03, +0x4e,0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02, +0x05,0x01,0x12,0x03,0x4e,0x0a,0x19,0x0a,0x0c,0x0a, +0x05,0x04,0x0a,0x02,0x05,0x03,0x12,0x03,0x4e,0x1c, +0x1d,0x0a,0x0a,0x0a,0x02,0x04,0x0b,0x12,0x04,0x51, +0x00,0x53,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x0b,0x01, +0x12,0x03,0x51,0x08,0x20,0x0a,0x0b,0x0a,0x04,0x04, +0x0b,0x02,0x00,0x12,0x03,0x52,0x04,0x26,0x0a,0x0c, +0x0a,0x05,0x04,0x0b,0x02,0x00,0x04,0x12,0x03,0x52, +0x04,0x0c,0x0a,0x0c,0x0a,0x05,0x04,0x0b,0x02,0x00, +0x06,0x12,0x03,0x52,0x0d,0x1b,0x0a,0x0c,0x0a,0x05, +0x04,0x0b,0x02,0x00,0x01,0x12,0x03,0x52,0x1c,0x21, +0x0a,0x0c,0x0a,0x05,0x04,0x0b,0x02,0x00,0x03,0x12, +0x03,0x52,0x24,0x25,0x0a,0x0a,0x0a,0x02,0x04,0x0c, +0x12,0x04,0x55,0x00,0x5a,0x01,0x0a,0x0a,0x0a,0x03, +0x04,0x0c,0x01,0x12,0x03,0x55,0x08,0x22,0x0a,0x0b, +0x0a,0x04,0x04,0x0c,0x02,0x00,0x12,0x03,0x56,0x04, +0x24,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x00,0x06, +0x12,0x03,0x56,0x04,0x15,0x0a,0x0c,0x0a,0x05,0x04, +0x0c,0x02,0x00,0x01,0x12,0x03,0x56,0x16,0x1f,0x0a, +0x0c,0x0a,0x05,0x04,0x0c,0x02,0x00,0x03,0x12,0x03, +0x56,0x22,0x23,0x0a,0x0b,0x0a,0x04,0x04,0x0c,0x02, +0x01,0x12,0x03,0x57,0x04,0x19,0x0a,0x0c,0x0a,0x05, +0x04,0x0c,0x02,0x01,0x05,0x12,0x03,0x57,0x04,0x0a, +0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x01,0x01,0x12, +0x03,0x57,0x0b,0x14,0x0a,0x0c,0x0a,0x05,0x04,0x0c, +0x02,0x01,0x03,0x12,0x03,0x57,0x17,0x18,0x0a,0x0b, +0x0a,0x04,0x04,0x0c,0x02,0x02,0x12,0x03,0x58,0x04, +0x1d,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x02,0x05, +0x12,0x03,0x58,0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04, +0x0c,0x02,0x02,0x01,0x12,0x03,0x58,0x0a,0x18,0x0a, +0x0c,0x0a,0x05,0x04,0x0c,0x02,0x02,0x03,0x12,0x03, +0x58,0x1b,0x1c,0x0a,0x0b,0x0a,0x04,0x04,0x0c,0x02, +0x03,0x12,0x03,0x59,0x04,0x1d,0x0a,0x0c,0x0a,0x05, +0x04,0x0c,0x02,0x03,0x05,0x12,0x03,0x59,0x04,0x09, +0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x03,0x01,0x12, +0x03,0x59,0x0a,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x0c, +0x02,0x03,0x03,0x12,0x03,0x59,0x1b,0x1c,0x0a,0x0a, +0x0a,0x02,0x04,0x0d,0x12,0x04,0x5c,0x00,0x60,0x01, +0x0a,0x0a,0x0a,0x03,0x04,0x0d,0x01,0x12,0x03,0x5c, +0x08,0x24,0x0a,0x0b,0x0a,0x04,0x04,0x0d,0x02,0x00, +0x12,0x03,0x5d,0x04,0x1b,0x0a,0x0c,0x0a,0x05,0x04, +0x0d,0x02,0x00,0x05,0x12,0x03,0x5d,0x04,0x0a,0x0a, +0x0c,0x0a,0x05,0x04,0x0d,0x02,0x00,0x01,0x12,0x03, +0x5d,0x0b,0x16,0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02, +0x00,0x03,0x12,0x03,0x5d,0x19,0x1a,0x0a,0x0b,0x0a, +0x04,0x04,0x0d,0x02,0x01,0x12,0x03,0x5e,0x04,0x19, +0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,0x01,0x05,0x12, +0x03,0x5e,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x0d, +0x02,0x01,0x01,0x12,0x03,0x5e,0x0b,0x14,0x0a,0x0c, +0x0a,0x05,0x04,0x0d,0x02,0x01,0x03,0x12,0x03,0x5e, +0x17,0x18,0x0a,0x0b,0x0a,0x04,0x04,0x0d,0x02,0x02, +0x12,0x03,0x5f,0x04,0x1d,0x0a,0x0c,0x0a,0x05,0x04, +0x0d,0x02,0x02,0x05,0x12,0x03,0x5f,0x04,0x09,0x0a, +0x0c,0x0a,0x05,0x04,0x0d,0x02,0x02,0x01,0x12,0x03, +0x5f,0x0a,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02, +0x02,0x03,0x12,0x03,0x5f,0x1b,0x1c,0x62,0x06,0x70, +0x72,0x6f,0x74,0x6f,0x33, }; static const char file_name[] = "MrcComm.proto"; static const char mrc_proto_ProtobufFingerData_name[] = "mrc.proto.ProtobufFingerData"; diff --git a/hal/src/generated/main/native/cpp/mrc/protobuf/MrcComm.npb.h b/hal/src/generated/main/native/cpp/mrc/protobuf/MrcComm.npb.h index 8116f1d535..0d0ec42463 100644 --- a/hal/src/generated/main/native/cpp/mrc/protobuf/MrcComm.npb.h +++ b/hal/src/generated/main/native/cpp/mrc/protobuf/MrcComm.npb.h @@ -58,6 +58,7 @@ typedef struct _mrc_proto_ProtobufControlData { pb_callback_t Joysticks; uint64_t CurrentOpMode; uint32_t ControlWord; + pb_callback_t GameData; } mrc_proto_ProtobufControlData; typedef struct _mrc_proto_ProtobufJoystickDescriptor { @@ -167,7 +168,7 @@ typedef struct _mrc_proto_ProtobufConsoleLineTimestamp { #define mrc_proto_ProtobufFingerData_init_default {0, 0, 0} #define mrc_proto_ProtobufTouchpadData_init_default {{{NULL}, NULL}} #define mrc_proto_ProtobufJoystickData_init_default {0, 0, 0, {{NULL}, NULL}, 0, 0, {{NULL}, NULL}} -#define mrc_proto_ProtobufControlData_init_default {0, {{NULL}, NULL}, 0, 0} +#define mrc_proto_ProtobufControlData_init_default {0, {{NULL}, NULL}, 0, 0, {{NULL}, NULL}} #define mrc_proto_ProtobufJoystickDescriptor_init_default {{{NULL}, NULL}, 0, 0, 0} #define mrc_proto_ProtobufJoystickDescriptors_init_default {{{NULL}, NULL}} #define mrc_proto_ProtobufJoystickOutput_init_default {0, 0, 0} @@ -181,7 +182,7 @@ typedef struct _mrc_proto_ProtobufConsoleLineTimestamp { #define mrc_proto_ProtobufFingerData_init_zero {0, 0, 0} #define mrc_proto_ProtobufTouchpadData_init_zero {{{NULL}, NULL}} #define mrc_proto_ProtobufJoystickData_init_zero {0, 0, 0, {{NULL}, NULL}, 0, 0, {{NULL}, NULL}} -#define mrc_proto_ProtobufControlData_init_zero {0, {{NULL}, NULL}, 0, 0} +#define mrc_proto_ProtobufControlData_init_zero {0, {{NULL}, NULL}, 0, 0, {{NULL}, NULL}} #define mrc_proto_ProtobufJoystickDescriptor_init_zero {{{NULL}, NULL}, 0, 0, 0} #define mrc_proto_ProtobufJoystickDescriptors_init_zero {{{NULL}, NULL}} #define mrc_proto_ProtobufJoystickOutput_init_zero {0, 0, 0} @@ -209,6 +210,7 @@ typedef struct _mrc_proto_ProtobufConsoleLineTimestamp { #define mrc_proto_ProtobufControlData_Joysticks_tag 3 #define mrc_proto_ProtobufControlData_CurrentOpMode_tag 4 #define mrc_proto_ProtobufControlData_ControlWord_tag 5 +#define mrc_proto_ProtobufControlData_GameData_tag 6 #define mrc_proto_ProtobufJoystickDescriptor_JoystickName_tag 1 #define mrc_proto_ProtobufJoystickDescriptor_IsGamepad_tag 2 #define mrc_proto_ProtobufJoystickDescriptor_GamepadType_tag 3 @@ -272,7 +274,8 @@ X(a, CALLBACK, REPEATED, MESSAGE, Touchpads, 7) X(a, STATIC, SINGULAR, INT32, MatchTime, 2) \ X(a, CALLBACK, REPEATED, MESSAGE, Joysticks, 3) \ X(a, STATIC, SINGULAR, FIXED64, CurrentOpMode, 4) \ -X(a, STATIC, SINGULAR, UINT32, ControlWord, 5) +X(a, STATIC, SINGULAR, UINT32, ControlWord, 5) \ +X(a, CALLBACK, SINGULAR, STRING, GameData, 6) #define mrc_proto_ProtobufControlData_CALLBACK pb_default_field_callback #define mrc_proto_ProtobufControlData_DEFAULT NULL #define mrc_proto_ProtobufControlData_Joysticks_MSGTYPE mrc_proto_ProtobufJoystickData diff --git a/hal/src/main/java/org/wpilib/hardware/hal/DriverStationJNI.java b/hal/src/main/java/org/wpilib/hardware/hal/DriverStationJNI.java index db76350815..a91ab76f3f 100644 --- a/hal/src/main/java/org/wpilib/hardware/hal/DriverStationJNI.java +++ b/hal/src/main/java/org/wpilib/hardware/hal/DriverStationJNI.java @@ -266,6 +266,15 @@ public class DriverStationJNI extends JNIWrapper { */ public static native int getMatchInfo(MatchInfoData info); + /** + * Gets the game-specific data for the current match. + * + * @param gameData The existing game data string. + * @return the game-specific data + * @see "HAL_GetGameData" + */ + public static native String getGameData(String gameData); + /** * Sends an error to the driver station. * diff --git a/hal/src/main/java/org/wpilib/hardware/hal/MatchInfoData.java b/hal/src/main/java/org/wpilib/hardware/hal/MatchInfoData.java index d247a0147a..3b8eb6aee7 100644 --- a/hal/src/main/java/org/wpilib/hardware/hal/MatchInfoData.java +++ b/hal/src/main/java/org/wpilib/hardware/hal/MatchInfoData.java @@ -10,9 +10,6 @@ public class MatchInfoData { /** Stores the event name. */ public String eventName = ""; - /** Stores the game specific message. */ - public String gameSpecificMessage = ""; - /** Stores the match number. */ public int matchNumber; @@ -29,19 +26,12 @@ public class MatchInfoData { * Called from JNI to set the structure data. * * @param eventName Event name. - * @param gameSpecificMessage Game-specific message. * @param matchNumber Match number. * @param replayNumber Replay number. * @param matchType Match type. */ - public void setData( - String eventName, - String gameSpecificMessage, - int matchNumber, - int replayNumber, - int matchType) { + public void setData(String eventName, int matchNumber, int replayNumber, int matchType) { this.eventName = eventName; - this.gameSpecificMessage = gameSpecificMessage; this.matchNumber = matchNumber; this.replayNumber = replayNumber; this.matchType = matchType; diff --git a/hal/src/main/java/org/wpilib/hardware/hal/simulation/DriverStationDataJNI.java b/hal/src/main/java/org/wpilib/hardware/hal/simulation/DriverStationDataJNI.java index 94e414723c..c7c0024e4c 100644 --- a/hal/src/main/java/org/wpilib/hardware/hal/simulation/DriverStationDataJNI.java +++ b/hal/src/main/java/org/wpilib/hardware/hal/simulation/DriverStationDataJNI.java @@ -109,11 +109,9 @@ public class DriverStationDataJNI extends JNIWrapper { public static native int getJoystickRumble(int stick, int rumbleNum); public static native void setMatchInfo( - String eventName, - String gameSpecificMessage, - int matchNumber, - int replayNumber, - int matchType); + String eventName, int matchNumber, int replayNumber, int matchType); + + public static native void setGameData(String gameData); public static native void registerAllCallbacks(NotifyCallback callback, boolean initialNotify); @@ -150,8 +148,6 @@ public class DriverStationDataJNI extends JNIWrapper { public static native void setJoystickSupportedOutputs(int stick, int supportedOutputs); - public static native void setGameSpecificMessage(String message); - public static native void setEventName(String name); public static native void setMatchType(int type); diff --git a/hal/src/main/native/cpp/jni/DriverStationJNI.cpp b/hal/src/main/native/cpp/jni/DriverStationJNI.cpp index 6a0d339d6a..897dd6094d 100644 --- a/hal/src/main/native/cpp/jni/DriverStationJNI.cpp +++ b/hal/src/main/native/cpp/jni/DriverStationJNI.cpp @@ -312,6 +312,29 @@ Java_org_wpilib_hardware_hal_DriverStationJNI_getMatchInfo return status; } +/* + * Class: org_wpilib_hardware_hal_DriverStationJNI + * Method: getGameData + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_org_wpilib_hardware_hal_DriverStationJNI_getGameData + (JNIEnv* env, jclass, jstring existing) +{ + HAL_GameData gameData; + HAL_GetGameData(&gameData); + std::string_view newView{gameData.gameData}; + if (existing != nullptr) { + // Load existing, see if it matches return old + JStringRef existingStr{env, existing}; + std::string_view existingView{existingStr}; + if (existingView == newView) { + return existing; + } + } + return MakeJString(env, newView); +} + /* * Class: org_wpilib_hardware_hal_DriverStationJNI * Method: sendError diff --git a/hal/src/main/native/cpp/jni/HALUtil.cpp b/hal/src/main/native/cpp/jni/HALUtil.cpp index efb7c6bb1a..41197d27b6 100644 --- a/hal/src/main/native/cpp/jni/HALUtil.cpp +++ b/hal/src/main/native/cpp/jni/HALUtil.cpp @@ -284,17 +284,12 @@ void SetCanStatusObject(JNIEnv* env, jobject canStatus, void SetMatchInfoObject(JNIEnv* env, jobject matchStatus, const HAL_MatchInfo& matchInfo) { static jmethodID func = - env->GetMethodID(matchInfoDataCls, "setData", - "(Ljava/lang/String;Ljava/lang/String;III)V"); + env->GetMethodID(matchInfoDataCls, "setData", "(Ljava/lang/String;III)V"); - env->CallVoidMethod( - matchStatus, func, MakeJString(env, matchInfo.eventName), - MakeJString(env, - {reinterpret_cast(matchInfo.gameSpecificMessage), - matchInfo.gameSpecificMessageSize}), - static_cast(matchInfo.matchNumber), - static_cast(matchInfo.replayNumber), - static_cast(matchInfo.matchType)); + env->CallVoidMethod(matchStatus, func, MakeJString(env, matchInfo.eventName), + static_cast(matchInfo.matchNumber), + static_cast(matchInfo.replayNumber), + static_cast(matchInfo.matchType)); } jbyteArray SetCANReceiveMessageObject(JNIEnv* env, jobject canData, diff --git a/hal/src/main/native/cpp/jni/simulation/DriverStationDataJNI.cpp b/hal/src/main/native/cpp/jni/simulation/DriverStationDataJNI.cpp index b3cb25ffe4..942d9cc7e3 100644 --- a/hal/src/main/native/cpp/jni/simulation/DriverStationDataJNI.cpp +++ b/hal/src/main/native/cpp/jni/simulation/DriverStationDataJNI.cpp @@ -583,31 +583,39 @@ Java_org_wpilib_hardware_hal_simulation_DriverStationDataJNI_getJoystickRumble /* * Class: org_wpilib_hardware_hal_simulation_DriverStationDataJNI * Method: setMatchInfo - * Signature: (Ljava/lang/String;Ljava/lang/String;III)V + * Signature: (Ljava/lang/String;III)V */ JNIEXPORT void JNICALL Java_org_wpilib_hardware_hal_simulation_DriverStationDataJNI_setMatchInfo - (JNIEnv* env, jclass, jstring eventName, jstring gameSpecificMessage, - jint matchNumber, jint replayNumber, jint matchType) + (JNIEnv* env, jclass, jstring eventName, jint matchNumber, jint replayNumber, + jint matchType) { JStringRef eventNameRef{env, eventName}; - JStringRef gameSpecificMessageRef{env, gameSpecificMessage}; HAL_MatchInfo halMatchInfo; wpi::util::format_to_n_c_str(halMatchInfo.eventName, sizeof(halMatchInfo.eventName), "{}", eventNameRef.str()); - wpi::util::format_to_n_c_str( - reinterpret_cast(halMatchInfo.gameSpecificMessage), - sizeof(halMatchInfo.gameSpecificMessage), "{}", - gameSpecificMessageRef.str()); - halMatchInfo.gameSpecificMessageSize = gameSpecificMessageRef.size(); halMatchInfo.matchType = (HAL_MatchType)matchType; halMatchInfo.matchNumber = matchNumber; halMatchInfo.replayNumber = replayNumber; HALSIM_SetMatchInfo(&halMatchInfo); } +/* + * Class: org_wpilib_hardware_hal_simulation_DriverStationDataJNI + * Method: setGameData + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_org_wpilib_hardware_hal_simulation_DriverStationDataJNI_setGameData + (JNIEnv* env, jclass, jstring gameData) +{ + JStringRef gameDataRef{env, gameData}; + auto str = wpi::util::make_string(gameDataRef.str()); + HALSIM_SetGameDataString(&str); +} + /* * Class: org_wpilib_hardware_hal_simulation_DriverStationDataJNI * Method: registerAllCallbacks @@ -838,20 +846,6 @@ Java_org_wpilib_hardware_hal_simulation_DriverStationDataJNI_setJoystickName HALSIM_SetJoystickName(stick, &str); } -/* - * Class: org_wpilib_hardware_hal_simulation_DriverStationDataJNI - * Method: setGameSpecificMessage - * Signature: (Ljava/lang/String;)V - */ -JNIEXPORT void JNICALL -Java_org_wpilib_hardware_hal_simulation_DriverStationDataJNI_setGameSpecificMessage - (JNIEnv* env, jclass, jstring message) -{ - JStringRef messageJString{env, message}; - auto str = wpi::util::make_string(messageJString); - HALSIM_SetGameSpecificMessage(&str); -} - /* * Class: org_wpilib_hardware_hal_simulation_DriverStationDataJNI * Method: setEventName diff --git a/hal/src/main/native/cpp/proto/ControlDataProto.cpp b/hal/src/main/native/cpp/proto/ControlDataProto.cpp index 5a4bebb368..67e7e579d3 100644 --- a/hal/src/main/native/cpp/proto/ControlDataProto.cpp +++ b/hal/src/main/native/cpp/proto/ControlDataProto.cpp @@ -2,6 +2,7 @@ // Open Source Software; you can modify and/or share it under the terms of // the WPILib BSD license file in the root directory of this project. +#include #include #include "wpi/hal/proto/ControlData.h" @@ -65,12 +66,14 @@ constexpr mrc::ControlFlags ToControlWord(uint32_t Word) { std::optional wpi::util::Protobuf::Unpack( InputStream& Stream) { wpi::util::UnpackCallback JoystickCb; + wpi::util::UnpackCallback GameDataCb; mrc_proto_ProtobufControlData Msg{ .MatchTime = 0, .Joysticks = JoystickCb.Callback(), .CurrentOpMode = 0, .ControlWord = 0, + .GameData = GameDataCb.Callback(), }; if (!Stream.Decode(Msg)) { @@ -78,6 +81,7 @@ std::optional wpi::util::Protobuf::Unpack( } auto Joysticks = JoystickCb.Items(); + auto GameData = GameDataCb.Items(); mrc::ControlData ControlData; @@ -90,6 +94,10 @@ std::optional wpi::util::Protobuf::Unpack( ControlData.Joysticks()[i] = std::move(Joysticks[i]); } + if (GameData.size() >= 1) { + ControlData.MoveGameData(std::move(GameData[0])); + } + return ControlData; } @@ -97,12 +105,15 @@ bool wpi::util::Protobuf::Pack( OutputStream& Stream, const mrc::ControlData& Value) { std::span Sticks = Value.Joysticks(); wpi::util::PackCallback Joysticks{Sticks}; + std::string_view GameData = Value.GetGameData(); + wpi::util::PackCallback GameDataCb{&GameData}; mrc_proto_ProtobufControlData Msg{ .MatchTime = Value.MatchTime, .Joysticks = Joysticks.Callback(), .CurrentOpMode = Value.CurrentOpMode.ToValue(), .ControlWord = FromControlWord(Value.ControlWord), + .GameData = GameDataCb.Callback(), }; return Stream.Encode(Msg); diff --git a/hal/src/main/native/include/wpi/hal/DriverStation.h b/hal/src/main/native/include/wpi/hal/DriverStation.h index 145703f35c..02c3ec0102 100644 --- a/hal/src/main/native/include/wpi/hal/DriverStation.h +++ b/hal/src/main/native/include/wpi/hal/DriverStation.h @@ -179,6 +179,14 @@ HAL_Bool HAL_GetJoystickIsGamepad(int32_t joystickNum); */ int32_t HAL_GetJoystickGamepadType(int32_t joystickNum); +/** + * Gets the game-specific message for the current match. + * + * @param gameData the game-specific message (output) + * @return the error code, or 0 for success + */ +int32_t HAL_GetGameData(HAL_GameData* gameData); + /** * Gets the supported outputs of a specific joystick. * diff --git a/hal/src/main/native/include/wpi/hal/DriverStationTypes.h b/hal/src/main/native/include/wpi/hal/DriverStationTypes.h index 57c8a0476b..25495773af 100644 --- a/hal/src/main/native/include/wpi/hal/DriverStationTypes.h +++ b/hal/src/main/native/include/wpi/hal/DriverStationTypes.h @@ -153,6 +153,11 @@ struct HAL_JoystickTouchpads { }; typedef struct HAL_JoystickTouchpads HAL_JoystickTouchpads; +struct HAL_GameData { + char gameData[9]; +}; +typedef struct HAL_GameData HAL_GameData; + struct HAL_JoystickDescriptor { uint8_t isGamepad; uint8_t gamepadType; @@ -166,8 +171,6 @@ struct HAL_MatchInfo { HAL_MatchType matchType; uint16_t matchNumber; uint8_t replayNumber; - uint8_t gameSpecificMessage[64]; - uint16_t gameSpecificMessageSize; }; typedef struct HAL_MatchInfo HAL_MatchInfo; diff --git a/hal/src/main/native/include/wpi/hal/simulation/DriverStationData.h b/hal/src/main/native/include/wpi/hal/simulation/DriverStationData.h index 8339a84283..6914d9cd70 100644 --- a/hal/src/main/native/include/wpi/hal/simulation/DriverStationData.h +++ b/hal/src/main/native/include/wpi/hal/simulation/DriverStationData.h @@ -36,6 +36,8 @@ typedef void (*HAL_JoystickRumblesCallback)( int32_t rightRumble, int32_t leftTriggerRumble, int32_t rightTriggerRumble); typedef void (*HAL_MatchInfoCallback)(const char* name, void* param, const HAL_MatchInfo* info); +typedef void (*HAL_GameDataCallback)(const char* name, void* param, + const HAL_GameData* gameData); #ifdef __cplusplus extern "C" { @@ -171,6 +173,12 @@ void HALSIM_CancelMatchInfoCallback(int32_t uid); void HALSIM_GetMatchInfo(HAL_MatchInfo* info); void HALSIM_SetMatchInfo(const HAL_MatchInfo* info); +int32_t HALSIM_RegisterGameDataCallback(HAL_GameDataCallback callback, + void* param, HAL_Bool initialNotify); +void HALSIM_CancelGameDataCallback(int32_t uid); +void HALSIM_GetGameData(HAL_GameData* gameData); +void HALSIM_SetGameData(const HAL_GameData* gameData); + void HALSIM_SetJoystickButton(int32_t stick, int32_t button, HAL_Bool state); void HALSIM_SetJoystickAxis(int32_t stick, int32_t axis, double value); void HALSIM_SetJoystickPOV(int32_t stick, int32_t pov, HAL_JoystickPOV value); @@ -193,7 +201,7 @@ void HALSIM_SetJoystickName(int32_t stick, const struct WPI_String* name); void HALSIM_SetJoystickSupportedOutputs(int32_t stick, int32_t supportedOutputs); -void HALSIM_SetGameSpecificMessage(const struct WPI_String* message); +void HALSIM_SetGameDataString(const struct WPI_String* name); void HALSIM_SetEventName(const struct WPI_String* name); void HALSIM_SetMatchType(HAL_MatchType type); void HALSIM_SetMatchNumber(int32_t matchNumber); diff --git a/hal/src/main/native/sim/DriverStation.cpp b/hal/src/main/native/sim/DriverStation.cpp index 499532c0c5..f583a3d62c 100644 --- a/hal/src/main/native/sim/DriverStation.cpp +++ b/hal/src/main/native/sim/DriverStation.cpp @@ -47,6 +47,7 @@ struct JoystickDataCache { HAL_AllianceStationID allianceStation; double matchTime; HAL_ControlWord controlWord; + HAL_GameData gameData; }; static_assert(std::is_standard_layout_v); // static_assert(std::is_trivial_v); @@ -75,6 +76,7 @@ void JoystickDataCache::Update() { SimDriverStationData->opMode, SimDriverStationData->robotMode, SimDriverStationData->enabled, SimDriverStationData->eStop, SimDriverStationData->fmsAttached, SimDriverStationData->dsAttached); + SimDriverStationData->GetGameData(&gameData); } #define CHECK_JOYSTICK_NUMBER(stickNum) \ @@ -345,6 +347,15 @@ int32_t HAL_GetJoystickGamepadType(int32_t joystickNum) { } } +int32_t HAL_GetGameData(HAL_GameData* gameData) { + if (gShutdown) { + return INCOMPATIBLE_STATE; + } + std::scoped_lock lock{driverStation->cacheMutex}; + *gameData = currentRead->gameData; + return 0; +} + int32_t HAL_GetJoystickSupportedOutputs(int32_t joystickNum) { HAL_JoystickDescriptor joystickDesc; if (HAL_GetJoystickDescriptor(joystickNum, &joystickDesc) < 0) { diff --git a/hal/src/main/native/sim/mockdata/DriverStationData.cpp b/hal/src/main/native/sim/mockdata/DriverStationData.cpp index b4c2d04128..d4814339e3 100644 --- a/hal/src/main/native/sim/mockdata/DriverStationData.cpp +++ b/hal/src/main/native/sim/mockdata/DriverStationData.cpp @@ -336,6 +336,33 @@ void DriverStationData::SetMatchInfo(const HAL_MatchInfo* info) { m_matchInfoCallbacks(info); } +int32_t DriverStationData::RegisterGameDataCallback( + HAL_GameDataCallback callback, void* param, HAL_Bool initialNotify) { + std::scoped_lock lock(m_gameDataMutex); + int32_t uid = m_gameDataCallbacks.Register(callback, param); + if (initialNotify) { + callback(GetGameDataName(), param, &m_gameData); + } + return uid; +} + +void DriverStationData::CancelGameDataCallback(int32_t uid) { + m_gameDataCallbacks.Cancel(uid); +} + +void DriverStationData::GetGameData(HAL_GameData* gameData) { + std::scoped_lock lock(m_gameDataMutex); + *gameData = m_gameData; +} + +void DriverStationData::SetGameData(std::string_view gameData) { + std::scoped_lock lock(m_gameDataMutex); + auto copied = + gameData.copy(m_gameData.gameData, sizeof(m_gameData.gameData) - 1); + m_gameData.gameData[copied] = '\0'; + m_gameDataCallbacks(&m_gameData); +} + int32_t DriverStationData::RegisterNewDataCallback(HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) { @@ -537,15 +564,6 @@ void DriverStationData::SetJoystickName(int32_t stick, std::string_view name) { m_joystickDescriptorCallbacks(stick, &m_joystickData[stick].descriptor); } -void DriverStationData::SetGameSpecificMessage(std::string_view message) { - std::scoped_lock lock(m_matchInfoMutex); - auto copied = - message.copy(reinterpret_cast(m_matchInfo.gameSpecificMessage), - sizeof(m_matchInfo.gameSpecificMessage)); - m_matchInfo.gameSpecificMessageSize = copied; - m_matchInfoCallbacks(&m_matchInfo); -} - void DriverStationData::SetEventName(std::string_view name) { std::scoped_lock lock(m_matchInfoMutex); auto copied = @@ -708,6 +726,24 @@ void HALSIM_SetMatchInfo(const HAL_MatchInfo* info) { SimDriverStationData->SetMatchInfo(info); } +int32_t HALSIM_RegisterGameDataCallback(HAL_GameDataCallback callback, + void* param, HAL_Bool initialNotify) { + return SimDriverStationData->RegisterGameDataCallback(callback, param, + initialNotify); +} + +void HALSIM_CancelGameDataCallback(int32_t uid) { + SimDriverStationData->CancelGameDataCallback(uid); +} + +void HALSIM_GetGameData(HAL_GameData* gameData) { + SimDriverStationData->GetGameData(gameData); +} + +void HALSIM_SetGameData(const HAL_GameData* gameData) { + SimDriverStationData->SetGameData(gameData->gameData); +} + int32_t HALSIM_RegisterDriverStationNewDataCallback(HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) { @@ -788,9 +824,8 @@ void HALSIM_SetJoystickName(int32_t stick, const WPI_String* name) { SimDriverStationData->SetJoystickName(stick, wpi::util::to_string_view(name)); } -void HALSIM_SetGameSpecificMessage(const WPI_String* message) { - SimDriverStationData->SetGameSpecificMessage( - wpi::util::to_string_view(message)); +void HALSIM_SetGameDataString(const WPI_String* message) { + SimDriverStationData->SetGameData(wpi::util::to_string_view(message)); } void HALSIM_SetEventName(const WPI_String* name) { diff --git a/hal/src/main/native/sim/mockdata/DriverStationDataInternal.h b/hal/src/main/native/sim/mockdata/DriverStationDataInternal.h index 1e2eb85567..023bb2736d 100644 --- a/hal/src/main/native/sim/mockdata/DriverStationDataInternal.h +++ b/hal/src/main/native/sim/mockdata/DriverStationDataInternal.h @@ -36,6 +36,7 @@ class DriverStationData { HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(JoystickRumbles) HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(JoystickTouchpads) HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(MatchInfo) + HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(GameData) HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(NewData) static LLVM_ATTRIBUTE_ALWAYS_INLINE HAL_Value @@ -124,6 +125,11 @@ class DriverStationData { void GetMatchInfo(HAL_MatchInfo* info); void SetMatchInfo(const HAL_MatchInfo* info); + int32_t RegisterGameDataCallback(HAL_GameDataCallback callback, void* param, + HAL_Bool initialNotify); + void CancelGameDataCallback(int32_t uid); + void GetGameData(HAL_GameData* gameData); + void FreeMatchInfo(const HAL_MatchInfo* info); int32_t RegisterNewDataCallback(HAL_NotifyCallback callback, void* param, @@ -154,7 +160,7 @@ class DriverStationData { void SetJoystickName(int32_t stick, std::string_view message); void SetJoystickSupportedOutputs(int32_t stick, int32_t supportedOutputs); - void SetGameSpecificMessage(std::string_view message); + void SetGameData(std::string_view message); void SetEventName(std::string_view name); void SetMatchType(HAL_MatchType type); void SetMatchNumber(int32_t matchNumber); @@ -192,6 +198,8 @@ class DriverStationData { m_joystickDescriptorCallbacks; SimCallbackRegistry m_matchInfoCallbacks; + SimCallbackRegistry + m_gameDataCallbacks; SimCallbackRegistry m_newDataCallbacks; struct JoystickOutputStore { @@ -218,6 +226,9 @@ class DriverStationData { wpi::util::spinlock m_matchInfoMutex; HAL_MatchInfo m_matchInfo; + wpi::util::spinlock m_gameDataMutex; + HAL_GameData m_gameData; + wpi::util::spinlock m_opModeMutex; std::vector m_opModeOptions; }; diff --git a/hal/src/main/native/systemcore/FRCDriverStation.cpp b/hal/src/main/native/systemcore/FRCDriverStation.cpp index 396616cce2..80d435d9d1 100644 --- a/hal/src/main/native/systemcore/FRCDriverStation.cpp +++ b/hal/src/main/native/systemcore/FRCDriverStation.cpp @@ -63,6 +63,7 @@ struct JoystickDataCache { HAL_AllianceStationID allianceStation; float matchTime; HAL_ControlWord controlWord; + HAL_GameData gameData; }; static_assert(std::is_standard_layout_v); // static_assert(std::is_trivial_v); @@ -77,7 +78,6 @@ struct SystemServerDriverStation { wpi::nt::ProtobufSubscriber controlDataSubscriber; wpi::nt::ProtobufSubscriber matchInfoSubscriber; - wpi::nt::StringSubscriber gameSpecificMessageSubscriber; wpi::nt::ProtobufSubscriber joystickDescriptorsTopic; @@ -145,8 +145,6 @@ struct SystemServerDriverStation { matchInfoSubscriber = ntInst.GetProtobufTopic(ROBOT_MATCH_INFO_PATH) .Subscribe({}); - gameSpecificMessageSubscriber = - ntInst.GetStringTopic(ROBOT_GAME_SPECIFIC_MESSAGE_PATH).Subscribe({}); joystickDescriptorsTopic = ntInst .GetProtobufTopic( @@ -239,6 +237,13 @@ void JoystickDataCache::Update(const mrc::ControlData& data) { allianceInt += 1; allianceStation = static_cast(allianceInt); + auto gameData = data.GetGameData(); + if (gameData.size() > 8) { + gameData = gameData.substr(0, 8); + } + std::memcpy(this->gameData.gameData, gameData.data(), gameData.size()); + this->gameData.gameData[gameData.size()] = '\0'; + if (data.ControlWord.SupportsOpModes) { controlWord = HAL_MakeControlWord( data.CurrentOpMode.ToValue(), @@ -328,7 +333,6 @@ static wpi::util::mutex tcpCacheMutex; void TcpCache::Update() { auto newMatchInfo = systemServerDs->matchInfoSubscriber.Get(); - auto gameMsg = systemServerDs->gameSpecificMessageSubscriber.Get(); matchInfo.matchNumber = newMatchInfo.MatchNumber; matchInfo.matchType = static_cast(newMatchInfo.Type); @@ -343,14 +347,6 @@ void TcpCache::Update() { } matchInfo.eventName[nameLen] = '\0'; - auto gameDataLen = - (std::min)(sizeof(matchInfo.gameSpecificMessage), gameMsg.size()); - - if (gameDataLen > 0) { - std::memcpy(matchInfo.gameSpecificMessage, gameMsg.data(), gameDataLen); - } - matchInfo.gameSpecificMessageSize = gameDataLen; - const auto descriptorsMsg = systemServerDs->joystickDescriptorsTopic.Get(); size_t descriptorCount = descriptorsMsg.GetDescriptorCount(); @@ -617,6 +613,12 @@ int32_t HAL_GetJoystickGamepadType(int32_t joystickNum) { } } +int32_t HAL_GetGameData(HAL_GameData* gameData) { + std::scoped_lock lock{cacheMutex}; + *gameData = currentRead->gameData; + return 0; +} + int32_t HAL_GetJoystickSupportedOutputs(int32_t joystickNum) { HAL_JoystickDescriptor joystickDesc; if (HAL_GetJoystickDescriptor(joystickNum, &joystickDesc) < 0) { diff --git a/hal/src/main/native/systemcore/mockdata/DriverStationData.cpp b/hal/src/main/native/systemcore/mockdata/DriverStationData.cpp index b22dd6d98d..a9bbaf36e0 100644 --- a/hal/src/main/native/systemcore/mockdata/DriverStationData.cpp +++ b/hal/src/main/native/systemcore/mockdata/DriverStationData.cpp @@ -101,6 +101,17 @@ void HALSIM_GetMatchInfo(HAL_MatchInfo* info) {} void HALSIM_SetMatchInfo(const HAL_MatchInfo* info) {} +int32_t HALSIM_RegisterGameDataCallback(HAL_GameDataCallback callback, + void* param, HAL_Bool initialNotify) { + return 0; +} + +void HALSIM_CancelGameDataCallback(int32_t uid) {} + +void HALSIM_GetGameData(HAL_GameData* info) {} + +void HALSIM_SetGameData(const HAL_GameData* info) {} + int32_t HALSIM_RegisterDriverStationNewDataCallback(HAL_NotifyCallback callback, void* param, HAL_Bool initialNotify) { @@ -149,7 +160,7 @@ void HALSIM_SetJoystickName(int32_t stick, const struct WPI_String* name) {} void HALSIM_SetJoystickSupportedOutputs(int32_t stick, int32_t supportedOutputs) {} -void HALSIM_SetGameSpecificMessage(const struct WPI_String* message) {} +void HALSIM_SetGameDataString(const struct WPI_String* message) {} void HALSIM_SetEventName(const struct WPI_String* name) {} diff --git a/hal/src/main/python/semiwrap/DriverStation.yml b/hal/src/main/python/semiwrap/DriverStation.yml index 354a15f7f2..5fd9204096 100644 --- a/hal/src/main/python/semiwrap/DriverStation.yml +++ b/hal/src/main/python/semiwrap/DriverStation.yml @@ -43,3 +43,4 @@ functions: HAL_ObserveUserProgram: GetControlWord: GetUncachedControlWord: + HAL_GetGameData: diff --git a/hal/src/main/python/semiwrap/DriverStationTypes.yml b/hal/src/main/python/semiwrap/DriverStationTypes.yml index 8dedf5c9e2..330c245d1d 100644 --- a/hal/src/main/python/semiwrap/DriverStationTypes.yml +++ b/hal/src/main/python/semiwrap/DriverStationTypes.yml @@ -45,8 +45,6 @@ classes: matchType: matchNumber: replayNumber: - gameSpecificMessage: - gameSpecificMessageSize: HAL_JoystickTouchpadFinger: attributes: down: @@ -93,6 +91,9 @@ classes: IsTest: IsTestEnabled: GetValue: + HAL_GameData: + attributes: + gameData: functions: HAL_MakeControlWord: HAL_ControlWord_GetOpModeHash: diff --git a/hal/src/main/python/semiwrap/simulation/DriverStationData.yml b/hal/src/main/python/semiwrap/simulation/DriverStationData.yml index 8cfeb8e4ff..39013c6302 100644 --- a/hal/src/main/python/semiwrap/simulation/DriverStationData.yml +++ b/hal/src/main/python/semiwrap/simulation/DriverStationData.yml @@ -68,6 +68,11 @@ functions: HALSIM_CancelMatchInfoCallback: HALSIM_GetMatchInfo: HALSIM_SetMatchInfo: + HALSIM_RegisterGameDataCallback: + ignore: true + HALSIM_CancelGameDataCallback: + HALSIM_GetGameData: + HALSIM_SetGameData: HALSIM_SetJoystickButton: HALSIM_SetJoystickAxis: HALSIM_SetJoystickPOV: @@ -80,11 +85,11 @@ functions: auto s = wpi::util::make_string(sv); HALSIM_SetJoystickName(stick, &s); } - HALSIM_SetGameSpecificMessage: + HALSIM_SetGameDataString: cpp_code: | [](std::string_view sv) { auto s = wpi::util::make_string(sv); - HALSIM_SetGameSpecificMessage(&s); + HALSIM_SetGameDataString(&s); } HALSIM_SetEventName: cpp_code: | diff --git a/hal/src/mrc/include/mrc/NetComm.h b/hal/src/mrc/include/mrc/NetComm.h index f43caedfd1..b79b60191f 100644 --- a/hal/src/mrc/include/mrc/NetComm.h +++ b/hal/src/mrc/include/mrc/NetComm.h @@ -253,6 +253,22 @@ struct ControlData { uint16_t MatchTime{0}; OpModeHash CurrentOpMode; + void SetGameData(std::string_view Data) { + if (Data.size() > MRC_MAX_GAME_DATA_LEN) { + Data = Data.substr(0, MRC_MAX_GAME_DATA_LEN); + } + GameData = Data; + } + + void MoveGameData(std::string&& Data) { + GameData = std::move(Data); + if (GameData.size() > MRC_MAX_GAME_DATA_LEN) { + GameData.resize(MRC_MAX_GAME_DATA_LEN); + } + } + + std::string_view GetGameData() const { return GameData; } + std::span Joysticks() { return std::span{JoysticksStore.data(), GetJoystickCount()}; } @@ -269,6 +285,7 @@ struct ControlData { } private: + std::string GameData; std::array JoysticksStore; uint8_t JoystickCount{0}; }; @@ -514,24 +531,24 @@ struct OpMode { OpModeHash Hash; void SetName(std::string_view NewName) { - if (NewName.size() > MRC_MAX_OPMODE_LEN) { - NewName = NewName.substr(0, MRC_MAX_OPMODE_LEN); + if (NewName.size() > MRC_MAX_OPMODE_STRING_LEN) { + NewName = NewName.substr(0, MRC_MAX_OPMODE_STRING_LEN); } Name = NewName; } void MoveName(std::string&& NewName) { Name = std::move(NewName); - if (Name.size() > MRC_MAX_OPMODE_LEN) { - Name.resize(MRC_MAX_OPMODE_LEN); + if (Name.size() > MRC_MAX_OPMODE_STRING_LEN) { + Name.resize(MRC_MAX_OPMODE_STRING_LEN); } } std::string_view GetName() const { return Name; } std::span WritableNameBuffer(size_t Len) { - if (Len > MRC_MAX_OPMODE_LEN) { - Len = MRC_MAX_OPMODE_LEN; + if (Len > MRC_MAX_OPMODE_STRING_LEN) { + Len = MRC_MAX_OPMODE_STRING_LEN; } Name.resize(Len); return std::span{reinterpret_cast(Name.data()), @@ -539,24 +556,24 @@ struct OpMode { } void SetGroup(std::string_view NewGroup) { - if (NewGroup.size() > MRC_MAX_OPMODE_LEN) { - NewGroup = NewGroup.substr(0, MRC_MAX_OPMODE_LEN); + if (NewGroup.size() > MRC_MAX_OPMODE_STRING_LEN) { + NewGroup = NewGroup.substr(0, MRC_MAX_OPMODE_STRING_LEN); } Group = NewGroup; } void MoveGroup(std::string&& NewGroup) { Group = std::move(NewGroup); - if (Group.size() > MRC_MAX_OPMODE_LEN) { - Group.resize(MRC_MAX_OPMODE_LEN); + if (Group.size() > MRC_MAX_OPMODE_STRING_LEN) { + Group.resize(MRC_MAX_OPMODE_STRING_LEN); } } std::string_view GetGroup() const { return Group; } std::span WritableGroupBuffer(size_t Len) { - if (Len > MRC_MAX_OPMODE_LEN) { - Len = MRC_MAX_OPMODE_LEN; + if (Len > MRC_MAX_OPMODE_STRING_LEN) { + Len = MRC_MAX_OPMODE_STRING_LEN; } Group.resize(Len); return std::span{reinterpret_cast(Group.data()), @@ -564,24 +581,24 @@ struct OpMode { } void SetDescription(std::string_view NewDescription) { - if (NewDescription.size() > MRC_MAX_OPMODE_LEN) { - NewDescription = NewDescription.substr(0, MRC_MAX_OPMODE_LEN); + if (NewDescription.size() > MRC_MAX_OPMODE_STRING_LEN) { + NewDescription = NewDescription.substr(0, MRC_MAX_OPMODE_STRING_LEN); } Description = NewDescription; } void MoveDescription(std::string&& NewDescription) { Description = std::move(NewDescription); - if (Description.size() > MRC_MAX_OPMODE_LEN) { - Description.resize(MRC_MAX_OPMODE_LEN); + if (Description.size() > MRC_MAX_OPMODE_STRING_LEN) { + Description.resize(MRC_MAX_OPMODE_STRING_LEN); } } std::string_view GetDescription() const { return Description; } std::span WritableDescriptionBuffer(size_t Len) { - if (Len > MRC_MAX_OPMODE_LEN) { - Len = MRC_MAX_OPMODE_LEN; + if (Len > MRC_MAX_OPMODE_STRING_LEN) { + Len = MRC_MAX_OPMODE_STRING_LEN; } Description.resize(Len); return std::span{reinterpret_cast(Description.data()), diff --git a/hal/src/mrc/include/mrc/NtNetComm.h b/hal/src/mrc/include/mrc/NtNetComm.h index feb415a199..2a6cf2bc8d 100644 --- a/hal/src/mrc/include/mrc/NtNetComm.h +++ b/hal/src/mrc/include/mrc/NtNetComm.h @@ -10,8 +10,6 @@ #define ROBOT_WATCHDOG_ACTIVE_PATH (ROBOT_CONTROL_DATA_PREFIX "WatchdogActive") #define ROBOT_CONTROL_DATA_PATH (ROBOT_CONTROL_DATA_PREFIX "ControlData") -#define ROBOT_GAME_SPECIFIC_MESSAGE_PATH \ - (ROBOT_CONTROL_DATA_PREFIX "GameSpecificMessage") #define ROBOT_MATCH_INFO_PATH (ROBOT_CONTROL_DATA_PREFIX "MatchInfo") #define ROBOT_JOYSTICK_DESCRIPTORS_PATH \ (ROBOT_CONTROL_DATA_PREFIX "JoystickDescriptors") @@ -58,8 +56,8 @@ #define MRC_MAX_NUM_AXES 12 #define MRC_MAX_NUM_POVS 8 #define MRC_MAX_NUM_BUTTONS 64 -#define MRC_MAX_OPMODE_LEN 128 -#define MRC_MAX_GAME_SPECIFIC_MESSAGE_LEN 128 +#define MRC_MAX_OPMODE_STRING_LEN 64 +#define MRC_MAX_GAME_DATA_LEN 8 #define MRC_MAX_EVENT_NAME_LEN 64 #define MRC_MAX_JOYSTICK_NAME_LEN 256 #define MRC_MAX_VERSION_SIZE 256 diff --git a/hal/src/mrc/proto/MrcComm.proto b/hal/src/mrc/proto/MrcComm.proto index 83093442fa..c458a89418 100644 --- a/hal/src/mrc/proto/MrcComm.proto +++ b/hal/src/mrc/proto/MrcComm.proto @@ -31,6 +31,7 @@ message ProtobufControlData { int32 MatchTime = 2; repeated ProtobufJoystickData Joysticks = 3; fixed64 CurrentOpMode = 4; + string GameData = 6; } message ProtobufJoystickDescriptor { diff --git a/hal/src/test/native/cpp/mockdata/DriverStationDataTest.cpp b/hal/src/test/native/cpp/mockdata/DriverStationDataTest.cpp index a4dc8dac8a..918ee65b0d 100644 --- a/hal/src/test/native/cpp/mockdata/DriverStationDataTest.cpp +++ b/hal/src/test/native/cpp/mockdata/DriverStationDataTest.cpp @@ -121,14 +121,9 @@ TEST(DriverStationTest, Joystick) { TEST(DriverStationTest, EventInfo) { constexpr std::string_view eventName = "UnitTest"; - constexpr std::string_view gameData = "Insert game specific info here :D"; HAL_MatchInfo info; wpi::util::format_to_n_c_str(info.eventName, sizeof(info.eventName), eventName); - wpi::util::format_to_n_c_str( - reinterpret_cast(info.gameSpecificMessage), - sizeof(info.gameSpecificMessage), gameData); - info.gameSpecificMessageSize = gameData.size(); info.matchNumber = 5; info.matchType = HAL_MatchType::HAL_kMatchType_qualification; info.replayNumber = 42; @@ -139,11 +134,7 @@ TEST(DriverStationTest, EventInfo) { HAL_MatchInfo dataBack; HAL_GetMatchInfo(&dataBack); - std::string gsm{reinterpret_cast(dataBack.gameSpecificMessage), - dataBack.gameSpecificMessageSize}; - EXPECT_EQ(eventName, dataBack.eventName); - EXPECT_EQ(gameData, gsm); EXPECT_EQ(5, dataBack.matchNumber); EXPECT_EQ(HAL_MatchType::HAL_kMatchType_qualification, dataBack.matchType); EXPECT_EQ(42, dataBack.replayNumber); diff --git a/simulation/halsim_ds_socket/src/main/native/cpp/DSCommPacket.cpp b/simulation/halsim_ds_socket/src/main/native/cpp/DSCommPacket.cpp index 09a5c16e48..d681c2ccd2 100644 --- a/simulation/halsim_ds_socket/src/main/native/cpp/DSCommPacket.cpp +++ b/simulation/halsim_ds_socket/src/main/native/cpp/DSCommPacket.cpp @@ -44,7 +44,6 @@ DSCommPacket::DSCommPacket() { i.ResetTcp(); i.ResetUdp(); } - matchInfo.gameSpecificMessageSize = 0; } /*---------------------------------------------------------------------------- @@ -160,9 +159,6 @@ void DSCommPacket::DecodeTCP(std::span packet) { case kJoystickNameTag: ReadJoystickDescriptionTag(tagPacket); break; - case kGameDataTag: - ReadGameSpecificMessageTag(tagPacket); - break; case kMatchInfoTag: ReadNewMatchInfoTag(tagPacket); break; @@ -240,22 +236,6 @@ void DSCommPacket::ReadNewMatchInfoTag(std::span data) { HALSIM_SetMatchInfo(&matchInfo); } -void DSCommPacket::ReadGameSpecificMessageTag(std::span data) { - // Size 2 bytes, tag 1 byte - if (data.size() <= 3) { - return; - } - - int length = std::min(((data[0] << 8) | data[1]) - 1, - sizeof(matchInfo.gameSpecificMessage)); - for (int i = 0; i < length; i++) { - matchInfo.gameSpecificMessage[i] = data[3 + i]; - } - - matchInfo.gameSpecificMessageSize = length; - - HALSIM_SetMatchInfo(&matchInfo); -} void DSCommPacket::ReadJoystickDescriptionTag(std::span data) { if (data.size() < 3) { return; diff --git a/simulation/halsim_ds_socket/src/main/native/include/wpi/halsim/ds_socket/DSCommPacket.hpp b/simulation/halsim_ds_socket/src/main/native/include/wpi/halsim/ds_socket/DSCommPacket.hpp index 2b200a4485..461afe3173 100644 --- a/simulation/halsim_ds_socket/src/main/native/include/wpi/halsim/ds_socket/DSCommPacket.hpp +++ b/simulation/halsim_ds_socket/src/main/native/include/wpi/halsim/ds_socket/DSCommPacket.hpp @@ -55,7 +55,6 @@ class DSCommPacket { void ReadMatchtimeTag(std::span tagData); void ReadJoystickTag(std::span data, int index); void ReadNewMatchInfoTag(std::span data); - void ReadGameSpecificMessageTag(std::span data); void ReadJoystickDescriptionTag(std::span data); uint8_t m_hi; diff --git a/simulation/halsim_ds_socket/src/test/native/cpp/DSCommPacketTest.cpp b/simulation/halsim_ds_socket/src/test/native/cpp/DSCommPacketTest.cpp index 3123ced24d..d2be694c55 100644 --- a/simulation/halsim_ds_socket/src/test/native/cpp/DSCommPacketTest.cpp +++ b/simulation/halsim_ds_socket/src/test/native/cpp/DSCommPacketTest.cpp @@ -29,11 +29,6 @@ class DSCommPacketTest : public ::testing::Test { return commPacket.matchInfo; } - HAL_MatchInfo& ReadGameSpecificTag(std::span data) { - commPacket.ReadGameSpecificMessageTag(data); - return commPacket.matchInfo; - } - protected: halsim::DSCommPacket commPacket; }; @@ -132,24 +127,3 @@ TEST_F(DSCommPacketTest, MatchInfoTag) { ASSERT_EQ(matchInfo.matchNumber, 18); ASSERT_EQ(matchInfo.replayNumber, 1); } - -TEST_F(DSCommPacketTest, GameDataTag) { - uint8_t arr[]{ - // Size (2), tag - 0, - 0, - 17, - // Match data (length is taglength - 1) - 'W', - 'C', - 'B', - 'C', - }; - arr[1] = sizeof(arr) - 2; - auto& matchInfo = ReadGameSpecificTag(arr); - ASSERT_EQ(matchInfo.gameSpecificMessageSize, 4); - ASSERT_EQ(matchInfo.gameSpecificMessage[0], 'W'); - ASSERT_EQ(matchInfo.gameSpecificMessage[1], 'C'); - ASSERT_EQ(matchInfo.gameSpecificMessage[2], 'B'); - ASSERT_EQ(matchInfo.gameSpecificMessage[3], 'C'); -} diff --git a/simulation/halsim_gui/src/main/native/cpp/DriverStationGui.cpp b/simulation/halsim_gui/src/main/native/cpp/DriverStationGui.cpp index 83a8baa3b9..55d813a0d8 100644 --- a/simulation/halsim_gui/src/main/native/cpp/DriverStationGui.cpp +++ b/simulation/halsim_gui/src/main/native/cpp/DriverStationGui.cpp @@ -231,9 +231,7 @@ class FMSSimModel : public wpi::glass::FMSModel { wpi::glass::IntegerSource* GetRobotModeData() override { return &m_robotMode; } - wpi::glass::StringSource* GetGameSpecificMessageData() override { - return &m_gameMessage; - } + wpi::glass::StringSource* GetGameData() override { return &m_gameMessage; } void SetFmsAttached(bool val) override { m_fmsAttached.SetValue(val); } void SetDsAttached(bool val) override { m_dsAttached.SetValue(val); } @@ -244,7 +242,7 @@ class FMSSimModel : public wpi::glass::FMSModel { void SetEStop(bool val) override { m_estop.SetValue(val); } void SetEnabled(bool val) override { m_enabled.SetValue(val); } void SetRobotMode(RobotMode val) override { m_robotMode.SetValue(val); } - void SetGameSpecificMessage(std::string_view val) override { + void SetGameData(std::string_view val) override { m_gameMessage.SetValue(val); } @@ -265,7 +263,7 @@ class FMSSimModel : public wpi::glass::FMSModel { wpi::glass::BooleanSource m_enabled{"FMS:RobotEnabled"}; wpi::glass::IntegerSource m_robotMode{"FMS:RobotMode"}; double m_startMatchTime = -1.0; - wpi::glass::StringSource m_gameMessage{"FMS:GameSpecificMessage"}; + wpi::glass::StringSource m_gameMessage{"FMS:GameData"}; }; } // namespace @@ -1319,7 +1317,7 @@ void FMSSimModel::UpdateHAL() { static_cast(m_robotMode.GetValue())); HALSIM_SetDriverStationMatchTime(m_matchTime.GetValue()); auto str = wpi::util::make_string(m_gameMessage.GetValue()); - HALSIM_SetGameSpecificMessage(&str); + HALSIM_SetGameDataString(&str); HALSIM_SetDriverStationDsAttached(m_dsAttached.GetValue()); } @@ -1353,12 +1351,10 @@ void FMSSimModel::Update() { } m_matchTime.SetValue(matchTime); - HAL_MatchInfo info; - HALSIM_GetMatchInfo(&info); + HAL_GameData info; + HALSIM_GetGameData(&info); m_gameMessage.SetValue( - std::string_view{reinterpret_cast(info.gameSpecificMessage), - reinterpret_cast(info.gameSpecificMessage) + - info.gameSpecificMessageSize}); + std::string_view{reinterpret_cast(info.gameData)}); } bool FMSSimModel::IsReadOnly() { diff --git a/simulation/halsim_ws_core/src/main/native/cpp/WSProvider_DriverStation.cpp b/simulation/halsim_ws_core/src/main/native/cpp/WSProvider_DriverStation.cpp index 0f4569c3c3..97cd0350e5 100644 --- a/simulation/halsim_ws_core/src/main/native/cpp/WSProvider_DriverStation.cpp +++ b/simulation/halsim_ws_core/src/main/native/cpp/WSProvider_DriverStation.cpp @@ -166,7 +166,7 @@ void HALSimWSProviderDriverStation::OnNetValueChanged( if ((it = json.find(">game_data")) != json.end()) { std::string message = it.value().get_ref(); auto str = wpi::util::make_string(message); - HALSIM_SetGameSpecificMessage(&str); + HALSIM_SetGameDataString(&str); } // Only notify usercode if we get the new data message diff --git a/wpilibc/src/main/native/cpp/driverstation/DriverStation.cpp b/wpilibc/src/main/native/cpp/driverstation/DriverStation.cpp index 8df4f8490c..3193587181 100644 --- a/wpilibc/src/main/native/cpp/driverstation/DriverStation.cpp +++ b/wpilibc/src/main/native/cpp/driverstation/DriverStation.cpp @@ -93,8 +93,7 @@ struct MatchDataSender { ".type", kSmartDashboardType, {{"SmartDashboard", kSmartDashboardType}}}; - MatchDataSenderEntry gameSpecificMessage{ - table, "GameSpecificMessage", ""}; + MatchDataSenderEntry gameData{table, "GameData", ""}; MatchDataSenderEntry eventName{table, "EventName", ""}; MatchDataSenderEntry matchNumber{table, "MatchNumber", 0}; @@ -701,11 +700,14 @@ std::string DriverStation::GetOpMode() { return GetInstance().OpModeToString(GetOpModeId()); } -std::string DriverStation::GetGameSpecificMessage() { - HAL_MatchInfo info; - HAL_GetMatchInfo(&info); - return std::string(reinterpret_cast(info.gameSpecificMessage), - info.gameSpecificMessageSize); +std::optional DriverStation::GetGameData() { + HAL_GameData info; + HAL_GetGameData(&info); + std::string_view gameDataView{reinterpret_cast(info.gameData)}; + if (gameDataView.empty()) { + return std::nullopt; + } + return std::string(gameDataView); } std::string DriverStation::GetEventName() { @@ -900,13 +902,15 @@ void SendMatchData() { HAL_MatchInfo tmpDataStore; HAL_GetMatchInfo(&tmpDataStore); + HAL_GameData tmpGameData; + HAL_GetGameData(&tmpGameData); + auto& inst = GetInstance(); inst.matchDataSender.alliance.Set(isRedAlliance); inst.matchDataSender.station.Set(stationNumber); inst.matchDataSender.eventName.Set(tmpDataStore.eventName); - inst.matchDataSender.gameSpecificMessage.Set( - std::string(reinterpret_cast(tmpDataStore.gameSpecificMessage), - tmpDataStore.gameSpecificMessageSize)); + inst.matchDataSender.gameData.Set( + std::string(reinterpret_cast(tmpGameData.gameData))); inst.matchDataSender.matchNumber.Set(tmpDataStore.matchNumber); inst.matchDataSender.replayNumber.Set(tmpDataStore.replayNumber); inst.matchDataSender.matchType.Set(static_cast(tmpDataStore.matchType)); diff --git a/wpilibc/src/main/native/cpp/simulation/DriverStationSim.cpp b/wpilibc/src/main/native/cpp/simulation/DriverStationSim.cpp index 639b13677c..ae3b01251c 100644 --- a/wpilibc/src/main/native/cpp/simulation/DriverStationSim.cpp +++ b/wpilibc/src/main/native/cpp/simulation/DriverStationSim.cpp @@ -301,9 +301,9 @@ void DriverStationSim::SetJoystickName(int stick, std::string_view name) { HALSIM_SetJoystickName(stick, &str); } -void DriverStationSim::SetGameSpecificMessage(std::string_view message) { +void DriverStationSim::SetGameData(std::string_view message) { auto str = wpi::util::make_string(message); - HALSIM_SetGameSpecificMessage(&str); + HALSIM_SetGameDataString(&str); } void DriverStationSim::SetEventName(std::string_view name) { diff --git a/wpilibc/src/main/native/include/wpi/driverstation/DriverStation.hpp b/wpilibc/src/main/native/include/wpi/driverstation/DriverStation.hpp index 2130b75aeb..7676dd07b8 100644 --- a/wpilibc/src/main/native/include/wpi/driverstation/DriverStation.hpp +++ b/wpilibc/src/main/native/include/wpi/driverstation/DriverStation.hpp @@ -519,7 +519,7 @@ class DriverStation final { * * @return A string containing the game specific message. */ - static std::string GetGameSpecificMessage(); + static std::optional GetGameData(); /** * Returns the name of the competition event provided by the FMS. diff --git a/wpilibc/src/main/native/include/wpi/simulation/DriverStationSim.hpp b/wpilibc/src/main/native/include/wpi/simulation/DriverStationSim.hpp index 255c43501f..fd1753af0d 100644 --- a/wpilibc/src/main/native/include/wpi/simulation/DriverStationSim.hpp +++ b/wpilibc/src/main/native/include/wpi/simulation/DriverStationSim.hpp @@ -419,7 +419,7 @@ class DriverStationSim { * * @param message the game specific message */ - static void SetGameSpecificMessage(std::string_view message); + static void SetGameData(std::string_view message); /** * Sets the event name. diff --git a/wpilibc/src/main/python/semiwrap/DriverStation.yml b/wpilibc/src/main/python/semiwrap/DriverStation.yml index 0512810df4..38d03cd81b 100644 --- a/wpilibc/src/main/python/semiwrap/DriverStation.yml +++ b/wpilibc/src/main/python/semiwrap/DriverStation.yml @@ -32,7 +32,7 @@ classes: IsTestEnabled: IsDSAttached: IsFMSAttached: - GetGameSpecificMessage: + GetGameData: GetEventName: GetMatchType: GetMatchNumber: diff --git a/wpilibc/src/main/python/semiwrap/simulation/DriverStationSim.yml b/wpilibc/src/main/python/semiwrap/simulation/DriverStationSim.yml index 515300e81a..a63b0015ab 100644 --- a/wpilibc/src/main/python/semiwrap/simulation/DriverStationSim.yml +++ b/wpilibc/src/main/python/semiwrap/simulation/DriverStationSim.yml @@ -55,7 +55,7 @@ classes: SetJoystickGamepadType: SetJoystickSupportedOutputs: SetJoystickName: - SetGameSpecificMessage: + SetGameData: SetEventName: SetMatchType: SetMatchNumber: diff --git a/wpilibc/src/test/native/cpp/simulation/DriverStationSimTest.cpp b/wpilibc/src/test/native/cpp/simulation/DriverStationSimTest.cpp index 1544aee294..2cd31a8f5d 100644 --- a/wpilibc/src/test/native/cpp/simulation/DriverStationSimTest.cpp +++ b/wpilibc/src/test/native/cpp/simulation/DriverStationSimTest.cpp @@ -240,14 +240,26 @@ TEST(DriverStationTest, MatchTime) { EXPECT_EQ(kTestTime, callback.GetLastValue()); } -TEST(DriverStationTest, SetGameSpecificMessage) { +TEST(DriverStationTest, SetGameData) { HAL_Initialize(500, 0); DriverStationSim::ResetData(); - constexpr auto message = "Hello World!"; - DriverStationSim::SetGameSpecificMessage(message); + constexpr auto message = "Hello"; + DriverStationSim::SetGameData(message); DriverStationSim::NotifyNewData(); - EXPECT_EQ(message, DriverStation::GetGameSpecificMessage()); + auto gameData = DriverStation::GetGameData(); + ASSERT_TRUE(gameData.has_value()); + EXPECT_EQ(message, gameData.value()); +} + +TEST(DriverStationTest, SetGameDataEmpty) { + HAL_Initialize(500, 0); + DriverStationSim::ResetData(); + + DriverStationSim::SetGameData(""); + DriverStationSim::NotifyNewData(); + auto gameData = DriverStation::GetGameData(); + EXPECT_FALSE(gameData.has_value()); } TEST(DriverStationTest, SetEventName) { diff --git a/wpilibj/src/main/java/org/wpilib/driverstation/DriverStation.java b/wpilibj/src/main/java/org/wpilib/driverstation/DriverStation.java index d48bb7339e..9ef82723ca 100644 --- a/wpilibj/src/main/java/org/wpilib/driverstation/DriverStation.java +++ b/wpilibj/src/main/java/org/wpilib/driverstation/DriverStation.java @@ -268,7 +268,7 @@ public final class DriverStation { private static class MatchDataSender { private static final String kSmartDashboardType = "FMSInfo"; - final StringPublisher gameSpecificMessage; + final StringPublisher gameData; final StringPublisher eventName; final IntegerPublisher matchNumber; final IntegerPublisher replayNumber; @@ -280,7 +280,7 @@ public final class DriverStation { boolean oldIsRedAlliance = true; int oldStationNumber = 1; String oldEventName = ""; - String oldGameSpecificMessage = ""; + String oldGameData = ""; int oldMatchNumber; int oldReplayNumber; int oldMatchType; @@ -294,8 +294,8 @@ public final class DriverStation { .publishEx( StringTopic.kTypeString, "{\"SmartDashboard\":\"" + kSmartDashboardType + "\"}") .set(kSmartDashboardType); - gameSpecificMessage = table.getStringTopic("GameSpecificMessage").publish(); - gameSpecificMessage.set(""); + gameData = table.getStringTopic("GameData").publish(); + gameData.set(""); eventName = table.getStringTopic("EventName").publish(); eventName.set(""); matchNumber = table.getIntegerTopic("MatchNumber").publish(); @@ -330,14 +330,14 @@ public final class DriverStation { }; String currentEventName; - String currentGameSpecificMessage; + String currentGameData; int currentMatchNumber; int currentReplayNumber; int currentMatchType; m_cacheDataMutex.lock(); try { currentEventName = DriverStation.m_matchInfo.eventName; - currentGameSpecificMessage = DriverStation.m_matchInfo.gameSpecificMessage; + currentGameData = DriverStation.m_gameData; currentMatchNumber = DriverStation.m_matchInfo.matchNumber; currentReplayNumber = DriverStation.m_matchInfo.replayNumber; currentMatchType = DriverStation.m_matchInfo.matchType; @@ -358,9 +358,9 @@ public final class DriverStation { eventName.set(currentEventName); oldEventName = currentEventName; } - if (!oldGameSpecificMessage.equals(currentGameSpecificMessage)) { - gameSpecificMessage.set(currentGameSpecificMessage); - oldGameSpecificMessage = currentGameSpecificMessage; + if (!oldGameData.equals(currentGameData)) { + gameData.set(currentGameData); + oldGameData = currentGameData; } if (currentMatchNumber != oldMatchNumber) { matchNumber.set(currentMatchNumber); @@ -547,6 +547,7 @@ public final class DriverStation { private static HALJoystickTouchpads[] m_joystickTouchpads = new HALJoystickTouchpads[kJoystickPorts]; private static MatchInfoData m_matchInfo = new MatchInfoData(); + private static String m_gameData = ""; private static ControlWord m_controlWord = new ControlWord(); private static String m_opMode = ""; private static EventVector m_refreshEvents = new EventVector(); @@ -561,6 +562,7 @@ public final class DriverStation { private static HALJoystickTouchpads[] m_joystickTouchpadsCache = new HALJoystickTouchpads[kJoystickPorts]; private static MatchInfoData m_matchInfoCache = new MatchInfoData(); + private static String m_gameDataCache = ""; private static ControlWord m_controlWordCache = new ControlWord(); private static String m_opModeCache = ""; @@ -1581,10 +1583,13 @@ public final class DriverStation { * * @return the game specific message */ - public static String getGameSpecificMessage() { + public static Optional getGameData() { m_cacheDataMutex.lock(); try { - return m_matchInfo.gameSpecificMessage; + if (m_gameData == null || m_gameData.isEmpty()) { + return Optional.empty(); + } + return Optional.of(m_gameData); } finally { m_cacheDataMutex.unlock(); } @@ -1812,6 +1817,10 @@ public final class DriverStation { DriverStationJNI.getMatchInfo(m_matchInfoCache); + // This is a pass through, so if it hasn't changed, it doesn't + // reallocate + m_gameDataCache = DriverStationJNI.getGameData(m_gameDataCache); + DriverStationJNI.getControlWord(m_controlWordCache); m_opModeCache = opModeToString(m_controlWordCache.getOpModeId()); @@ -1855,6 +1864,8 @@ public final class DriverStation { m_matchInfo = m_matchInfoCache; m_matchInfoCache = currentInfo; + m_gameData = m_gameDataCache; + ControlWord currentWord = m_controlWord; m_controlWord = m_controlWordCache; m_controlWordCache = currentWord; diff --git a/wpilibj/src/main/java/org/wpilib/simulation/DriverStationSim.java b/wpilibj/src/main/java/org/wpilib/simulation/DriverStationSim.java index 4a7eb780bf..00562c255b 100644 --- a/wpilibj/src/main/java/org/wpilib/simulation/DriverStationSim.java +++ b/wpilibj/src/main/java/org/wpilib/simulation/DriverStationSim.java @@ -505,8 +505,8 @@ public final class DriverStationSim { * * @param message the game specific message */ - public static void setGameSpecificMessage(String message) { - DriverStationDataJNI.setGameSpecificMessage(message); + public static void setGameData(String message) { + DriverStationDataJNI.setGameData(message); } /** diff --git a/wpilibj/src/test/java/org/wpilib/hal/MatchInfoDataTest.java b/wpilibj/src/test/java/org/wpilib/hal/MatchInfoDataTest.java index 753dd184dd..2e2309ab1e 100644 --- a/wpilibj/src/test/java/org/wpilib/hal/MatchInfoDataTest.java +++ b/wpilibj/src/test/java/org/wpilib/hal/MatchInfoDataTest.java @@ -18,7 +18,7 @@ class MatchInfoDataTest { @Test void testSetMatchInfo() { MatchType matchType = MatchType.Qualification; - DriverStationDataJNI.setMatchInfo("Event Name", "Game Message", 174, 191, matchType.ordinal()); + DriverStationDataJNI.setMatchInfo("Event Name", 174, 191, matchType.ordinal()); DriverStationSim.notifyNewData(); @@ -29,7 +29,6 @@ class MatchInfoDataTest { () -> assertEquals("Event Name", outMatchInfo.eventName), () -> assertEquals(matchType.ordinal(), outMatchInfo.matchType), () -> assertEquals(174, outMatchInfo.matchNumber), - () -> assertEquals(191, outMatchInfo.replayNumber), - () -> assertEquals("Game Message", outMatchInfo.gameSpecificMessage)); + () -> assertEquals(191, outMatchInfo.replayNumber)); } } diff --git a/wpilibj/src/test/java/org/wpilib/simulation/DriverStationSimTest.java b/wpilibj/src/test/java/org/wpilib/simulation/DriverStationSimTest.java index 0b62322d12..575bef9139 100644 --- a/wpilibj/src/test/java/org/wpilib/simulation/DriverStationSimTest.java +++ b/wpilibj/src/test/java/org/wpilib/simulation/DriverStationSimTest.java @@ -262,14 +262,36 @@ class DriverStationSimTest { } @Test - void testSetGameSpecificMessage() { + void testSetGameData() { HAL.initialize(500, 0); DriverStationSim.resetData(); - final String message = "Hello World!"; - DriverStationSim.setGameSpecificMessage(message); + final String message = "Hello"; + DriverStationSim.setGameData(message); DriverStationSim.notifyNewData(); - assertEquals(message, DriverStation.getGameSpecificMessage()); + var gameData = DriverStation.getGameData(); + assertTrue(gameData.isPresent()); + assertEquals(message, gameData.get()); + } + + @Test + void testSetGameDataEmpty() { + HAL.initialize(500, 0); + DriverStationSim.resetData(); + + DriverStationSim.setGameData(""); + DriverStationSim.notifyNewData(); + assertTrue(DriverStation.getGameData().isEmpty()); + } + + @Test + void testSetGameDataNull() { + HAL.initialize(500, 0); + DriverStationSim.resetData(); + + DriverStationSim.setGameData(null); + DriverStationSim.notifyNewData(); + assertTrue(DriverStation.getGameData().isEmpty()); } @Test