mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
pdm: Updated/fixed sysver compat, updated structs.
This commit is contained in:
parent
4ece4e5b8f
commit
c3e110988a
@ -38,41 +38,71 @@ typedef enum {
|
|||||||
PdmPlayLogPolicy_Unknown3 = 3, ///< [10.0.0+] The cmds which require ::PdmPlayLogPolicy_All, now also allow value 3 if the cmd input flag is set.
|
PdmPlayLogPolicy_Unknown3 = 3, ///< [10.0.0+] The cmds which require ::PdmPlayLogPolicy_All, now also allow value 3 if the cmd input flag is set.
|
||||||
} PdmPlayLogPolicy;
|
} PdmPlayLogPolicy;
|
||||||
|
|
||||||
/// AppletEvent.
|
/// AppletEventV1. AppletEvent for [1.0.0-15.0.1], converted to \ref PdmAppletEvent when needed.
|
||||||
/// Timestamp format, converted from PosixTime: total minutes since epoch UTC 1999/12/31 00:00:00.
|
/// Timestamp format, converted from PosixTime: total minutes since epoch UTC 1999/12/31 00:00:00.
|
||||||
/// See \ref pdmPlayTimestampToPosix.
|
/// See \ref pdmPlayTimestampToPosix.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u64 program_id; ///< ProgramId.
|
u64 program_id; ///< ProgramId.
|
||||||
u32 entry_index; ///< Entry index.
|
u32 entry_index; ///< Entry index.
|
||||||
u32 timestampUser; ///< See PdmPlayEvent::timestampUser, with the above timestamp format.
|
u32 timestamp_user; ///< See PdmPlayEvent::timestamp_user, with the above timestamp format.
|
||||||
u32 timestampNetwork; ///< See PdmPlayEvent::timestampNetwork, with the above timestamp format.
|
u32 timestamp_network; ///< See PdmPlayEvent::timestamp_network, with the above timestamp format.
|
||||||
u8 eventType; ///< \ref PdmAppletEventType
|
u8 event_type; ///< \ref PdmAppletEventType
|
||||||
u8 pad[3]; ///< Padding.
|
u8 pad[3]; ///< Padding.
|
||||||
|
} PdmAppletEventV1;
|
||||||
|
|
||||||
|
/// AppletEvent. AppletEvent for [16.0.0+], converted from \ref PdmAppletEventV1 on [1.0.0-15.0.1].
|
||||||
|
typedef struct {
|
||||||
|
u64 program_id; ///< ProgramId.
|
||||||
|
u32 entry_index; ///< Entry index.
|
||||||
|
u32 pad; ///< Padding
|
||||||
|
u64 timestamp_user; ///< See PdmPlayEvent::timestamp_user.
|
||||||
|
u64 timestamp_network; ///< See PdmPlayEvent::timestamp_network.
|
||||||
|
u8 event_type; ///< \ref PdmAppletEventType
|
||||||
|
u8 pad2[7]; ///< Padding.
|
||||||
} PdmAppletEvent;
|
} PdmAppletEvent;
|
||||||
|
|
||||||
/// PlayStatistics
|
/// PlayStatisticsV1. PlayStatistics for [1.0.0-15.0.1], converted to \ref PdmPlayStatistics when needed.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u64 application_id; ///< ApplicationId.
|
u64 program_id; ///< ProgramId.
|
||||||
|
|
||||||
u32 first_entry_index; ///< Entry index for the first time the application was played.
|
u32 first_entry_index; ///< Entry index for the first time the program was played.
|
||||||
u32 first_timestampUser; ///< See PdmAppletEvent::timestampUser. This is for the first time the application was played.
|
u32 first_timestamp_user; ///< See PdmAppletEventV1::timestamp_user. This is for the first time the program was played.
|
||||||
u32 first_timestampNetwork; ///< See PdmAppletEvent::timestampNetwork. This is for the first time the application was played.
|
u32 first_timestamp_network; ///< See PdmAppletEventV1::timestamp_network. This is for the first time the program was played.
|
||||||
|
|
||||||
u32 last_entry_index; ///< Entry index for the last time the application was played.
|
u32 last_entry_index; ///< Entry index for the last time the program was played.
|
||||||
u32 last_timestampUser; ///< See PdmAppletEvent::timestampUser. This is for the last time the application was played.
|
u32 last_timestamp_user; ///< See PdmAppletEventV1::timestamp_user. This is for the last time the program was played.
|
||||||
u32 last_timestampNetwork; ///< See PdmAppletEvent::timestampNetwork. This is for the last time the application was played.
|
u32 last_timestamp_network; ///< See PdmAppletEventV1::timestamp_network. This is for the last time the program was played.
|
||||||
|
|
||||||
u32 playtimeMinutes; ///< Total play-time in minutes.
|
u32 playtime_minutes; ///< Total play-time in minutes.
|
||||||
u32 totalLaunches; ///< Total times the application was launched.
|
u32 total_launches; ///< Total times the program was launched.
|
||||||
|
} PdmPlayStatisticsV1;
|
||||||
|
|
||||||
|
/// PlayStatistics. PlayStatistics for [16.0.0+], converted from \ref PdmPlayStatisticsV1 on [1.0.0-15.0.1].
|
||||||
|
typedef struct {
|
||||||
|
u64 program_id; ///< ProgramId.
|
||||||
|
|
||||||
|
u32 first_entry_index; ///< Entry index for the first time the program was played.
|
||||||
|
u32 pad; ///< Padding
|
||||||
|
u64 first_timestamp_user; ///< See PdmAppletEvent::timestamp_user. This is for the first time the program was played, in PosixTime.
|
||||||
|
u64 first_timestamp_network; ///< See PdmAppletEvent::timestamp_network. This is for the first time the program was played, in PosixTime.
|
||||||
|
|
||||||
|
u32 last_entry_index; ///< Entry index for the last time the program was played.
|
||||||
|
u32 pad2; ///< Padding
|
||||||
|
u64 last_timestamp_user; ///< See PdmAppletEvent::timestamp_user. This is for the last time the program was played, in PosixTime.
|
||||||
|
u64 last_timestamp_network; ///< See PdmAppletEvent::timestamp_network. This is for the last time the program was played, in PosixTime.
|
||||||
|
|
||||||
|
u64 playtime; ///< Total play-time in nanoseconds.
|
||||||
|
u32 total_launches; ///< Total times the program was launched.
|
||||||
|
u32 pad3; ///< Padding
|
||||||
} PdmPlayStatistics;
|
} PdmPlayStatistics;
|
||||||
|
|
||||||
/// LastPlayTime.
|
/// LastPlayTime.
|
||||||
/// This contains data from the last time the application was played.
|
/// This contains data from the last time the application was played.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u64 application_id; ///< ApplicationId.
|
u64 application_id; ///< ApplicationId.
|
||||||
u32 timestampUser; ///< See PdmAppletEvent::timestampUser.
|
u32 timestamp_user; ///< See PdmAppletEventV1::timestamp_user.
|
||||||
u32 timestampNetwork; ///< See PdmAppletEvent::timestampNetwork.
|
u32 timestamp_network; ///< See PdmAppletEventV1::timestamp_network.
|
||||||
u32 lastPlayedMinutes; ///< Total minutes since the application was last played.
|
u32 last_played_minutes; ///< Total minutes since the application was last played.
|
||||||
u8 flag; ///< Flag indicating whether the above field is set.
|
u8 flag; ///< Flag indicating whether the above field is set.
|
||||||
u8 pad[3]; ///< Padding.
|
u8 pad[3]; ///< Padding.
|
||||||
} PdmLastPlayTime;
|
} PdmLastPlayTime;
|
||||||
@ -98,10 +128,10 @@ typedef struct {
|
|||||||
u32 data;
|
u32 data;
|
||||||
} unk_x8;
|
} unk_x8;
|
||||||
|
|
||||||
u8 appletId; ///< \ref AppletId
|
u8 applet_id; ///< \ref AppletId
|
||||||
u8 storageId; ///< \ref NcmStorageId
|
u8 storage_id; ///< \ref NcmStorageId
|
||||||
u8 logPolicy; ///< \ref PdmPlayLogPolicy
|
u8 log_policy; ///< \ref PdmPlayLogPolicy
|
||||||
u8 eventType; ///< \ref PdmAppletEventType
|
u8 event_type; ///< \ref PdmAppletEventType
|
||||||
u8 unused[0xc]; ///< Unused.
|
u8 unused[0xc]; ///< Unused.
|
||||||
} applet;
|
} applet;
|
||||||
|
|
||||||
@ -114,34 +144,59 @@ typedef struct {
|
|||||||
struct {
|
struct {
|
||||||
u8 value; ///< Input value from the pdm:ntfy command.
|
u8 value; ///< Input value from the pdm:ntfy command.
|
||||||
u8 unused[0x1b]; ///< Unused.
|
u8 unused[0x1b]; ///< Unused.
|
||||||
} powerStateChange;
|
} power_state_change;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u8 value; ///< Input value from the pdm:ntfy command.
|
u8 value; ///< Input value from the pdm:ntfy command.
|
||||||
u8 unused[0x1b]; ///< Unused.
|
u8 unused[0x1b]; ///< Unused.
|
||||||
} operationModeChange;
|
} operation_mode_change;
|
||||||
|
|
||||||
u8 data[0x1c];
|
u8 data[0x1c];
|
||||||
} eventData; ///< ProgramId/ApplicationId/userId stored within here have the u32 low/high swapped in each u64.
|
} event_data; ///< ProgramId/ApplicationId/userId stored within here have the u32 low/high swapped in each u64.
|
||||||
|
|
||||||
u8 playEventType; ///< \ref PdmPlayEventType. Controls which struct in the above eventData is used. ::PdmPlayEventType_Initialize doesn't use eventData.
|
u8 play_event_type; ///< \ref PdmPlayEventType. Controls which struct in the above event_data is used. ::PdmPlayEventType_Initialize doesn't use event_data.
|
||||||
u8 pad[3]; ///< Padding.
|
u8 pad[3]; ///< Padding.
|
||||||
|
|
||||||
u64 timestampUser; ///< PosixTime timestamp from StandardUserSystemClock.
|
u64 timestamp_user; ///< PosixTime timestamp from StandardUserSystemClock.
|
||||||
u64 timestampNetwork; ///< PosixTime timestamp from StandardNetworkSystemClock.
|
u64 timestamp_network; ///< PosixTime timestamp from StandardNetworkSystemClock.
|
||||||
u64 timestampSteady; ///< Timestamp in seconds derived from StandardSteadyClock.
|
u64 timestamp_steady; ///< Timestamp in seconds derived from StandardSteadyClock.
|
||||||
} PdmPlayEvent;
|
} PdmPlayEvent;
|
||||||
|
|
||||||
/// AccountEvent
|
/// AccountEventV3. AccountEvent for [3.0.0-9.2.0], converted to \ref PdmAccountEvent when needed.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
AccountUid uid; ///< \ref AccountUid
|
AccountUid uid; ///< \ref AccountUid
|
||||||
u32 entry_index; ///< Entry index.
|
u32 entry_index; ///< Entry index.
|
||||||
u8 pad[4]; ///< Padding.
|
u8 pad[4]; ///< Padding.
|
||||||
u64 timestampUser; ///< See PdmPlayEvent::timestampUser.
|
u64 timestamp_user; ///< See PdmPlayEvent::timestamp_user.
|
||||||
u64 timestampNetwork; ///< See PdmPlayEvent::timestampNetwork.
|
u64 timestamp_network; ///< See PdmPlayEvent::timestamp_network.
|
||||||
u64 timestampSteady; ///< See PdmPlayEvent::timestampSteady.
|
u64 timestamp_steady; ///< See PdmPlayEvent::timestamp_steady.
|
||||||
u8 type; ///< See PdmPlayEvent::eventData::account::type.
|
u8 type; ///< See PdmPlayEvent::event_data::account::type.
|
||||||
u8 pad_x31[7]; ///< Padding.
|
u8 pad2[7]; ///< Padding.
|
||||||
|
} PdmAccountEventV3;
|
||||||
|
|
||||||
|
/// AccountEventV10. AccountEvent for [10.0.0-15.0.1], converted to \ref PdmAccountEvent when needed.
|
||||||
|
typedef struct {
|
||||||
|
AccountUid uid; ///< \ref AccountUid
|
||||||
|
u64 program_id; ///< ProgramId
|
||||||
|
u32 entry_index; ///< Entry index.
|
||||||
|
u8 pad[4]; ///< Padding.
|
||||||
|
u64 timestamp_user; ///< See PdmPlayEvent::timestamp_user.
|
||||||
|
u64 timestamp_network; ///< See PdmPlayEvent::timestamp_network.
|
||||||
|
u64 timestamp_steady; ///< See PdmPlayEvent::timestamp_steady.
|
||||||
|
u8 type; ///< See PdmPlayEvent::event_data::account::type.
|
||||||
|
u8 pad2[7]; ///< Padding.
|
||||||
|
} PdmAccountEventV10;
|
||||||
|
|
||||||
|
/// AccountEvent. AccountEvent for [16.0.0+], converted from the older structs when needed.
|
||||||
|
typedef struct {
|
||||||
|
AccountUid uid; ///< \ref AccountUid
|
||||||
|
u64 program_id; ///< [10.0.0+] ProgramId
|
||||||
|
u32 entry_index; ///< Entry index.
|
||||||
|
u8 pad[4]; ///< Padding.
|
||||||
|
u64 timestamp_user; ///< See PdmPlayEvent::timestamp_user.
|
||||||
|
u64 timestamp_network; ///< See PdmPlayEvent::timestamp_network.
|
||||||
|
u8 type; ///< See PdmPlayEvent::event_data::account::type.
|
||||||
|
u8 pad2[7]; ///< Padding.
|
||||||
} PdmAccountEvent;
|
} PdmAccountEvent;
|
||||||
|
|
||||||
/// AccountPlayEvent.
|
/// AccountPlayEvent.
|
||||||
@ -157,8 +212,8 @@ typedef struct {
|
|||||||
/// ApplicationPlayStatistics
|
/// ApplicationPlayStatistics
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u64 application_id; ///< ApplicationId.
|
u64 application_id; ///< ApplicationId.
|
||||||
u64 totalPlayTime; ///< Total play-time in nanoseconds.
|
u64 playtime; ///< Total play-time in nanoseconds.
|
||||||
u64 totalLaunches; ///< Total times the application was launched.
|
u64 total_launches; ///< Total times the application was launched.
|
||||||
} PdmApplicationPlayStatistics;
|
} PdmApplicationPlayStatistics;
|
||||||
|
|
||||||
/// Initialize pdm:qry.
|
/// Initialize pdm:qry.
|
||||||
@ -226,6 +281,7 @@ Result pdmqryGetAvailablePlayEventRange(s32 *total_entries, s32 *start_entry_ind
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets a list of \ref PdmAccountEvent.
|
* @brief Gets a list of \ref PdmAccountEvent.
|
||||||
|
* @note Only available with [3.0.0+].
|
||||||
* @param[in] entry_index Start entry index.
|
* @param[in] entry_index Start entry index.
|
||||||
* @param[out] events Output \ref PdmAccountEvent array.
|
* @param[out] events Output \ref PdmAccountEvent array.
|
||||||
* @param[in] count Max entries in the output array.
|
* @param[in] count Max entries in the output array.
|
||||||
@ -265,7 +321,7 @@ Result pdmqryGetAvailableAccountPlayEventRange(AccountUid uid, s32 *total_entrie
|
|||||||
Result pdmqryQueryRecentlyPlayedApplication(AccountUid uid, bool flag, u64 *application_ids, s32 count, s32 *total_out);
|
Result pdmqryQueryRecentlyPlayedApplication(AccountUid uid, bool flag, u64 *application_ids, s32 count, s32 *total_out);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets an Event which is signaled when logging a new \ref PdmPlayEvent which would be available via \ref pdmqryQueryAccountEvent, where PdmPlayEvent::eventData::account::type is 0.
|
* @brief Gets an Event which is signaled when logging a new \ref PdmPlayEvent which would be available via \ref pdmqryQueryAccountEvent, where PdmPlayEvent::event_data::account::type is 0.
|
||||||
* @note Only available with [6.0.0-14.1.2].
|
* @note Only available with [6.0.0-14.1.2].
|
||||||
* @note The Event must be closed by the user once finished with it.
|
* @note The Event must be closed by the user once finished with it.
|
||||||
* @param[out] out_event Output Event with autoclear=false.
|
* @param[out] out_event Output Event with autoclear=false.
|
||||||
|
@ -20,6 +20,60 @@ Service* pdmqryGetServiceSession(void) {
|
|||||||
return &g_pdmqrySrv;
|
return &g_pdmqrySrv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _pdmConvertAppletEventFromV1(const PdmAppletEventV1 *in, PdmAppletEvent *out) {
|
||||||
|
memset(out, 0, sizeof(*out));
|
||||||
|
|
||||||
|
out->program_id = in->program_id;
|
||||||
|
|
||||||
|
out->entry_index = in->entry_index;
|
||||||
|
out->timestamp_user = pdmPlayTimestampToPosix(in->timestamp_user);
|
||||||
|
out->timestamp_network = pdmPlayTimestampToPosix(in->timestamp_network);
|
||||||
|
|
||||||
|
out->event_type = in->event_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _pdmConvertPlayStatisticsFromV1(const PdmPlayStatisticsV1 *in, PdmPlayStatistics *out) {
|
||||||
|
memset(out, 0, sizeof(*out));
|
||||||
|
|
||||||
|
out->program_id = in->program_id;
|
||||||
|
|
||||||
|
out->first_entry_index = in->first_entry_index;
|
||||||
|
out->first_timestamp_user = pdmPlayTimestampToPosix(in->first_timestamp_user);
|
||||||
|
out->first_timestamp_network = pdmPlayTimestampToPosix(in->first_timestamp_network);
|
||||||
|
|
||||||
|
out->last_entry_index = in->last_entry_index;
|
||||||
|
out->last_timestamp_user = pdmPlayTimestampToPosix(in->last_timestamp_user);
|
||||||
|
out->last_timestamp_network = pdmPlayTimestampToPosix(in->last_timestamp_network);
|
||||||
|
|
||||||
|
out->playtime = ((u64)in->playtime_minutes) * 60 * 1000000000UL;
|
||||||
|
out->total_launches = in->total_launches;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _pdmConvertAccountEventFromV3(const PdmAccountEventV3 *in, PdmAccountEvent *out) {
|
||||||
|
memset(out, 0, sizeof(*out));
|
||||||
|
|
||||||
|
out->uid = in->uid;
|
||||||
|
|
||||||
|
out->entry_index = in->entry_index;
|
||||||
|
out->timestamp_user = in->timestamp_user;
|
||||||
|
out->timestamp_network = in->timestamp_network;
|
||||||
|
|
||||||
|
out->type = in->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _pdmConvertAccountEventFromV10(const PdmAccountEventV10 *in, PdmAccountEvent *out) {
|
||||||
|
memset(out, 0, sizeof(*out));
|
||||||
|
|
||||||
|
out->uid = in->uid;
|
||||||
|
out->program_id = in->program_id;
|
||||||
|
|
||||||
|
out->entry_index = in->entry_index;
|
||||||
|
out->timestamp_user = in->timestamp_user;
|
||||||
|
out->timestamp_network = in->timestamp_network;
|
||||||
|
|
||||||
|
out->type = in->type;
|
||||||
|
}
|
||||||
|
|
||||||
static Result _pdmCmdGetEvent(Service* srv, Event* out_event, bool autoclear, u32 cmd_id) {
|
static Result _pdmCmdGetEvent(Service* srv, Event* out_event, bool autoclear, u32 cmd_id) {
|
||||||
Handle event = INVALID_HANDLE;
|
Handle event = INVALID_HANDLE;
|
||||||
Result rc = serviceDispatch(srv, cmd_id,
|
Result rc = serviceDispatch(srv, cmd_id,
|
||||||
@ -41,28 +95,49 @@ static Result _pdmqryQueryEvent(s32 entry_index, void* events, size_t entrysize,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result pdmqryQueryAppletEvent(s32 entry_index, bool flag, PdmAppletEvent *events, s32 count, s32 *total_out) {
|
Result pdmqryQueryAppletEvent(s32 entry_index, bool flag, PdmAppletEvent *events, s32 count, s32 *total_out) {
|
||||||
|
Result rc=0;
|
||||||
|
|
||||||
if (hosversionBefore(10,0,0)) {
|
if (hosversionBefore(10,0,0)) {
|
||||||
return serviceDispatchInOut(&g_pdmqrySrv, 0, entry_index, *total_out,
|
rc = serviceDispatchInOut(&g_pdmqrySrv, 0, entry_index, *total_out,
|
||||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||||
.buffers = { { events, count*sizeof(PdmAppletEvent) } },
|
.buffers = { { events, count*sizeof(PdmAppletEvent) } },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
const struct {
|
const struct {
|
||||||
u8 flag;
|
u8 flag;
|
||||||
u8 pad[3];
|
u8 pad[3];
|
||||||
s32 entry_index;
|
s32 entry_index;
|
||||||
} in = { flag!=0, {0}, entry_index };
|
} in = { flag!=0, {0}, entry_index };
|
||||||
|
|
||||||
return serviceDispatchInOut(&g_pdmqrySrv, 0, in, *total_out,
|
size_t entrysize = hosversionBefore(16,0,0) ? sizeof(PdmAppletEventV1) : sizeof(PdmAppletEvent);
|
||||||
|
rc = serviceDispatchInOut(&g_pdmqrySrv, 0, in, *total_out,
|
||||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
|
||||||
.buffers = { { events, count*sizeof(PdmAppletEvent) } },
|
.buffers = { { events, count*entrysize } },
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc) && hosversionBefore(16,0,0)) {
|
||||||
|
s32 end = count;
|
||||||
|
if (total_out && *total_out < end) end = *total_out;
|
||||||
|
PdmAppletEventV1 *v1_in = (PdmAppletEventV1*)events;
|
||||||
|
for (s32 i=end-1; i>=0; i--) { // V1 is smaller than latest, so loop backwards.
|
||||||
|
PdmAppletEventV1 tmp = v1_in[i];
|
||||||
|
_pdmConvertAppletEventFromV1(&tmp, &events[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result pdmqryQueryPlayStatisticsByApplicationId(u64 application_id, bool flag, PdmPlayStatistics *stats) {
|
Result pdmqryQueryPlayStatisticsByApplicationId(u64 application_id, bool flag, PdmPlayStatistics *stats) {
|
||||||
|
PdmPlayStatisticsV1 tmp={};
|
||||||
|
Result rc=0;
|
||||||
|
|
||||||
if (hosversionBefore(10,0,0)) {
|
if (hosversionBefore(10,0,0)) {
|
||||||
return serviceDispatchInOut(&g_pdmqrySrv, 4, application_id, *stats);
|
rc = serviceDispatchInOut(&g_pdmqrySrv, 4, application_id, tmp);
|
||||||
|
if (R_SUCCEEDED(rc)) _pdmConvertPlayStatisticsFromV1(&tmp, stats);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct {
|
const struct {
|
||||||
@ -71,17 +146,28 @@ Result pdmqryQueryPlayStatisticsByApplicationId(u64 application_id, bool flag, P
|
|||||||
u64 application_id;
|
u64 application_id;
|
||||||
} in = { flag!=0, {0}, application_id };
|
} in = { flag!=0, {0}, application_id };
|
||||||
|
|
||||||
return serviceDispatchInOut(&g_pdmqrySrv, 4, in, *stats);
|
if (hosversionBefore(16,0,0)) {
|
||||||
|
Result rc = serviceDispatchInOut(&g_pdmqrySrv, 4, in, tmp);
|
||||||
|
if (R_SUCCEEDED(rc)) _pdmConvertPlayStatisticsFromV1(&tmp, stats);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = serviceDispatchInOut(&g_pdmqrySrv, 4, in, *stats);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(u64 application_id, AccountUid uid, bool flag, PdmPlayStatistics *stats) {
|
Result pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(u64 application_id, AccountUid uid, bool flag, PdmPlayStatistics *stats) {
|
||||||
|
PdmPlayStatisticsV1 tmp={};
|
||||||
|
Result rc=0;
|
||||||
|
|
||||||
if (hosversionBefore(10,0,0)) {
|
if (hosversionBefore(10,0,0)) {
|
||||||
const struct {
|
const struct {
|
||||||
u64 application_id;
|
u64 application_id;
|
||||||
AccountUid uid;
|
AccountUid uid;
|
||||||
} in = { application_id, uid };
|
} in = { application_id, uid };
|
||||||
|
|
||||||
return serviceDispatchInOut(&g_pdmqrySrv, 5, in, *stats);
|
rc = serviceDispatchInOut(&g_pdmqrySrv, 5, in, tmp);
|
||||||
|
if (R_SUCCEEDED(rc)) _pdmConvertPlayStatisticsFromV1(&tmp, stats);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct {
|
const struct {
|
||||||
@ -91,7 +177,13 @@ Result pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(u64 application_
|
|||||||
AccountUid uid;
|
AccountUid uid;
|
||||||
} in = { flag!=0, {0}, application_id, uid };
|
} in = { flag!=0, {0}, application_id, uid };
|
||||||
|
|
||||||
return serviceDispatchInOut(&g_pdmqrySrv, 5, in, *stats);
|
if (hosversionBefore(16,0,0)) {
|
||||||
|
Result rc = serviceDispatchInOut(&g_pdmqrySrv, 5, in, tmp);
|
||||||
|
if (R_SUCCEEDED(rc)) _pdmConvertPlayStatisticsFromV1(&tmp, stats);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = serviceDispatchInOut(&g_pdmqrySrv, 5, in, *stats);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result pdmqryQueryLastPlayTime(bool flag, PdmLastPlayTime *playtimes, const u64 *application_ids, s32 count, s32 *total_out) {
|
Result pdmqryQueryLastPlayTime(bool flag, PdmLastPlayTime *playtimes, const u64 *application_ids, s32 count, s32 *total_out) {
|
||||||
@ -142,7 +234,50 @@ Result pdmqryGetAvailablePlayEventRange(s32 *total_entries, s32 *start_entry_ind
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result pdmqryQueryAccountEvent(s32 entry_index, PdmAccountEvent *events, s32 count, s32 *total_out) {
|
Result pdmqryQueryAccountEvent(s32 entry_index, PdmAccountEvent *events, s32 count, s32 *total_out) {
|
||||||
return _pdmqryQueryEvent(entry_index, events, sizeof(PdmAccountEvent), count, total_out, 10);
|
if (hosversionBefore(3,0,0))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||||
|
|
||||||
|
size_t entrysize = sizeof(PdmAccountEventV3);
|
||||||
|
u32 ver=0;
|
||||||
|
if (hosversionBetween(10, 16)) {
|
||||||
|
entrysize = sizeof(PdmAccountEventV10);
|
||||||
|
ver=1;
|
||||||
|
}
|
||||||
|
else if (hosversionAtLeast(16,0,0)) {
|
||||||
|
entrysize = sizeof(PdmAccountEvent);
|
||||||
|
ver=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result rc=0;
|
||||||
|
if (ver!=1) rc = _pdmqryQueryEvent(entry_index, events, entrysize, count, total_out, 10);
|
||||||
|
if (R_SUCCEEDED(rc) && ver==0) {
|
||||||
|
s32 end = count;
|
||||||
|
if (total_out && *total_out < end) end = *total_out;
|
||||||
|
PdmAccountEventV3 *v3_in = (PdmAccountEventV3*)events;
|
||||||
|
for (s32 i=0; i<end; i++) {
|
||||||
|
PdmAccountEventV3 tmp = v3_in[i];
|
||||||
|
_pdmConvertAccountEventFromV3(&tmp, &events[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ver==1) { // V10 needs special handling since it's larger than latest.
|
||||||
|
PdmAccountEventV10 v10_tmp[4]={};
|
||||||
|
s32 tmp_out=0;
|
||||||
|
if (total_out) *total_out = 0;
|
||||||
|
|
||||||
|
for (s32 i=0; i<count; i+=4) {
|
||||||
|
size_t cur_count = 4;
|
||||||
|
if (count-i < cur_count) cur_count = count-i;
|
||||||
|
rc = _pdmqryQueryEvent(entry_index+i, v10_tmp, entrysize, cur_count, &tmp_out, 10);
|
||||||
|
if (R_FAILED(rc) || tmp_out<=0) break;
|
||||||
|
if (tmp_out>cur_count) tmp_out = cur_count;
|
||||||
|
if (total_out) *total_out += tmp_out;
|
||||||
|
for (s32 j=0; j<tmp_out; j++) {
|
||||||
|
_pdmConvertAccountEventFromV10(&v10_tmp[j], &events[i+j]);
|
||||||
|
}
|
||||||
|
if (tmp_out < 4) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result pdmqryQueryAccountPlayEvent(s32 entry_index, AccountUid uid, PdmAccountPlayEvent *events, s32 count, s32 *total_out) {
|
Result pdmqryQueryAccountPlayEvent(s32 entry_index, AccountUid uid, PdmAccountPlayEvent *events, s32 count, s32 *total_out) {
|
||||||
|
Loading…
Reference in New Issue
Block a user