Skip to content

Commit

Permalink
Merge pull request #303 from oxters168/more-launch-funcs
Browse files Browse the repository at this point in the history
More launch funcs
  • Loading branch information
LossyDragon authored Dec 22, 2024
2 parents 1b5b2a3 + 9c1110a commit 7290ebe
Show file tree
Hide file tree
Showing 8 changed files with 443 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

/**
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -48,6 +51,11 @@ class SteamCloud : ClientMsgHandler() {
?: throw NullPointerException("Unable to get SteamUnifiedMessages handler")
unifiedMessages.createService<Cloud>()
}
private val clientMetrics: ClientMetrics by lazy {
val unifiedMessages = client.getHandler(SteamUnifiedMessages::class.java)
?: throw NullPointerException("Unable to get SteamUnifiedMessages handler")
unifiedMessages.createService<ClientMetrics>()
}

/**
* Requests details for a specific item of user generated content from the Steam servers.
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.Builder>(
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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 7290ebe

Please sign in to comment.