diff --git a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamapps/SteamApps.kt b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamapps/SteamApps.kt index ca28a8eb..1d292a7f 100644 --- a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamapps/SteamApps.kt +++ b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamapps/SteamApps.kt @@ -4,8 +4,10 @@ import com.google.protobuf.ByteString import `in`.dragonbra.javasteam.base.ClientMsg import `in`.dragonbra.javasteam.base.ClientMsgProtobuf import `in`.dragonbra.javasteam.base.IPacketMsg +import `in`.dragonbra.javasteam.enums.EAppUsageEvent import `in`.dragonbra.javasteam.enums.EMsg import `in`.dragonbra.javasteam.enums.EOSType +import `in`.dragonbra.javasteam.generated.MsgClientAppUsageEvent import `in`.dragonbra.javasteam.generated.MsgClientGetLegacyGameKey import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesClientserver.CMsgClientGamesPlayed import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesClientserver.CMsgClientGetAppOwnershipTicket @@ -33,6 +35,7 @@ import `in`.dragonbra.javasteam.steam.handlers.steamapps.callback.VACStatusCallb import `in`.dragonbra.javasteam.steam.steamclient.callbackmgr.CallbackMsg import `in`.dragonbra.javasteam.types.AsyncJobMultiple import `in`.dragonbra.javasteam.types.AsyncJobSingle +import `in`.dragonbra.javasteam.types.GameID import `in`.dragonbra.javasteam.util.NetHelpers /** @@ -299,6 +302,26 @@ class SteamApps : ClientMsgHandler() { return AsyncJobSingle(client, request.sourceJobID) } + /** + * An event sent to Steam after syncing user files during launch to notify Steam of the + * app that is launching. + * + * @param gameId Holds information pertaining to the app being launched + * @param usageEvent The type of launch occurring + */ + // JavaSteam Addition + fun sendClientAppUsageEvent( + gameId: GameID, + usageEvent: EAppUsageEvent, + offline: Short, + ) { + ClientMsg(MsgClientAppUsageEvent::class.java).apply { + body.appUsageEvent = usageEvent + body.gameID = gameId + body.offline = offline + }.also(client::send) + } + /** * Notify Steam of games being played * TODO: Support appid/non-steam game, [relevant discord msg](https://discord.com/channels/420907597906968586/420907598527594497/464573011274629151) diff --git a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamcloud/SteamCloud.kt b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamcloud/SteamCloud.kt index 3b26ecb5..b44cc911 100644 --- a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamcloud/SteamCloud.kt +++ b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamcloud/SteamCloud.kt @@ -5,9 +5,11 @@ import `in`.dragonbra.javasteam.base.ClientMsgProtobuf import `in`.dragonbra.javasteam.base.IPacketMsg import `in`.dragonbra.javasteam.enums.EMsg import `in`.dragonbra.javasteam.enums.EOSType +import `in`.dragonbra.javasteam.enums.EPlatformType import `in`.dragonbra.javasteam.enums.EResult import `in`.dragonbra.javasteam.enums.ESteamRealm import `in`.dragonbra.javasteam.protobufs.steamclient.Enums.EBluetoothDeviceType +import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesClientmetricsSteamclient.CClientMetrics_CloudAppSyncStats_Notification import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesClientserverUfs.CMsgClientUFSGetSingleFileInfo import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesClientserverUfs.CMsgClientUFSGetUGCDetails import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesClientserverUfs.CMsgClientUFSShareFile @@ -20,6 +22,7 @@ import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesCloudSteamcli import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesCloudSteamclient.CCloud_CompleteAppUploadBatch_Request import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesCloudSteamclient.CCloud_ExternalStorageTransferReport_Notification import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesCloudSteamclient.CCloud_GetAppFileChangelist_Request +import `in`.dragonbra.javasteam.rpc.service.ClientMetrics import `in`.dragonbra.javasteam.rpc.service.Cloud import `in`.dragonbra.javasteam.steam.authentication.AuthSession import `in`.dragonbra.javasteam.steam.handlers.ClientMsgHandler @@ -48,6 +51,11 @@ class SteamCloud : ClientMsgHandler() { ?: throw NullPointerException("Unable to get SteamUnifiedMessages handler") unifiedMessages.createService() } + private val clientMetrics: ClientMetrics by lazy { + val unifiedMessages = client.getHandler(SteamUnifiedMessages::class.java) + ?: throw NullPointerException("Unable to get SteamUnifiedMessages handler") + unifiedMessages.createService() + } /** * Requests details for a specific item of user generated content from the Steam servers. @@ -311,14 +319,103 @@ class SteamCloud : ClientMsgHandler() { cloudService.completeAppUploadBatchBlocking(request.build()).runBlock() } + /** + * Notify Steam of the stats of the sync that just occurred. The values with Ac in them, + * I believe, are for [Steam Auto Cloud](https://partner.steamgames.com/doc/features/cloud#steam_auto-cloud). + * + * @param appId The ID of the app whose user files were synced + * @param filesUploaded The number of files that were uploaded in the sync + * @param filesDownloaded The number of files that were downloaded in the sync + * @param filesDeleted The number of files that were deleted in the sync + * @param bytesUploaded The total number of bytes that were uploaded in the sync + * @param bytesDownloaded The total number of bytes that were downloaded in the sync + * @param microsecTotal The total time the sync took in micro-seconds + * @param microsecDeleteFiles The time the sync took to delete all the required files in micro-seconds + * @param microsecDownloadFiles The time the sync took to download all the required files in micro-seconds + * @param microsecUploadFiles The time the sync took to upload all the required files in micro-seconds + */ + // JavaSteam Addition + @JvmOverloads + fun appCloudSyncStats( + appId: Int, + platformType: EPlatformType, + preload: Boolean = false, + blockingAppLaunch: Boolean, + filesUploaded: Int = 0, + filesDownloaded: Int = 0, + filesDeleted: Int = 0, + bytesUploaded: Long = 0, + bytesDownloaded: Long = 0, + microsecTotal: Long, + microsecInitCaches: Long, + microsecValidateState: Long, + microsecAcLaunch: Long = 0, + microsecAcPrepUserFiles: Long = 0, + microsecAcExit: Long = 0, + microsecBuildSyncList: Long, + microsecDeleteFiles: Long = 0, + microsecDownloadFiles: Long = 0, + microsecUploadFiles: Long = 0, + hardwareType: Int = 1, + filesManaged: Int, + ) { + val request = CClientMetrics_CloudAppSyncStats_Notification.newBuilder().apply { + this.appId = appId + this.platformType = platformType.code() + this.preload = preload + this.blockingAppLaunch = blockingAppLaunch + if (filesUploaded > 0) { + this.filesUploaded = filesUploaded + } + if (filesDownloaded > 0) { + this.filesDownloaded = filesDownloaded + } + if (filesDeleted > 0) { + this.filesDeleted = filesDeleted + } + if (bytesUploaded > 0) { + this.bytesUploaded = bytesUploaded + } + if (bytesDownloaded > 0) { + this.bytesDownloaded = bytesDownloaded + } + this.microsecTotal = microsecTotal + this.microsecInitCaches = microsecInitCaches + this.microsecValidateState = microsecValidateState + if (microsecAcLaunch > 0) { + this.microsecAcLaunch = microsecAcLaunch + } + if (microsecAcPrepUserFiles > 0) { + this.microsecAcPrepUserFiles = microsecAcPrepUserFiles + } + if (microsecAcExit > 0) { + this.microsecAcExit = microsecAcExit + } + this.microsecBuildSyncList = microsecBuildSyncList + if (microsecDeleteFiles > 0) { + this.microsecDeleteFiles = microsecDeleteFiles + } + if (microsecDownloadFiles > 0) { + this.microsecDownloadFiles = microsecDownloadFiles + } + if (microsecUploadFiles > 0) { + this.microsecUploadFiles = microsecUploadFiles + } + this.hardwareType = hardwareType + this.filesManaged = filesManaged + } + clientMetrics.clientCloudAppSyncStats(request.build()) + } + /** * Lets Steam know we are about to launch an app and Steam responds with any current pending remote operations * that we may need to wait for * - * @param appId The ID of the app about to be launched - * @param clientId The ID given when authenticating the user [AuthSession.clientID] - * @param machineName The name of the machine that is launching the app - * @param osType The OS type of the machine launching the app + * @param appId The ID of the app about to be launched + * @param clientId The ID given when authenticating the user [AuthSession.clientID] + * @param machineName The name of the machine that is launching the app + * @param ignorePendingOperations Should current remote operations be ignored and app be launched anyway + * @param osType The OS type of the machine launching the app * @return A list of the pending remote operations, empty if none */ // JavaSteam Addition diff --git a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/SteamUser.kt b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/SteamUser.kt index e43ea22f..d14e7031 100644 --- a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/SteamUser.kt +++ b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamuser/SteamUser.kt @@ -9,6 +9,7 @@ import `in`.dragonbra.javasteam.enums.EResult import `in`.dragonbra.javasteam.enums.EUIMode import `in`.dragonbra.javasteam.generated.MsgClientLogon import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesBase.CMsgIPAddress +import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesClientserver2.CMsgClientKickPlayingSession import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesClientserverLogin.CMsgClientLogOff import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesClientserverLogin.CMsgClientLogon import `in`.dragonbra.javasteam.steam.handlers.ClientMsgHandler @@ -179,6 +180,24 @@ class SteamUser : ClientMsgHandler() { client.disconnect() } + /** + * Kicks any Steam client currently in a playing session + * + * @param onlyStopGame Whether to only stop the game or quit the Steam client as well + */ + // JavaSteam Addition + fun kickPlayingSession( + onlyStopGame: Boolean = false, + ) { + val request = ClientMsgProtobuf( + CMsgClientKickPlayingSession::class.java, + EMsg.ClientKickPlayingSession + ).apply { + body.onlyStopGame = onlyStopGame + } + client.send(request) + } + companion object { private fun getCallback(packetMsg: IPacketMsg): CallbackMsg? = when (packetMsg.msgType) { EMsg.ClientLogOnResponse -> LoggedOnCallback(packetMsg) diff --git a/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/clientmetrics.proto b/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/clientmetrics.proto new file mode 100644 index 00000000..ad25ae00 --- /dev/null +++ b/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/clientmetrics.proto @@ -0,0 +1,46 @@ +option java_package = "in.dragonbra.javasteam.protobufs.steamclient"; + +option optimize_for = SPEED; + +message CClientMetrics_ClientBootstrap_RequestInfo { + optional string original_hostname = 1; + optional string actual_hostname = 2; + optional string path = 3; + optional string base_name = 4; + optional bool success = 5; + optional uint32 status_code = 6; + optional string address_of_request_url = 7; + optional uint32 response_time_ms = 8; + optional uint64 bytes_received = 9; + optional uint32 num_retries = 10; +} + +message CClientMetrics_ClientBootstrap_Summary { + optional uint32 launcher_type = 1; + optional uint32 steam_realm = 2; + optional string beta_name = 3; + optional bool download_completed = 4; + optional uint32 total_time_ms = 6; + repeated .CClientMetrics_ClientBootstrap_RequestInfo manifest_requests = 7; + repeated .CClientMetrics_ClientBootstrap_RequestInfo package_requests = 8; +} + +message CClientMetrics_ContentDownloadResponse_Counts { + optional uint32 class_100 = 1; + optional uint32 class_200 = 2; + optional uint32 class_300 = 3; + optional uint32 class_400 = 4; + optional uint32 class_500 = 5; + optional uint32 no_response = 6; + optional uint32 class_unknown = 7; +} + +message CClientMetrics_ContentDownloadResponse_HostCounts { + optional string hostname = 1; + optional uint32 source_type = 2; + optional .CClientMetrics_ContentDownloadResponse_Counts counts = 3; +} + +message CClientMetrics_ContentDownloadResponse_Hosts { + repeated .CClientMetrics_ContentDownloadResponse_HostCounts hosts = 1; +} diff --git a/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_client_objects.proto b/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_client_objects.proto index 8578938b..6db6cc27 100644 --- a/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_client_objects.proto +++ b/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_client_objects.proto @@ -3,7 +3,6 @@ import "in/dragonbra/javasteam/protobufs/steamclient/enums.proto"; option java_package = "in.dragonbra.javasteam.protobufs.steamclient"; option optimize_for = SPEED; -option cc_generic_services = false; enum ECloudPendingRemoteOperation { k_ECloudPendingRemoteOperationNone = 0; diff --git a/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_clientmetrics.steamclient.proto b/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_clientmetrics.steamclient.proto new file mode 100644 index 00000000..a7ea2ffa --- /dev/null +++ b/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_clientmetrics.steamclient.proto @@ -0,0 +1,251 @@ +import "in/dragonbra/javasteam/protobufs/steamclient/steammessages_base.proto"; +import "in/dragonbra/javasteam/protobufs/steamclient/steammessages_unified_base.steamclient.proto"; +import "in/dragonbra/javasteam/protobufs/steamclient/clientmetrics.proto"; +import "in/dragonbra/javasteam/protobufs/steamclient/enums.proto"; + +option java_package = "in.dragonbra.javasteam.protobufs.steamclient"; + +option optimize_for = SPEED; +option java_generic_services = false; + +enum ESteamPipeWorkType { + k_ESteamPipeClientWorkType_Invalid = 0; + k_ESteamPipeClientWorkType_StageFromChunkStores = 1; +} + +enum ESteamPipeOperationType { + k_ESteamPipeOperationType_Invalid = 0; + k_ESteamPipeOperationType_DecryptCPU = 1; + k_ESteamPipeOperationType_DiskRead = 2; + k_ESteamPipeOperationType_DiskWrite = 3; +} + +enum EClipShareMethod { + k_EClipShareMethod_Chat = 1; + k_EClipShareMethod_Clipboard = 2; + k_EClipShareMethod_File = 3; + k_EClipShareMethod_SendClip = 4; + k_EClipShareMethod_SaveToMedia = 5; + k_EClipShareMethod_CreateLink = 6; +} + +enum EClipRangeMethod { + k_EClipRangeMethod_CreateClipButton = 1; + k_EClipRangeMethod_Highlight = 2; + k_EClipRangeMethod_BeginEndButtons = 3; + k_EClipRangeMethod_ContextMenu = 4; + k_EClipRangeMethod_Drag = 5; + k_EClipRangeMethod_EntireClip = 6; + k_EClipRangeMethod_PhaseRecording = 7; +} + +message CClientMetrics_AppInterfaceCreation { + optional string raw_version = 1; + optional string requested_interface_type = 2; +} + +message CClientMetrics_AppInterfaceMethodCounts { + optional string interface_name = 1; + optional string method_name = 2; + optional uint32 call_count = 3; +} + +message CClientMetrics_AppInterfaceStats_Notification { + optional uint64 game_id = 1; + repeated .CClientMetrics_AppInterfaceCreation interfaces_created = 2; + repeated .CClientMetrics_AppInterfaceMethodCounts methods_called = 3; + optional uint32 session_length_seconds = 4; +} + +message CClientMetrics_IPv6Connectivity_Result { + optional uint32 protocol_tested = 1; + optional uint32 connectivity_state = 2; +} + +message CClientMetrics_IPv6Connectivity_Notification { + optional uint32 cell_id = 1; + repeated .CClientMetrics_IPv6Connectivity_Result results = 2; + optional bool private_ip_is_rfc6598 = 3; +} + +message CClientMetrics_SteamPipeWorkStats_Operation { + optional .ESteamPipeOperationType type = 1 [default = k_ESteamPipeOperationType_Invalid]; + optional uint32 num_ops = 2; + optional uint64 num_bytes = 3; + optional uint64 busy_time_ms = 4; + optional uint64 idle_time_ms = 5; + optional uint64 sum_run_time_ms = 6; + optional uint64 sum_wait_time_ms = 7; +} + +message CClientMetrics_SteamPipeWorkStats_Notification { + optional uint32 appid = 1; + optional uint32 depotid = 2; + optional .ESteamPipeWorkType work_type = 3 [default = k_ESteamPipeClientWorkType_Invalid]; + repeated .CClientMetrics_SteamPipeWorkStats_Operation operations = 4; + optional uint32 hardware_type = 5; +} + +message CClientMetrics_ReportReactUsage_Notification { + message RouteData { + optional string route = 1; + optional uint32 count = 2; + } + + message ComponentData { + optional string component = 1; + optional uint32 count = 2; + } + + message ActionData { + optional string action = 1; + optional uint32 count = 2; + } + + optional string product = 1; + optional string version = 2; + repeated .CClientMetrics_ReportReactUsage_Notification.RouteData routes = 3; + repeated .CClientMetrics_ReportReactUsage_Notification.ComponentData components = 4; + repeated .CClientMetrics_ReportReactUsage_Notification.ActionData actions = 5; +} + +message CClientMetrics_ReportClientError_Notification { + message Error { + optional string identifier = 1; + optional string message = 2; + optional uint32 count = 3; + } + + optional string product = 1; + optional string version = 2; + repeated .CClientMetrics_ReportClientError_Notification.Error errors = 3; +} + +message CClientMetrics_ClientBootstrap_Notification { + optional .CClientMetrics_ClientBootstrap_Summary summary = 1; +} + +message CClientMetrics_DownloadRates_Notification { + message StatsInfo { + optional uint32 source_type = 1; + optional uint32 source_id = 2; + optional uint64 bytes = 3; + optional string host_name = 4; + optional uint64 microseconds = 5; + optional bool used_ipv6 = 6; + optional bool proxied = 7; + optional bool used_http2 = 8; + optional uint32 cache_hits = 9; + optional uint32 cache_misses = 10; + optional uint64 hit_bytes = 11; + optional uint64 miss_bytes = 12; + } + + optional uint32 cell_id = 1; + repeated .CClientMetrics_DownloadRates_Notification.StatsInfo stats = 2; + optional uint32 throttling_kbps = 3; + optional uint32 os_type = 4; + optional uint32 device_type = 5; +} + +message CClientMetrics_ContentValidation_Notification { + optional int32 validation_result = 1; + optional uint32 app_id = 2; + optional bool staged_files = 3; + optional bool user_initiated = 4; + optional bool early_out = 5; + optional uint32 chunks_scanned = 6; + optional uint32 chunks_corrupt = 7; + optional uint64 bytes_scanned = 8; + optional uint64 chunk_bytes_corrupt = 9; + optional uint64 total_file_size_corrupt = 10; +} + +message CClientMetrics_CloudAppSyncStats_Notification { + optional uint32 app_id = 1; + optional uint32 platform_type = 2; + optional bool preload = 3; + optional bool blocking_app_launch = 4; + optional uint32 files_uploaded = 5; + optional uint32 files_downloaded = 6; + optional uint32 files_deleted = 7; + optional uint64 bytes_uploaded = 8; + optional uint64 bytes_downloaded = 9; + optional uint64 microsec_total = 10; + optional uint64 microsec_init_caches = 11; + optional uint64 microsec_validate_state = 12; + optional uint64 microsec_ac_launch = 13; + optional uint64 microsec_ac_prep_user_files = 14; + optional uint64 microsec_ac_exit = 15; + optional uint64 microsec_build_sync_list = 16; + optional uint64 microsec_delete_files = 17; + optional uint64 microsec_download_files = 18; + optional uint64 microsec_upload_files = 19; + optional uint32 hardware_type = 20; + optional uint32 files_managed = 21; +} + +message CClientMetrics_ContentDownloadResponse_Counts_Notification { + optional uint32 cell_id = 1; + optional .CClientMetrics_ContentDownloadResponse_Hosts data = 2; +} + +message CClientMetrics_ReportClientArgs_Notification { + repeated string client_args = 1; + optional bool gpu_webview_regkey_disabled = 2; + optional bool suppress_gpu_chrome = 3; + optional bool browser_not_supported = 4; + optional bool hw_accel_video_regkey_disabled = 5; + optional bool mini_mode_enabled = 6; + optional bool fps_counter_enabled = 7; + optional bool library_low_bandwidth_mode_enabled = 8; + optional bool library_low_perf_mode_enabled = 9; + optional int32 gr_mode = 10; +} + +message CClientMetrics_ClipShare_Notification { + optional uint32 eresult = 1 [default = 2]; + optional .EClipShareMethod share_method = 2 [default = k_EClipShareMethod_Chat]; + optional float seconds = 3; + optional uint64 bytes = 4; + optional fixed64 gameid = 5; +} + +message CClientMetrics_ClipRange_Notification { + message RelativeRangeEdge { + optional .EClipRangeMethod original_range_method = 1 [default = k_EClipRangeMethod_CreateClipButton]; + optional .EClipRangeMethod latest_range_method = 2 [default = k_EClipRangeMethod_CreateClipButton]; + optional int32 delta_ms = 3; + } + + optional .EClipRangeMethod original_range_method = 1 [default = k_EClipRangeMethod_CreateClipButton]; + optional .CClientMetrics_ClipRange_Notification.RelativeRangeEdge start = 2; + optional .CClientMetrics_ClipRange_Notification.RelativeRangeEdge end = 3; + optional float seconds = 4; + optional fixed64 gameid = 5; +} + +message CClientMetrics_EndGameRecording_Notification { + optional .EGameRecordingType recording_type = 1 [default = k_EGameRecordingType_Unknown]; + optional float seconds = 2; + optional uint64 bytes = 3; + optional fixed64 gameid = 4; + optional bool instant_clip = 5; +} + +service ClientMetrics { + rpc ClientAppInterfaceStatsReport (.CClientMetrics_AppInterfaceStats_Notification) returns (.NoResponse); + rpc ClientIPv6ConnectivityReport (.CClientMetrics_IPv6Connectivity_Notification) returns (.NoResponse); + rpc SteamPipeWorkStatsReport (.CClientMetrics_SteamPipeWorkStats_Notification) returns (.NoResponse); + rpc ReportReactUsage (.CClientMetrics_ReportReactUsage_Notification) returns (.NoResponse); + rpc ReportClientError (.CClientMetrics_ReportClientError_Notification) returns (.NoResponse); + rpc ClientBootstrapReport (.CClientMetrics_ClientBootstrap_Notification) returns (.NoResponse); + rpc ClientDownloadRatesReport (.CClientMetrics_DownloadRates_Notification) returns (.NoResponse); + rpc ClientContentValidationReport (.CClientMetrics_ContentValidation_Notification) returns (.NoResponse); + rpc ClientCloudAppSyncStats (.CClientMetrics_CloudAppSyncStats_Notification) returns (.NoResponse); + rpc ClientDownloadResponseCodeCounts (.CClientMetrics_ContentDownloadResponse_Counts_Notification) returns (.NoResponse); + rpc ReportClientArgs (.CClientMetrics_ReportClientArgs_Notification) returns (.NoResponse); + rpc ReportClipShare (.CClientMetrics_ClipShare_Notification) returns (.NoResponse); + rpc ReportClipRange (.CClientMetrics_ClipRange_Notification) returns (.NoResponse); + rpc ReportEndGameRecording (.CClientMetrics_EndGameRecording_Notification) returns (.NoResponse); +} diff --git a/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_cloud.steamclient.proto b/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_cloud.steamclient.proto index db885e05..a2b39123 100644 --- a/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_cloud.steamclient.proto +++ b/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_cloud.steamclient.proto @@ -8,8 +8,6 @@ option java_package = "in.dragonbra.javasteam.protobufs.steamclient"; option optimize_for = SPEED; option java_generic_services = false; -option cc_generic_services = true; - message CCloud_ClientLogUploadCheck_Notification { optional uint64 client_id = 1; } diff --git a/src/test/java/in/dragonbra/javasteam/rpc/UnifiedInterfaceTest.kt b/src/test/java/in/dragonbra/javasteam/rpc/UnifiedInterfaceTest.kt index aa5eeaac..4ed11afb 100644 --- a/src/test/java/in/dragonbra/javasteam/rpc/UnifiedInterfaceTest.kt +++ b/src/test/java/in/dragonbra/javasteam/rpc/UnifiedInterfaceTest.kt @@ -55,6 +55,9 @@ class UnifiedInterfaceTest { "ChatUsability.kt", "ChatUsabilityClient.kt", "ClanChatRooms.kt", + "ClientMetrics.kt", + "Cloud.kt", + "CloudClient.kt", "CloudGaming.kt", "ContentServerDirectory.kt", "EmbeddedClient.kt", @@ -72,8 +75,6 @@ class UnifiedInterfaceTest { "RemoteClientSteamClient.kt", "TwoFactor.kt", "UserAccount.kt", - "Cloud.kt", - "CloudClient.kt", ) } }