first commit

This commit is contained in:
murdle
2026-03-01 02:38:58 +02:00
commit 19250b9db4
19111 changed files with 4358159 additions and 0 deletions

View File

@@ -0,0 +1,167 @@
#include "stdafx.h"
#include "Include\SenClientMain.h"
#include "Include\SenClientDynamicConfig.h"
#include "DynamicConfigurations.h"
MinecraftDynamicConfigurations::Dynamic_Config_Trial_Data MinecraftDynamicConfigurations::trialData;
bool MinecraftDynamicConfigurations::s_bFirstUpdateStarted = false;
bool MinecraftDynamicConfigurations::s_bUpdatedConfigs[MinecraftDynamicConfigurations::eDynamic_Config_Max];
MinecraftDynamicConfigurations::EDynamic_Configs MinecraftDynamicConfigurations::s_eCurrentConfig = MinecraftDynamicConfigurations::eDynamic_Config_Max;
size_t MinecraftDynamicConfigurations::s_currentConfigSize = 0;
size_t MinecraftDynamicConfigurations::s_dataWrittenSize = 0;
byte *MinecraftDynamicConfigurations::s_dataWritten = NULL;
void MinecraftDynamicConfigurations::Tick()
{
if(!s_bFirstUpdateStarted)
{
UpdateAllConfigurations();
s_bFirstUpdateStarted = true;
}
}
DWORD MinecraftDynamicConfigurations::GetTrialTime()
{
return trialData.trialTimeSeconds;
}
void MinecraftDynamicConfigurations::UpdateAllConfigurations()
{
for(DWORD i = 0; i < eDynamic_Config_Max; ++i)
{
s_bUpdatedConfigs[i] = false;
}
UpdateNextConfiguration();
}
void MinecraftDynamicConfigurations::UpdateNextConfiguration()
{
EDynamic_Configs update = eDynamic_Config_Max;
for(DWORD i = 0; i < eDynamic_Config_Max; ++i)
{
if(!s_bUpdatedConfigs[i])
{
update = (EDynamic_Configs)i;
break;
}
}
if( update < eDynamic_Config_Max )
{
UpdateConfiguration( update );
}
}
void MinecraftDynamicConfigurations::UpdateConfiguration(EDynamic_Configs id)
{
app.DebugPrintf("DynamicConfig: Attempting to update dynamic configuration %d\n", id);
HRESULT hr = Sentient::SenDynamicConfigGetSize( id, &s_currentConfigSize, &MinecraftDynamicConfigurations::GetSizeCompletedCallback, NULL);
switch(hr)
{
case S_OK:
s_eCurrentConfig = id;
//The server call was spawned successfully.
break;
case E_FAIL:
app.DebugPrintf("DynamicConfig: Failed to get size for config\n");
//Sentient failed to spawn the call to the server.
//An unknown error occurred. For more information, see the debug log that is available when you compile your application against the debug version of the library (SenCoreD.lib).
break;
case Sentient::SENTIENT_E_NOT_INITIALIZED:
app.DebugPrintf("DynamicConfig: Failed to get size for config as sentient not initialized\n");
//Sentient is not initialized. You must call SentientInitialize before you call this function.
break;
case E_POINTER:
app.DebugPrintf("DynamicConfig: Failed to get size for config as pointer is invalid\n");
//The out_size pointer is NULL.
break;
}
if(FAILED(hr) )
{
s_bUpdatedConfigs[s_eCurrentConfig] = true;
UpdateNextConfiguration();
}
}
void MinecraftDynamicConfigurations::GetSizeCompletedCallback(HRESULT taskResult, void *userCallbackData)
{
if( HRESULT_SUCCEEDED(taskResult) )
{
s_dataWritten = new byte[s_currentConfigSize];
HRESULT hr = Sentient::SenDynamicConfigGetBytes(
s_eCurrentConfig,
s_currentConfigSize,
&s_dataWrittenSize,
s_dataWritten,
&MinecraftDynamicConfigurations::GetDataCompletedCallback,
NULL
);
switch(hr)
{
case S_OK:
//The server call was spawned successfully.
break;
case E_FAIL:
app.DebugPrintf("DynamicConfig : Failed to get bytes for config\n");
//Sentient failed to spawn the call to the server.
//An unknown error occurred. For more information, see the debug log that is available when you compile your application against the debug version of the library (SenCoreD.lib).
break;
case Sentient::SENTIENT_E_NOT_INITIALIZED:
app.DebugPrintf("DynamicConfig : Failed to get bytes for config as sentient not initialized\n");
//Sentient is not initialized. You must call SentientInitialize before you call this function.
break;
case E_POINTER:
app.DebugPrintf("DynamicConfig: Failed to get bytes for config as pointer is NULL\n");
//The out_size pointer is NULL.
break;
}
if(FAILED(hr) )
{
s_bUpdatedConfigs[s_eCurrentConfig] = true;
UpdateNextConfiguration();
}
}
else
{
s_bUpdatedConfigs[s_eCurrentConfig] = true;
UpdateNextConfiguration();
app.DebugPrintf("MinecraftDynamicConfigurations::GetSizeCompletedCallback : FAILED\n");
}
}
void MinecraftDynamicConfigurations::GetDataCompletedCallback(HRESULT taskResult, void *userCallbackData)
{
if(HRESULT_SUCCEEDED(taskResult) && s_currentConfigSize == s_dataWrittenSize)
{
switch(s_eCurrentConfig)
{
case eDynamic_Config_Trial:
{
int version = *(int *)s_dataWritten;
switch(version)
{
case DYNAMIC_CONFIG_TRIAL_VERSION:
//case 1:
memcpy(&trialData,s_dataWritten+4,sizeof(_dynamic_config_trial_data_version1));
app.DebugPrintf("Updated dynamic config TRIAL: timer is %d\n", trialData.trialTimeSeconds);
break;
};
}
break;
};
}
else
{
app.DebugPrintf("MinecraftDynamicConfigurations::GetDataCompletedCallback : FAILED\n");
}
delete [] s_dataWritten;
s_dataWritten = NULL;
s_bUpdatedConfigs[s_eCurrentConfig] = true;
UpdateNextConfiguration();
}

View File

@@ -0,0 +1,68 @@
#pragma once
// 4J Stu - This file defines the id's for the dynamic configurations that we are currently using
// as well as the format of the data in them
/***********************
*
* TRIAL TIMER
*
************************/
#define DYNAMIC_CONFIG_TRIAL_ID 0
#define DYNAMIC_CONFIG_TRIAL_VERSION 1
#define DYNAMIC_CONFIG_DEFAULT_TRIAL_TIME 2400 //40 mins 1200 // 20 mins //300; // 5 minutes
class MinecraftDynamicConfigurations
{
private:
enum EDynamic_Configs
{
eDynamic_Config_Trial,
eDynamic_Config_Max,
};
/***********************
*
* TRIAL TIMER
*
************************/
// 4J Stu - The first 4 bytes define a version number, that defines the structure of the data
// After reading those bytes into a DWORD, the remainder of the data should be the size of the
// relevant struct and can be cast to the struct
struct _dynamic_config_trial_data_version1
{
// The time in seconds that the player can play the trial for
DWORD trialTimeSeconds;
_dynamic_config_trial_data_version1() { trialTimeSeconds = DYNAMIC_CONFIG_DEFAULT_TRIAL_TIME; }
};
typedef _dynamic_config_trial_data_version1 Dynamic_Config_Trial_Data;
// Stored configurations
static Dynamic_Config_Trial_Data trialData;
static bool s_bFirstUpdateStarted;
static bool s_bUpdatedConfigs[eDynamic_Config_Max];
static EDynamic_Configs s_eCurrentConfig;
static size_t s_currentConfigSize;
static size_t s_dataWrittenSize;
static byte *s_dataWritten;
public:
static void Tick();
static DWORD GetTrialTime();
private:
static void UpdateAllConfigurations();
static void UpdateNextConfiguration();
static void UpdateConfiguration(EDynamic_Configs id);
static void GetSizeCompletedCallback(HRESULT taskResult, void *userCallbackData);
static void GetDataCompletedCallback(HRESULT taskResult, void *userCallbackData);
};

View File

@@ -0,0 +1,419 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client AvatarSuperstars Avatar API
//
// Include this to get access to all Avatar-related Sentient features.
#pragma once
#include "SenClientRawData.h"
#include "SenClientResource.h"
#include "SenClientSys.h"
#include "SenClientXML.h"
#include <xnamath.h>
#include <xonline.h>
namespace Sentient
{
//====================//
// //
// Avatar Types //
// //
//====================//
// When enumerating avatars, these are the options for pre-sorting the
// returned list.
enum SenAvatarSortBy
{
SenAvatarSortBy_Default = 0,
// ... TBD ...
};
// This structure contains the information needed to download the
// raw data for a given gender.
struct SenAvatarGenderInfo
{
SenRawDataTransferInfo metadata;
SenRawDataTransferInfo assets;
SenRawDataTransferInfo xml;
SenRawDataTransferInfo icon;
};
// This structure contains the original uploaded info plus info
// needed to download raw data.
struct SenAvatarInfo : public SenResourceInfo
{
int vipLevel;
SenAvatarGenderInfo female;
SenAvatarGenderInfo male;
};
struct SenAvatarPalette
{
XMCOLOR entry[3];
};
struct SenAvatarNamedPalette : SenAvatarPalette
{
wchar_t name[57+1];
};
/// @brief Extra avatar information.
///
/// @details This structure contains additional data about the avatar, such as localized strings and palettes.
///
struct SenAvatarExtraInfo
{
wchar_t title[XMARKETPLACE_MAX_TITLE_NAME_LENGTH+1]; ///< The localized game title associated with the avatar.
wchar_t name[XMARKETPLACE_MAX_OFFER_NAME_LENGTH+1]; ///< The localized name associated with the avatar.
wchar_t description[XMARKETPLACE_MAX_OFFER_SELL_TEXT_LENGTH+1]; ///< The localized short description associated with the avatar.
size_t paletteCount;
SenAvatarNamedPalette palette[16];
};
//========================//
// //
// Avatar Functions //
// //
//========================//
/// @brief Search the database for all the avatars that match the search criteria.
///
/// @param[in] userIndex
/// The index of the initiating user on the console. Note: This is NOT a XUID.
///
/// @param[in] avatarInfoCountMax
/// The number of SenAvatarInfo structures available in @a out_avatarInfoList.
///
/// @param[out] out_avatarInfoCount
/// This is the number of entries actually enumerated by the call.
///
/// @param[out] out_avatarInfoList
/// The structures to fill in with the enumerated information.
/// It is assumed that this is preallocated to at least @a avatarInfoCountMax entries.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// E_POINTER: out_avatarInfoList is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details Enumerates in default order, at the current time, for all titles.
///
/// @related SenAvatarDownloadExtraInfo()
/// @related SenAvatarDownloadMetadata()
/// @related SenAvatarDownloadAssets()
/// @related SenAvatarDownloadIcon()
///
HRESULT SenAvatarEnumerate(
int userIndex,
size_t avatarInfoCountMax,
size_t *out_avatarInfoCount,
SenAvatarInfo *out_avatarInfoList,
SenSysCompletedCallback userCallback,
void *userCallbackData );
// Search the database for a specific avatar at the current time.
/// @brief Search the database for a specific avatar at the current time
///
/// @param[in] titleID
/// The ID of the title that the avatar item is associated with.
///
/// @param[in] resourceID
/// The ID of the specific asset about which information should be returned.
///
/// @param[out] out_avatarInfo
/// The structures to fill in with the information.
/// It is assumed that this is preallocated to at least 1 entry.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// E_POINTER: out_avatarInfo is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @related SenAvatarEnumerate()
/// @related SenAvatarDownloadExtraInfo()
/// @related SenAvatarDownloadMetadata()
/// @related SenAvatarDownloadAssets()
/// @related SenAvatarDownloadIcon()
///
HRESULT SenAvatarFind(
SenSysTitleID titleID,
SenResourceID resourceID,
SenAvatarInfo *out_avatarInfo,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief Download the avatar metadata to the client.
///
/// @param[in] avatarInfo
/// The info describing the attributes and data of the avatar asset.
/// This is obtained from SenAvatarEnumerate().
///
/// @param[in] male
/// Whether or not to receive information about the male avatar (vs. the female)
///
/// @param[in] dataSizeMax
/// Used to indicate the size of the buffer pointed to by @a out_data.
/// If the actual size of the data exceeds this, you will receive an error.
/// It is assumed that this is at least @a avatarInfo.[fe]male.metadata.GetBufferSize() bytes.
///
/// @param[out] out_data
/// The buffer to fill in with the metadata.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_INVALIDARG: avatarInfo.resourceID or avatarInfo.[fe]male.metadata is invalid.
/// E_POINTER: out_data is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @related SenAvatarEnumerate()
/// @related SenAvatarDownloadExtraInfo()
/// @related SenAvatarDownloadAssets()
/// @related SenAvatarDownloadIcon()
///
HRESULT SenAvatarDownloadMetadata(
const SenAvatarInfo &avatarInfo,
bool male,
size_t dataSizeMax,
void *out_data,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief Download the avatar asset binary data to the client.
///
/// @param[in] avatarInfo
/// The info describing the attributes and data of the avatar asset.
/// This is obtained from SenAvatarEnumerate().
///
/// @param[in] male
/// Whether or not to receive information about the male avatar (vs. the female)
///
/// @param[in] dataSizeMax
/// Used to indicate the size of the buffer pointed to by @a out_data.
/// If the actual size of the data exceeds this, you will receive an error.
/// It is assumed that this is at least @a avatarInfo.[fe]male.assets.GetBufferSize() bytes.
///
/// @param[out] out_data
/// The buffer to fill in with the asset data.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_INVALIDARG: avatarInfo.resourceID or avatarInfo.[fe]male.assets is invalid.
/// E_POINTER: out_data is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @related SenAvatarEnumerate()
/// @related SenAvatarDownloadExtraInfo()
/// @related SenAvatarDownloadMetadata()
/// @related SenAvatarDownloadIcon()
///
HRESULT SenAvatarDownloadAssets(
const SenAvatarInfo &avatarInfo,
bool male,
size_t dataSizeMax,
void *out_data,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief Download the avatar icon binary data to the client.
///
/// @param[in] avatarInfo
/// The info describing the attributes and data of the avatar asset.
/// This is obtained from SenAvatarEnumerate().
///
/// @param[in] male
/// Whether or not to receive information about the male avatar (vs. the female)
///
/// @param[in] dataSizeMax
/// Used to indicate the size of the buffer pointed to by @a out_data.
/// If the actual size of the data exceeds this, you will receive an error.
/// It is assumed that this is at least @a avatarInfo.[fe]male.icon.GetBufferSize() bytes.
///
/// @param[out] out_data
/// The buffer to fill in with the binary icon data.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_INVALIDARG: avatarInfo.resourceID or avatarInfo.[fe]male.icon is invalid.
/// E_POINTER: out_data is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @related SenAvatarEnumerate()
/// @related SenAvatarDownloadExtraInfo()
/// @related SenAvatarDownloadMetadata()
/// @related SenAvatarDownloadAssets()
///
HRESULT SenAvatarDownloadIcon(
const SenAvatarInfo &avatarInfo,
bool male,
size_t dataSizeMax,
void *out_data,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief Download extra information about a given avatar to the client.
///
/// @param[in] avatarInfo
/// The info describing the attributes and data of the avatar.
/// This is obtained from SenAvatarEnumerate().
///
/// @param[in] male
/// Whether or not to receive information about the male avatar (vs. the female).
///
/// @param[out] out_avatarExtraInfo
/// The structure to populate with extra information.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_INVALIDARG: avatarInfo.resourceID or avatarInfo.xml is invalid.
/// E_POINTER: out_avatarExtraInfo is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details On completion, the structure will contain extra information, such as localized strings.
///
/// @related SenAvatarEnumerate()
/// @related SenAvatarDownloadMetadata()
/// @related SenAvatarDownloadAssets()
/// @related SenAvatarDownloadIcon()
///
HRESULT SenAvatarDownloadExtraInfo(
const SenAvatarInfo &avatarInfo,
bool male,
SenAvatarExtraInfo *out_avatarExtraInfo,
SenSysCompletedCallback userCallback, void *userCallbackData );
// Download the raw binary data to the client.
// It is assumed that out_data is preallocated to (at least) dataSizeMax bytes,
// which in turn should be at least avatarInfo.[fe]male.xml.GetBufferSize() bytes.
HRESULT SenAvatarDownloadXML(
const SenAvatarInfo &avatarInfo,
bool male,
size_t dataSizeMax,
void *out_data,
SenSysCompletedCallback userCallback,
void *userCallbackData );
// Obtain a wide, localized string with a given avatar's game title.
//
// Assumes you have already downloaded the XML and run it through
// SenXMLParse() to get a SenXML struct.
//
// First method, filling a fixed-size buffer:
//
// wchar_t buffer[1234];
// SenAvatarXMLGetTitle( xml, loc, _countof(buffer), NULL, buffer );
//
// Second method, filling a dynamically-allocated buffer:
//
// size_t bufferLength;
// SenAvatarXMLGetTitle( xml, loc, 0, &bufferLength, NULL );
// wchar_t buffer = new wchar_t[bufferLength];
// SenAvatarXMLGetTitle( xml, loc, bufferLength, NULL, buffer );
//
// Note that bufferLength is in wchars, and includes the terminating nul.
// The actual length of the _string_ is (*out_bufferLength - 1).
//
HRESULT SenAvatarXMLGetTitle(
const SenXML &senXML,
size_t bufferLengthMax,
size_t *out_bufferLength, // optional
wchar_t *out_buffer ); // optional
// Obtain a wide, localized string with a given avatar's name.
// See the similar SenAvatarGetTitle() for details.
HRESULT SenAvatarXMLGetName(
const SenXML &senXML,
size_t bufferLengthMax,
size_t *out_bufferLength, // optional
wchar_t *out_buffer ); // optional
// Obtain a wide, localized string with a given avatar's description.
// See the similar SenAvatarGetTitle() for details.
HRESULT SenAvatarXMLGetDescription(
const SenXML &senXML,
size_t bufferLengthMax,
size_t *out_bufferLength, // optional
wchar_t *out_buffer ); // optional
// Obtain the number of custom avatar palettes.
HRESULT SenAvatarXMLGetPaletteCount(
const SenXML &senXML,
size_t *out_paletteCount );
// Obtain the localized name for an avatar palettes.
// See the similar SenAvatarGetTitle() for details.
HRESULT SenAvatarXMLGetPaletteName(
const SenXML &senXML,
int paletteIndex,
size_t bufferLengthMax,
size_t *out_bufferLength, // optional
wchar_t *out_buffer ); // optional
// Obtain a single palette at a given index in the list of palettes
// for a given avatar.
HRESULT SenAvatarXMLGetPalette(
const SenXML &senXML,
int paletteIndex,
SenAvatarPalette *out_palette );
// Extract all palette entries at once.
// It is assumed that out_paletteList is preallocated to (at least)
// paletteCountMax entries.
HRESULT SenAvatarXMLGetPalettes(
const SenXML &senXML,
size_t paletteCountMax,
size_t *out_paletteCount, // optional
SenAvatarPalette *out_paletteList );
} // namespace Sentient

View File

@@ -0,0 +1,409 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client BoxArt API
//
// Include this to get access to all BoxArt-related Sentient features.
#pragma once
#include "SenClientRawData.h"
#include "SenClientResource.h"
#include "SenClientSys.h"
#include "SenClientXML.h"
#include <xonline.h>
namespace Sentient
{
//====================//
// //
// BoxArt Types //
// //
//====================//
/// @brief Box Art sorting options.
///
/// @details When enumerating box Art, these are the options for pre-sorting the returned list.
///
enum SenBoxArtSortBy
{
/// Sort by the default order (currently just the order stored on the server).
SenBoxArtSortBy_Default = 0,
};
/// @brief Box art command/action types.
///
/// @details When the user selects box art, these are the options for generating the resulting action.
///
enum SenBoxArtCommand
{
/// The game should call up the marketplace UI with info.GetOfferID().
SenBoxArtCommand_Store = 0,
// (more commands TBD)
};
/// @brief Basic box art information.
///
/// @details This structure contains the original uploaded info plus any info implied by the raw data that was uploaded (e.g. data sizes).
///
struct SenBoxArtInfo : public SenResourceInfo
{
SenRawDataTransferInfo image; ///< Points to a file, typically JPG or PNG, which can be passed to D3DXCreateTextureFromFileInMemory().
SenRawDataTransferInfo xml; ///< Points to an opaque XML file used to hold extended information about the box art. Use SenBoxArtDownloadExtraInfo() to retrieve.
SenBoxArtCommand command; ///< What to do when the box art is selected.
INT32 commandData0; ///< 32 bits of arbitrary data to go with command. (e.g. offerID high bits)
INT32 commandData1; ///< 32 bits of arbitrary data to go with command. (e.g. offerID low bits)
UINT32 friendsWithTitle; ///< Number of friends owning the title this box art is associated with.
/// @brief
/// Get the offerID associated with this box art.
///
/// @details
/// If command==SenBoxArtCommand_Store, this returns commandData0,1 as a SenSysOfferID.
/// Otherwise, it returns SenSysOfferID_Invalid.
///
SenSysOfferID GetOfferID() const;
};
/// @brief Extra box art information.
///
/// @details This structure contains additional data about box art, such as localized strings.
///
struct SenBoxArtExtraInfo
{
wchar_t title[XMARKETPLACE_MAX_OFFER_NAME_LENGTH+1]; ///< The localized title associated with the offer.
wchar_t description[XMARKETPLACE_MAX_OFFER_SELL_TEXT_LENGTH+1]; ///< The localized short description associated with the offer.
};
//========================//
// //
// BoxArt Functions //
// //
//========================//
/// @brief Search the database for all the box arts that match the search criteria.
///
/// @param[in] userIndex
/// The index of the initiating user on the console. Note: This is NOT a XUID.
///
/// @param[in] boxArtInfoCountMax
/// The number of SenBoxArtInfo structures available in @a out_boxArtInfoList.
///
/// @param[out] out_boxArtInfoCount
/// This is the number of entries actually enumerated by the call.
///
/// @param[out] out_boxArtInfoList
/// The structures to fill in with the enumerated information.
/// It is assumed that this is preallocated to at least @a boxArtInfoCountMax entries.
///
/// @param[out] out_senHandle
/// Provides a handle to the async task, which will allow for calling SentientCancel
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// E_POINTER: out_boxArtInfoList is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details Enumerates in default order, at the current time, for all titles, the box art available to display.
///
/// @related SenBoxArtDownloadImage()
/// @related SenBoxArtDownloadXML()
///
HRESULT SenBoxArtEnumerate(
int userIndex,
size_t boxArtInfoCountMax,
size_t *out_boxArtInfoCount,
SenBoxArtInfo *out_boxArtInfoList,
SenHandle *out_senHandle,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief Download the raw box art image data to the client.
///
/// @param[in] boxArtInfo
/// The info describing the attributes and data of the box art.
/// This is obtained from SenBoxArtEnumerate().
///
/// @param[in] dataSizeMax
/// Used to indicate the size of the buffer pointed to by @a out_data.
/// If the actual size of the data exceeds this, you will receive an error.
/// It is assumed that this is at least @a boxArtInfo.image.GetBufferSize() bytes.
///
/// @param[out] out_data
/// The buffer to fill in with the raw image data.
///
/// @param[out] out_senHandle
/// Provides a handle to the async task, which will allow for calling SentientCancel
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_INVALIDARG: boxArtInfo.resourceID or boxArtInfo.image is invalid.
/// E_POINTER: out_data is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details The data is expected to contain a PNG or JPG file, suitable for use with D3DXCreateTextureFromFileInMemory().
///
/// @related SenBoxArtEnumerate()
/// @related SenBoxArtDownloadXML()
///
HRESULT SenBoxArtDownloadImage(
const SenBoxArtInfo &boxArtInfo,
size_t dataSizeMax,
void *out_data,
SenHandle *out_senHandle,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief Download extra information about a give box art to the client.
///
/// @param[in] boxArtInfo
/// The info describing the attributes and data of the box art.
/// This is obtained from SenBoxArtEnumerate().
///
/// @param[out] out_boxArtExtraInfo
/// The structure to populate with extra information.
///
/// @param[out] out_senHandle
/// Provides a handle to the async task, which will allow for calling SentientCancel
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_INVALIDARG: boxArtInfo.resourceID or boxArtInfo.xml is invalid.
/// E_POINTER: out_boxArtExtraInfo is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details On completion, the structure will contain extra information, such as localized strings.
///
/// @related SenBoxArtEnumerate()
/// @related SenBoxArtDownloadImage()
///
HRESULT SenBoxArtDownloadExtraInfo(
const SenBoxArtInfo &boxArtInfo,
SenBoxArtExtraInfo *out_boxArtExtraInfo,
SenHandle *out_senHandle,
SenSysCompletedCallback userCallback, void *userCallbackData );
/// @brief Download the raw box art xml data to the client.
///
/// @param[in] boxArtInfo
/// The info describing the attributes and data of the box art.
/// This is obtained from SenBoxArtEnumerate().
///
/// @param[in] dataSizeMax
/// Used to indicate the size of the buffer pointed to by @a out_data.
/// If the actual size of the data exceeds this, you will receive an error.
/// It is assumed that this is at least @a boxArtInfo.xml.GetBufferSize() bytes.
///
/// @param[out] out_data
/// The buffer to fill in with the raw image data.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_INVALIDARG: boxArtInfo.resourceID or boxArtInfo.xml is invalid.
/// E_POINTER: out_data is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details The data is expected to contain a UTF-8 XML file, though those details
/// are irrelevant, as the contents are parsed transparently with SenXMLParse().
///
/// @related SenBoxArtEnumerate()
/// @related SenBoxArtDownloadImage()
///
/// @deprecated Use SenBoxArtDownloadExtraInfo() instead.
///
__declspec(deprecated("This function is deprecated, use SenBoxArtDownloadExtraInfo instead")) HRESULT SenBoxArtDownloadXML(
const SenBoxArtInfo &boxArtInfo,
size_t dataSizeMax,
void *out_data,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief Obtain a wide, localized string describing a given box art's game title.
///
/// @param[in] senXML
/// This is the result of a call to SenXMLParse() with the results of
/// SenBoxArtDownloadXML().
///
/// @param[in] culture
/// This is the result of a call to SenCultureFind() or SenCultureGet*().
/// You may also pass NULL to use the culture set with SenCultureSetCurrent().
///
/// @param[in] bufferLength
/// Note that bufferLength is in wchars, and needs to _include_ space for the terminating nul.
///
/// @param[out] out_bufferLength
/// Used to return the actual number of wchars written to the buffer, including the terminating nul.
/// The actual length of the _string_ is (*out_bufferLength - 1).
/// Pass @a out_bufferLength = NULL if you don't care about the actual size.
///
/// @param[out] out_buffer
/// The buffer to fill in with the string.
/// It is assumed that this is preallocated to at least @a bufferLength wchars.
/// Pass @a out_buffer = NULL if you are only interested in finding out the necessary buffer size.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_UNEXPECTED: passed a NULL culture without a default culture being set first.
/// E_INVALIDARG: senXML does not contain parsed XML data.
/// E_FAIL: Failed to locate text.
/// S_OK: Server call spawned successfully.
///
/// @details Assumes you have already downloaded the XML and run it through
/// SenXMLParse() to get a SenXML struct.
///
/// First method, filling a fixed-size buffer:
///
/// wchar_t buffer[1234];
/// SenBoxArtXMLGetTitle( xml, culture, _countof(buffer), NULL, buffer );
///
/// Second method, filling a dynamically-allocated buffer:
///
/// size_t bufferLength;
/// SenBoxArtXMLGetTitle( xml, culture, 0, &bufferLength, NULL );
/// wchar_t buffer = new wchar_t[bufferLength];
/// SenBoxArtXMLGetTitle( xml, culture, bufferLength, NULL, buffer );
///
/// @related SenBoxArtDownloadXML()
/// @related SenXMLParse()
///
/// @deprecated Use SenBoxArtDownloadExtraInfo() instead.
///
__declspec(deprecated("This function is deprecated, use SenBoxArtDownloadExtraInfo instead")) HRESULT SenBoxArtXMLGetTitle(
const SenXML &senXML,
size_t bufferLengthMax,
size_t *out_bufferLength,
wchar_t *out_buffer );
/// @brief Obtain a wide, localized string describing a given box art's game title.
///
/// @param[in] senXML
/// This is the result of a call to SenXMLParse() with the results of
/// SenBoxArtDownloadXML().
///
/// @param[in] culture
/// This is the result of a call to SenCultureFind() or SenCultureGet*().
/// You may also pass NULL to use the culture set with SenCultureSetCurrent().
///
/// @param[in] bufferLength
/// Note that bufferLength is in wchars, and needs to _include_ space for the terminating nul.
///
/// @param[out] out_bufferLength
/// Used to return the actual number of wchars written to the buffer, including the terminating nul.
/// The actual length of the _string_ is (*out_bufferLength - 1).
/// Pass @a out_bufferLength = NULL if you don't care about the actual size.
///
/// @param[out] out_buffer
/// The buffer to fill in with the string.
/// It is assumed that this is preallocated to at least @a bufferLength wchars.
/// Pass @a out_buffer = NULL if you are only interested in finding out the necessary buffer size.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_UNEXPECTED: passed a NULL culture without a default culture being set first.
/// E_INVALIDARG: senXML does not contain parsed XML data.
/// E_FAIL: Failed to locate text.
/// S_OK: Server call spawned successfully.
///
/// @details Assumes you have already downloaded the XML and run it through
/// SenXMLParse() to get a SenXML struct.
///
/// First method, filling a fixed-size buffer:
///
/// wchar_t buffer[1234];
/// SenBoxArtXMLGetDescription( xml, culture, _countof(buffer), NULL, buffer );
///
/// Second method, filling a dynamically-allocated buffer:
///
/// size_t bufferLength;
/// SenBoxArtXMLGetDescription( xml, culture, 0, &bufferLength, NULL );
/// wchar_t buffer = new wchar_t[bufferLength];
/// SenBoxArtXMLGetDescription( xml, culture, bufferLength, NULL, buffer );
///
/// @related SenBoxArtDownloadXML()
/// @related SenXMLParse()
///
/// @deprecated Use SenBoxArtDownloadExtraInfo() instead.
///
__declspec(deprecated("This function is deprecated, use SenBoxArtDownloadExtraInfo instead")) HRESULT SenBoxArtXMLGetDescription(
const SenXML &senXML,
size_t bufferLengthMax,
size_t *out_bufferLength,
wchar_t *out_buffer );
/// @brief Download the raw box art image data to the client.
///
/// @param[in] boxArtInfo
/// The info describing the attributes and data of the box art.
/// This is obtained from SenBoxArtEnumerate().
///
/// @param[in] dataSizeMax
/// Used to indicate the size of the buffer pointed to by @a out_data.
/// If the actual size of the data exceeds this, you will receive an error.
/// It is assumed that this is at least @a boxArtInfo.image.GetBufferSize() bytes.
///
/// @param[out] out_data
/// The buffer to fill in with the raw image data.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_INVALIDARG: boxArtInfo.resourceID or boxArtInfo.image is invalid.
/// E_POINTER: out_data is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details The data is expected to contain a PNG or JPG file, suitable for use with D3DXCreateTextureFromFileInMemory().
///
/// @related SenBoxArtEnumerate()
/// @related SenBoxArtDownloadXML()
///
__declspec(deprecated("This function is deprecated, use the overload with a SenHandle out param instead")) HRESULT SenBoxArtDownloadImage(
const SenBoxArtInfo &boxArtInfo,
size_t dataSizeMax,
void *out_data,
SenSysCompletedCallback userCallback,
void *userCallbackData );
} // namespace Sentient

View File

@@ -0,0 +1,116 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client ConfigFile API
//
// Include this to get access to all ConfigFile-related Sentient features.
#pragma once
#include "SenClientRawData.h"
#include "SenClientResource.h"
#include "SenClientSys.h"
namespace Sentient
{
//==============================//
// //
// Game Config File Types //
// //
//==============================//
/// @brief Basic config file information.
///
/// @details This structure contains the original uploaded info plus any info implied by the raw data that was uploaded (e.g. data sizes).
///
struct SenConfigInfo : public SenResourceInfo
{
SenRawDataTransferInfo config; ///< Points to a generic data block, whose format is determined by the game.
};
//==================================//
// //
// Game Config File Functions //
// //
//==================================//
/// @brief Find a config file by ID.
///
/// @param[in] resourceID
/// Which config file to find, e.g. "SenResourceID_Config_0 + 4".
///
/// @param[out] out_configInfo
/// The structure to fill in with the found information.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_POINTER: out_configInfo is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details Search the database for a specific config file at the current time.
///
/// @deprecated This function is deprecated. Use SenDynamicConfigGetSize() instead
///
/// @related SenConfigFileDownload()
///
__declspec(deprecated("Use SenDynamicConfigGetSize() instead"))
HRESULT SenConfigFileFind(
SenResourceID resourceID,
SenConfigInfo *out_configInfo,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief Download the raw config file data to the client.
///
/// @param[in] configInfo
/// The info describing the attributes and data of the config file.
/// This is obtained from SenConfigFileFind().
///
/// @param[in] dataSizeMax
/// Used to indicate the size of the buffer pointed to by @a out_data.
/// If the actual size of the data exceeds this, you will receive an error.
/// It is assumed that this is at least @a configInfo.config.GetBufferSize() bytes.
///
/// @param[out] out_data
/// The buffer to fill in with the raw image data.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_INVALIDARG: configInfo.resourceID or configInfo.config is invalid.
/// E_POINTER: out_data is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details The data format is determined entirely by the game code and is never examined or processed by Sentient.
///
/// @deprecated This function is deprecated. Use SenDynamicConfigGetSize() instead
///
/// @related SenConfigFileFind()
///
__declspec(deprecated("Use SenDynamicConfigGetBytes() instead"))
HRESULT SenConfigFileDownload(
const SenConfigInfo &configInfo,
size_t dataSizeMax,
void *out_data,
SenSysCompletedCallback userCallback,
void *userCallbackData );
} // namespace Sentient

View File

@@ -0,0 +1,74 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client Core API
//
// Include this to get access to ALL core Sentient features.
#pragma once
#include "SenClientConfig.h"
#include "SenClientCulture.h"
#include "SenClientFile.h"
#include "SenClientMain.h"
#include "SenClientPackage.h"
#include "SenClientRawData.h"
#include "SenClientResource.h"
#include "SenClientStats.h"
#include "SenClientSys.h"
#include "SenClientUtil.h"
#include "SenClientXML.h"
#include "SenClientUser.h"
// REVIEW: is this block of text still relevant?
/* API Design considerations
1. All functions will return S_OK if they succeed or either E_FAIL or an HRESULT error code
if they fail. Callers should use the standard SUCCEEDED(hr) or FAILED(hr) macros to
test the results, as it eliminates errors due to misconceptions about what exactly is
an HRESULT error vs. success/status.
PLEASE NOTE: S_FALSE is for successfully returning a false, and does *not* qualify as an
error code. It should not be used for fail cases. Use only codes like E_FAIL,
E_OUTOFMEMORY, E_INVALIDARG, E_POINTER, etc. for failures. Most error codes contain "E_"
at or near the start of the name, but you can always tell by whether the top bit is set.
2. The API is not thread safe at this time, so all calls must be made from the same thread.
3. Many functions are designed for asynchronous use, and will internally create a task that
will only finish after feedback from the server.
a. These functions can be either blocking or asynchronous. If the callback pointer is NULL
then it is a blocking call.
b. If the call is asynchronous, then it will always return instantly, and will return S_OK
if a task has been created.
1. If the task is created then at some point the callback will be called once the task
finishes, regardless of whether the task succeeds or fails. The task result is then
passed into the callback
2. However, if the call fails to create a task (due to bad parameters or something else)
and returns something other than S_OK, it will *not* call the callback.
c. If the call is blocking, the return value will be the task result value.
d. The recommended usage is to use async calls, but if a game run all Sentient calls from a
worker thread then using blocking calls could work.
4. The order in which async calls complete is not guaranteed.
a. Similarly, if one or more async calls are started, and a blocking call is performed, the
async calls may or may not finish before the blocking call returns ( as the blocking call
just calls SentientUpdate() until it completes ).
5. All async functions that take pointers will assume that the pointers point valid memory for the
duration of the task, and that the game does not free or overwrite the memory until the task
is completed.
6. All output variables (but not output buffers) are cleared even if the function call fails.
7. Functions that return buffers of data, will have to have the buffer allocated before being called.
NOTE: This is changed from the first release (october 2010)
8. There are multiple sets of functionality that relies on "blobs" - a blob is a custom (usually
game-specific) chunk of binary data that the Sentient does not know anything about.
*/

View File

@@ -0,0 +1,61 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client Culture API
//
// Include this to get access to all Culture-related Sentient features.
#pragma once
#include "SenClientTypes.h"
namespace Sentient
{
//=========================//
// //
// Culture Functions //
// //
//=========================//
/// @brief Set the current culture to the one specified, if possible.
///
/// @param[in] dwLanguage
/// the DWORD id as defined in xconfig.h (e.g. XC_LANGUAGE_ENGLISH) for the language to use
/// @param[in] dwLocale
/// the DWORD id as defined in xconfig.h (e.g. XC_LOCALE_GREAT_BRITAIN) for the region to use
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_FAIL: Failed to find the given culture.
/// S_OK: Current culture set successfully.
///
/// @details Set the current culture to the one specified, if possible (if not english will be used).
/// This should only be called during title launch if it is determined that the console is set to a lanuage unsupported by the title.
/// This method should only be called once, right after calling SentientInitialize()
/// This is the culture that will be used when any string routine is called.
/// By default, this is set to the system culture & region.
///
HRESULT SetCurrentCulture(
__in DWORD dwLanguage,
__in DWORD dwLocale
);
/// @brief Set the current culture to English (no region)
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_FAIL: Failed to find the given culture.
/// S_OK: Current culture set successfully.
///
/// @details Set the current culture English.
/// This should only be called during title launch if it is determined that the console is set to a lanuage unsupported by the title.
/// This method should only be called once, right after calling SentientInitialize()
/// This is the culture that will be used when any string routine is called.
/// By default, Sentient uses the console's culture & region.
///
__inline HRESULT SetCurrentCultureEnglish() { return SetCurrentCulture(XC_LANGUAGE_ENGLISH, 0); }
} // namespace Sentient

View File

@@ -0,0 +1,44 @@
#pragma once
#include "SenClientBoxArt.h"
#include "SenClientCultureBackCompat_SenCore.h"
namespace Sentient
{
#pragma warning(disable:4996)
__declspec(deprecated("This function is deprecated. See the function body for an example of using the new API."))
__inline HRESULT SenBoxArtDownloadExtraInfo(
const SenBoxArtInfo &boxArtInfo,
const SenCultureInfo *culture,
SenBoxArtExtraInfo *out_boxArtExtraInfo,
SenHandle *out_senHandle,
SenSysCompletedCallback userCallback, void *userCallbackData )
{
return SenBoxArtDownloadExtraInfo(boxArtInfo, out_boxArtExtraInfo, out_senHandle, userCallback, userCallbackData);
}
__declspec(deprecated("This function is deprecated, use SenBoxArtDownloadExtraInfo instead"))
__inline HRESULT SenBoxArtXMLGetTitle(
const SenXML &senXML,
const SenCultureInfo *culture,
size_t bufferLengthMax,
size_t *out_bufferLength,
wchar_t *out_buffer )
{
return SenBoxArtXMLGetTitle(senXML, bufferLengthMax, out_bufferLength, out_buffer);
}
__declspec(deprecated("This function is deprecated, use SenBoxArtDownloadExtraInfo instead"))
__inline HRESULT SenBoxArtXMLGetDescription(
const SenXML &senXML,
const SenCultureInfo *culture,
size_t bufferLengthMax,
size_t *out_bufferLength,
wchar_t *out_buffer )
{
return SenBoxArtXMLGetDescription(senXML, bufferLengthMax, out_bufferLength, out_buffer);
}
#pragma warning(default:4996)
}

View File

@@ -0,0 +1,72 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client UGC API - Backwards compat file for SenCulture removal
//
// Include this to get access to all UGC related backwards compatibility with the old SenCulture
#pragma once
#include "SenClientUGC.h"
#include "SenClientCultureBackCompat_SenCore.h"
namespace Sentient
{
/// @brief Retrieves a collection of feeds that are viewable by the
/// current user.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[in] culture
/// This is the result of a call to SenCultureFind() or SenCultureGet*().
/// You may also pass NULL to use the culture set with SenCultureSetCurrent().
/// May be NULL for default culture.
///
/// @param[in] maxResults
/// Used to indicate the number of items to be returned by @a out_feedInfo.
/// If the actual number of items exceeds this, you will receive an error.
///
/// @param[out] out_feedInfo
/// Pointer to a collection of structures to fill with SenUGCFeedInfo data.
///
/// @param[out] out_resultCount
/// The number of entries actually enumerated by the call.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
/// E_POINTER: out_feedInfo or out_resultCount are null.
///
/// @details <Insert detailed method documentation>
///
/// @related SenUGCGetFeed()
///
/// @deprecated Use SenUGCEnumerateFeeds() without SenCulture
///
__declspec(deprecated("This function is deprecated. See the function body for an example of using the new API."))
__inline HRESULT SenUGCEnumerateFeeds(
int userIndex,
const SenCultureInfo *culture,
size_t maxResults,
SenUGCFeedInfo *out_feedInfo,
size_t *out_resultCount,
SenSysCompletedCallback userCallback,
void *userCallbackData)
{
return SenUGCEnumerateFeeds(userIndex, maxResults, out_feedInfo, out_resultCount, userCallback, userCallbackData);
}
} // namespace Sentient

View File

@@ -0,0 +1,81 @@
#pragma once
#include "SenClientCulture.h"
namespace Sentient
{
//enum
//{
// // Note that these include a terminating nul.
// SenCulture_DescSizeMax = 80,
// SenCulture_NameSizeMax = 12,
//};
struct SenCultureInfo
{
wchar_t name[12]; // e.g. { L"en", L"en-CA", L"en-GB", L"" }
wchar_t desc[80]; // e.g. L"English (United States)"
size_t nameCount; // e.g. 1
const SenCultureInfo *parent;
};
static SenCultureInfo s_defaultculture;
__declspec(deprecated("This function is deprecated, and should not be used"))
__inline const wchar_t *SenCultureGetSystemLanguageString()
{
return L"en";
}
__declspec(deprecated("This function is deprecated, and should not be used"))
__inline const wchar_t *SenCultureGetSystemLocaleString()
{
return L"US";
}
__declspec(deprecated("This function is deprecated, and should not be used"))
const wchar_t *SenCultureGetSystemCultureString();
//{
// return L"en-US";
//}
__declspec(deprecated("This function is deprecated, and should not be used"))
__inline const SenCultureInfo *SenCultureFind( const wchar_t *name )
{
return &s_defaultculture;
}
__declspec(deprecated("This function is deprecated, and should not be used"))
__inline const SenCultureInfo *SenCultureGetParent( const SenCultureInfo *culture )
{
return &s_defaultculture;
}
__declspec(deprecated("This function is deprecated, and should not be used"))
__inline HRESULT SenCultureSetCurrent( const wchar_t name[] )
{
return E_FAIL;
}
__declspec(deprecated("This function is deprecated, and should not be used"))
__inline const SenCultureInfo *SenCultureGetCurrent()
{
return &s_defaultculture;
}
__declspec(deprecated("This function is deprecated, and should not be used"))
__inline HRESULT SenCultureSetDefault( const wchar_t name[] )
{
return E_FAIL;
}
__declspec(deprecated("This function is deprecated, and should not be used"))
__inline const SenCultureInfo *SenCultureGetDefault()
{
return &s_defaultculture;
}
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include "SenClientCultureBackCompat_SenCore.h"
#include "SenClientNews.h"
namespace Sentient
{
__declspec(deprecated("This function is deprecated. See the function body for an example of using the new API."))
__inline HRESULT SenGetTickerMessage(
int userIndex,
const SenCultureInfo *culture,
SenTickerData *out_tickerData )
{
return SenGetTickerMessage(userIndex, out_tickerData);
}
}

View File

@@ -0,0 +1,101 @@
#pragma once
#include "SenClientCultureBackCompat_SenCore.h"
#include "SenClientFame.h"
#include "SenClientAvatar.h"
namespace Sentient
{
__declspec(deprecated("This function is deprecated. See the function body for an example of using the new API."))
__inline HRESULT SenGetAwardMessage(
int userIndex,
const SenCultureInfo *culture,
SenAwardMessageData *out_awardData )
{
return SenGetAwardMessage(userIndex, out_awardData);
}
__declspec(deprecated("This function is deprecated. See the function body for an example of using the new API."))
__inline HRESULT SenGetVIPLevelName(
const SenCultureInfo *culture,
unsigned int vipLevel,
size_t maxNameLength,
wchar_t *out_name)
{
return SenGetVIPLevelName(vipLevel, maxNameLength, out_name);
}
__declspec(deprecated("This function is deprecated. See the function body for an example of using the new API."))
__inline HRESULT SenGetFameDisplayData(
int userIndex,
const SenCultureInfo *culture,
size_t startIndex,
size_t maxDisplayDataCount,
size_t *out_dataCount,
SenFameDisplayData *out_displayData )
{
return SenGetFameDisplayData(userIndex, startIndex, maxDisplayDataCount, out_dataCount, out_displayData);
}
__declspec(deprecated("This function is deprecated. See the function body for an example of using the new API."))
__inline HRESULT SenAvatarDownloadExtraInfo(
const SenAvatarInfo &avatarInfo,
bool male,
const SenCultureInfo *culture,
SenAvatarExtraInfo *out_avatarExtraInfo,
SenSysCompletedCallback userCallback, void *userCallbackData )
{
return SenAvatarDownloadExtraInfo(
avatarInfo,
male,
culture,
out_avatarExtraInfo,
userCallback, userCallbackData );
}
__declspec(deprecated("This function is deprecated. See the function body for an example of using the new API."))
__inline HRESULT SenAvatarXMLGetTitle(
const SenXML &senXML,
const SenCultureInfo *culture, // optional
size_t bufferLengthMax,
size_t *out_bufferLength, // optional
wchar_t *out_buffer )
{
return SenAvatarXMLGetTitle(senXML, bufferLengthMax, out_bufferLength, out_buffer);
}
__declspec(deprecated("This function is deprecated. See the function body for an example of using the new API."))
__inline HRESULT SenAvatarXMLGetName(
const SenXML &senXML,
const SenCultureInfo *culture,
size_t bufferLengthMax,
size_t *out_bufferLength, // optional
wchar_t *out_buffer )
{
return SenAvatarXMLGetName(senXML, bufferLengthMax, out_bufferLength, out_buffer);
}
__declspec(deprecated("This function is deprecated. See the function body for an example of using the new API."))
__inline HRESULT SenAvatarXMLGetDescription(
const SenXML &senXML,
const SenCultureInfo *culture, // optional
size_t bufferLengthMax,
size_t *out_bufferLength, // optional
wchar_t *out_buffer )
{
return SenAvatarXMLGetDescription(senXML, bufferLengthMax, out_bufferLength, out_buffer);
}
__declspec(deprecated("This function is deprecated. See the function body for an example of using the new API."))
__inline HRESULT SenAvatarXMLGetPaletteName(
const SenXML &senXML,
int paletteIndex,
const SenCultureInfo *culture, // optional
size_t bufferLengthMax,
size_t *out_bufferLength, // optional
wchar_t *out_buffer )
{
return SenAvatarXMLGetPaletteName(senXML, paletteIndex, bufferLengthMax, out_bufferLength, out_buffer);
}
}

View File

@@ -0,0 +1,170 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client DynamicConfig API
//
// Include this to get access to all DynamicConfig-related Sentient features
#pragma once
#include "SenClientSys.h"
namespace Sentient
{
/// @brief Gets the size of a config file, so memory can be allocated
///
/// @param[in] titleID
/// Which title's config file to search for.
///
/// @param[in] resourceID
/// Which config file to find.
///
/// @param[out] out_size
/// The size of the file, in bytes.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_POINTER: size is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details Search the service for a specific config file at the current time.
///
/// @related SenDynamicConfigFileGetBytes()
///
HRESULT SenDynamicConfigGetSize(
__in unsigned int titleID,
__in unsigned int resourceID,
__out size_t* out_size,
__in SenSysCompletedCallback userCallback,
__in void *userCallbackData );
/// @brief Gets the size of a config file, so memory can be allocated
///
/// @param[in] resourceID
/// Which config file to find.
///
/// @param[out] out_size
/// The size of the file, in bytes.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_POINTER: size is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details Search the service for a specific config file at the current time.
///
/// @related SenDynamicConfigFileGetBytes()
///
__inline HRESULT SenDynamicConfigGetSize(
__in unsigned int resourceID,
__out size_t* out_size,
__in SenSysCompletedCallback userCallback,
__in void *userCallbackData )
{
return SenDynamicConfigGetSize(SenSysTitleID_This, resourceID, out_size, userCallback, userCallbackData);
}
/// @brief Gets the contents of a config file
///
/// @param[in] titleID
/// Which title's config file to search for.
///
/// @param[in] resourceID
/// Which config file to return.
///
/// @param[in] dataSizeMax
/// Maximum number of bytes to return.
///
/// @param[out] out_bytesWritten
/// The number of bytes written into the buffer.
///
/// @param[out] out_data
/// The buffer that receives the contents of the file.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_POINTER: out_data is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details Search the service for a specific config file at the current time.
///
/// @related SenDynamicConfigFileGetSize()
///
HRESULT SenDynamicConfigGetBytes(
__in unsigned int titleID,
__in unsigned int resourceID,
__in size_t dataSizeMax,
__out_opt size_t* out_bytesWritten,
__out void *out_data,
__in SenSysCompletedCallback userCallback,
__in void *userCallbackData );
/// @brief Gets the contents of a config file
///
/// @param[in] resourceID
/// Which config file to return.
///
/// @param[in] dataSizeMax
/// Maximum number of bytes to return.
///
/// @param[out] out_bytesWritten
/// The number of bytes written into the buffer.
///
/// @param[out] out_data
/// The buffer that receives the contents of the file.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_POINTER: out_data is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details Search the service for a specific config file at the current time.
///
/// @related SenDynamicConfigFileGetSize()
///
__inline HRESULT SenDynamicConfigGetBytes(
__in unsigned int resourceID,
__in size_t dataSizeMax,
__out_opt size_t* out_bytesWritten,
__out void *out_data,
__in SenSysCompletedCallback userCallback,
__in void *userCallbackData )
{
return SenDynamicConfigGetBytes(SenSysTitleID_This, resourceID, dataSizeMax, out_bytesWritten, out_data, userCallback, userCallbackData);
}
}

View File

@@ -0,0 +1,572 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client AvatarSuperstars Fame API
//
// Include this to get access to all Fame-related Sentient features.
#pragma once
#include "SenClientSys.h"
namespace Sentient
{
/**********************
***** Fame Types *****
**********************/
enum SenFameVIPLevel
{
SenFameVIPLevel_Unknown = 0xFFFFFFFF,
SenFameVIPLevel_Fan = 0,
SenFameVIPLevel_Newcomer = 1,
SenFameVIPLevel_UpAndComing = 2,
SenFameVIPLevel_Headliner = 3,
SenFameVIPLevel_Star = 4,
SenFameVIPLevel_Superstar = 5,
};
/// @brief Information about a user's VIP status
///
/// @details This structure contains the user's current VIP level and fame points
///
struct SenFameVIPData
{
PlayerUID user; ///< ID for the user whose VIP status this instance describes
unsigned int vipLevel; ///< Current VIP level [0-n]
unsigned int lastAckedVIPLevel; ///< VIP level last time this structure was acknowledged by a Sentient client
unsigned int famePointsCurrent; ///< Fame Points accrued across all Fame titles since the last VIP level passed.
unsigned int famePointsWeek; ///< Fame Points accrued across all Fame titles this week.
unsigned int famePointsLifetime; ///< Fame Points accrued across all Fame titles over the user's entire history.
unsigned int pointsToNextLevel; ///< Incremental Fame Points that must be acquired to gain a new VIP level.
unsigned int superstarCounter; ///< Number of times the user has achieved the maximum possible VIP level.
SYSTEMTIME vipLevelExpiresAt; ///< Date at which current VIP level will expire. Only relevant when vipLevelExpires is true.
bool vipLevelExpires; ///< Whether or not the current VIP level will expire.
};
/// @brief Information about a single row in a Fame leaderboard
///
/// @details This structure contains the identity of the user and summary information about their Fame status
///
struct SenFameLeaderboardEntry
{
PlayerUID user; ///< ID for the user this row describes
unsigned int vipLevel; ///< Current VIP level[0-n]
unsigned int famePoints; ///< Fame Points accrued. May be weekly or lifetime depending on leaderboard type queried.
unsigned int superstarCounter; ///< Number of times the user has achieved the maximum possible VIP level.
unsigned int rank; ///< Global rank in the leaderboard [1-n]
};
/// @brief Leaderboard query ranking options
///
/// @details When querying leaderboards, these are the options for how the leaderboard is ranked.
///
enum SenFameLeaderboardRankType
{
SenFameLeaderboardRankType_Week, ///< Return ranking for fame points earned this week.
SenFameLeaderboardRankType_Lifetime, ///< Return ranking for fame points earned all time
SenFameLeaderboardRankType_Superstar ///< Return ranking for superstar counter
};
/// @brief Leaderboard query filter options
///
/// @details When querying leaderboards, these are the options for how the leaderboard is filtered.
///
enum SenFameLeaderboardFilter
{
SenFameLeaderboardFilter_Everyone = 0, ///< Return the unfiltered leaderboard
SenFameLeaderboardFilter_Friends, ///< Filter leaderboard by friends.
};
/// @brief Information about the parameters for a leaderboard query
///
/// @details This structure should be filled in to specify parameters for a leaderboard query
///
struct SenFameLeaderboardRequest
{
SenFameLeaderboardRankType type; ///< Ranking option for this query.
SenFameLeaderboardFilter filter; ///< Filter option for this query.
int startIndex; ///< Rank at which leaderboard query should start. Set to -1 to center on querying user.
};
/// @brief Information about the results of a leaderboard query
///
/// @details This structure contains information about the results of a leaderboard query.
///
struct SenFameLeaderboardResults
{
unsigned int playerIndex; ///< When playerIndex < numEntriesReturned, provides the index into result set at which the row for the querying user is located.
size_t numEntriesReturned; ///< Number of rows returned by the query.
size_t numLeaderboardEntries; ///< Total number of rows in the leaderboard.
};
/// @brief Fame progress (challenge) types
///
/// @details Defines a set of well-known challenge types, plus a range for titles to use for their custom challenge types
///
enum SenFameProgressID
{
SenFameProgressID_TitleDefinedFirst = 0, ///< First possible ID for a title-defined challenge.
SenFameProgressID_TitleDefinedLast = 1023, ///< Last possible ID for a title-defined challenge.
SenFameProgressID_FirstPlay = 1024, ///< Challenge tracks the first time a user plays a given title. This challenge is implemented on the Sentient server. Do not submit updates for it.
SenFameProgressID_AvatarAward1, ///< Challenge tracks the user receiving the first available Avatar Award. Progress against this challenge must be submitted by titles.
SenFameProgressID_AvatarAward2, ///< Challenge tracks the user receiving the second available Avatar Award. Progress against this challenge must be submitted by titles.
SenFameProgressID_FriendsOwnTitle,
// These challenges are not currently implemented. Contact senhelp@microsoft.com before using.
SenFameProgressID_MPWithFriend,
SenFameProgressID_MPWithVIP1,
SenFameProgressID_MPWithVIP2,
SenFameProgressID_MPWithVIP3,
SenFameProgressID_MPWithVIP4,
SenFameProgressID_MPWithVIP5,
SenFameProgressID_FriendsAtVIP1,
SenFameProgressID_FriendsAtVIP2,
SenFameProgressID_FriendsAtVIP3,
SenFameProgressID_FriendsAtVIP4,
SenFameProgressID_FriendsAtVIP5,
SenFameProgressID_Invalid = 0xffffffff ///< Reserved identifier for an invalid challenge.
};
/// @brief Constants that may be reported when Fame APIs return a count.
enum SenFameCount : unsigned int
{
SenFameCount_Unbounded = 0xffffffff ///< Indicates that there is no fixed limit on the number of items.
};
/// @brief Information about a granted award (milestone)
///
/// @details When querying for awards, this structure will be filled out with summary information about any award granted to the user.
struct SenAwardMessageData
{
wchar_t awardDesc[128]; ///< Localized string containing a message for display.
unsigned int awardPoints; ///< Fame Points granted as a result of this award.
unsigned int awardTrigger; ///< Progress within the associated Challenge that caused the award to trigger.
};
/// @brief Measures a time period.
///
/// @details Provides a display-friendly way to report time differences - e.g. the time until the current Fame week expires.
struct SenFameTime
{
int days;
int hours;
int minutes;
int seconds;
};
/// @brief Information about a user's progress against a single Challenge
///
/// @details Provides a display-friendly format for retrieving information about a user's progress against Fame Challenges.
///
struct SenFameDisplayData
{
wchar_t milestoneTypeDescription[128]; ///< Localized string that describes the challenge.
SenFameProgressID milestoneTypeID; ///< ID for the Challenge.
unsigned int milestoneCount; ///< Total number of milestones (awards) available for this Challenge. May be SenFameCount_Unbounded.
unsigned int currentMilestone; ///< Index of the milestone the user is currently working towards (i.e. 0 indicates no milestones have been passed).
unsigned int xpSinceLastMilestone; ///< Progress achieved since the last milestone in this Challenge was passed.
unsigned int xpToNextMilestone; ///< Progress required to hit the next milestone in this Challenge. Expressed as the progress difference between milestones, i.e. does not vary with xpSinceLastMilestone
unsigned int famePointsSoFar; ///< Fame Points achieved in this Challenge.
unsigned int famePointsMaximum; ///< Total Fame Points available from this Challenge. May be SenFameCount_Unbounded.
bool isWeekly; ///< When true, progress against this Challenge is reset weekly.
};
/// @brief Information about a participant in a multiplayer game.
///
/// @details Use for reporting information about multiplayer games to the Sentient server.
///
struct SenFameMPGameParticipant
{
PlayerUID user; ///< ID of a user who should be credited with participation in the game.
bool winner; ///< When true, this user should be considered among the winners of the game. There are no restrictions on the number of 'winners' a game may have.
};
/**************************
***** Fame Functions *****
**************************/
/// @brief Query the server for VIP status information for a collection of arbitrary users.
///
/// @param[in] userIndex
/// The index of the initiating user on the console. Note: This is NOT a XUID.
///
/// @param[in] userIDCount
/// The number of valid XUIDs in @a userIDArray
///
/// @param[in] userIDArray
/// Users for whom VIP data should be retrieved.
///
/// @param[out] out_userFameVIPArray
/// The structures to fill in with the retrieved information.
/// It is assumed that this is preallocated to at least @a userIDCount entries.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// E_POINTER: out_userFameVIPArray is NULL.
/// SENTIENT_E_TOO_MANY_CALLS: This call has been rejected to avoid excessive server load. Try again later.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details This overload can be used to retrieve VIP status for friends or remote participants in a multiplayer session.
/// For local users, prefer SenGetFameVIPLevel(int, SenFameVIPData*)
///
HRESULT SenGetFameVIPLevel(
int userIndex,
size_t userIDCount,
const PlayerUID *userIDArray,
SenFameVIPData *out_userFameVIPArray,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief Query for VIP status information for a local user.
///
/// @param[in] userIndex
/// The index of the initiating user on the console. Note: This is NOT a XUID.
///
/// @param[out] out_fameVIPData
/// The structure to fill in with the retrieved information.
/// It is assumed that this is preallocated to fit at least 1 entry.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// E_POINTER: out_fameVIPData is NULL.
/// SENTIENT_S_OPERATION_IN_PROGRESS: The call could not be completed immediately and out_fameVIPData has not been filled in.
/// S_OK: The operation completed successfully.
///
/// @details This overload is preferred when retrieving information about local users.
/// There are no restrictions on the call frequency and it will typically return immediately.
/// In rare cases where SENTIENT_S_OPERATION_IN_PROGRESS is returned the title should call again
/// on the next scheduled iteration of their Sentient update loop.
///
HRESULT SenGetFameVIPLevel(
int userIndex,
SenFameVIPData *out_fameVIPData );
/// @brief Acknowledge a change in user VIP level reported by the server.
///
/// @param[in] userIndex
/// The index of the initiating user on the console. Note: This is NOT a XUID.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details When retrieving user VIP status, the server will include the user's last VIP level
/// for which it has not received an acknowledgement message. Titles can use this information
/// to highlight changes in VIP level. Once a change has been messaged titles should
/// call this API to clear the server state.
HRESULT SenAcknowledgeVIPLevelChange(
int userIndex );
/// @brief Query a Fame leaderboard
///
/// @param[in] userIndex
/// The index of the initiating user on the console. Note: This is NOT a XUID.
///
/// @param[in] leaderboardRequest
/// Defines the parameters for the leaderboard query.
///
/// @param[in] entryCountMax
/// The maximum number of leaderboard rows to return.
///
/// @param[out] out_entryArray
/// The structures to fill in with the rows returned from the leaderboard query.
/// It is assumed that this is preallocated to hold at least entryCountMax entries.
///
/// @param[out] out_leaderboardResults
/// Summary information about the results of the leaderboard query.
///
/// @param[out] out_senHandle
/// Provides a handle to the async task, which will allow for calling SentientCancel
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// E_POINTER: out_entryArray or out_leaderboardResults is NULL.
/// E_INVALIDARG: userCallback is NULL and out_senHandle is non-NULL. Task handles are not supported for synchronous requests.
/// SENTIENT_E_TOO_MANY_CALLS: This call has been rejected to avoid excessive server load. Try again later.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
HRESULT SenGetFameLeaderboard(
int userIndex,
const SenFameLeaderboardRequest &leaderboardRequest,
size_t entryCountMax,
SenFameLeaderboardEntry *out_entryArray,
SenFameLeaderboardResults *out_leaderboardResults,
SenHandle *out_senHandle,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief Poll for notifications of when a user passes a Fame milestone.
///
/// @param[in] userIndex
/// The index of the initiating user on the console. Note: This is NOT a XUID.
///
/// @param[out] out_awardData
/// Structure to fill in with information about any new award.
///
/// @return SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// E_POINTER: out_awardData is NULL.
/// SENTIENT_S_OPERATION_IN_PROGRESS: The call could not be completed immediately and out_awardData has not been filled in.
/// S_FALSE: The operation completed successfully but there were no awards to report. out_awardData has not been filled in.
/// S_OK: The operation completed successfully and there was a valid award to report. out_awardData contains information about the award.
///
/// @details There are no restrictions on how frequently this API may be called, and it returnes immediately, so titles should poll
/// in all states where they can display award messages. When a message is returned it is popped from an internal queue
/// and will not be returned again by further calls.
///
HRESULT SenGetAwardMessage(
int userIndex,
SenAwardMessageData *out_awardData );
/// @brief Retrieve the time left before weekly fame progress is reset.
///
/// @param[out] out_timeRemaining
/// Structure to fill in with information about time remaining.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_POINTER: out_timeRemaining is NULL.
/// SENTIENT_S_OPERATION_IN_PROGRESS: The call could not be completed immediately and out_timeRemaining has not been filled in.
/// E_FAIL: Internal failure. Check log for output.
/// S_OK: Call completed successfully and out_timeRemaining has been filled in.
///
/// @details Some Fame Challenges are reset weekly. Use this API when displaying a timer for the reset.
///
HRESULT SenGetTimeLeftInFameWeek(
SenFameTime *out_timeRemaining );
//
/// @brief Retrieve the time left before transient VIP level is reset.
///
/// @param[in] userIndex
/// The index of the initiating user on the console. Note: This is NOT a XUID.
///
/// @param[out] out_timeRemaining
/// Structure to fill in with information about time remaining.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// E_POINTER: out_timeRemaining is NULL.
/// SENTIENT_S_OPERATION_IN_PROGRESS: The call could not be completed immediately and out_timeRemaining has not been filled in.
/// S_FALSE: The VIP level of the supplied user does not expire. out_timeRemaining has not been filled in.
/// E_FAIL: Internal failure. Check log for output.
/// S_OK: Call completed successfully and out_timeRemaining has been filled in.
///
/// @details Some VIP levels are reset if the user does not actively maintain them. Use this API
/// when displaying a timer for the reset.
///
HRESULT SenGetTimeLeftInVIPLevel(
int userIndex,
SenFameTime *out_timeRemaining );
/// @brief Get a localized string that names the given VIP level.
///
/// @param[in] vipLevel
/// The level whose name should be returned.
///
/// @param[in] maxNameLength
/// The maximum length (including null terminating character) of the string to return.
///
/// @param[out] out_name
/// The string to fill in with the VIP level name.
/// It is assumed that this is preallocated to fit at least @a maxNameLength characters.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_POINTER: out_name is NULL.
/// E_INVALIDARG: vipLevel is outside the range of known VIP levels.
/// SENTIENT_S_OPERATION_IN_PROGRESS: The call could not be completed immediately and out_name has not been filled in.
/// S_OK: The operation completed successfully.
///
/// @details Titles can use this API to get the server-defined name for a VIP level for additional flexibility post-release.
/// In rare cases where SENTIENT_S_OPERATION_IN_PROGRESS is returned the title should call again
/// on the next scheduled iteration of their Sentient update loop.
///
HRESULT SenGetVIPLevelName(
unsigned int vipLevel,
size_t maxNameLength,
wchar_t *out_name);
/// @brief Get the maximum number of items that will be returned by a call to SenGetFameDisplayData
///
/// @param[out] out_count
/// Location to be filled in with the number of display data items available.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// E_POINTER: out_count is NULL.
/// SENTIENT_S_OPERATION_IN_PROGRESS: The call could not be completed immediately and out_count has not been filled in.
/// E_FAIL: Internal failure. Check log for output.
/// S_OK: The operation completed successfully.
///
/// @details Titles can use this API to ensure that they allocate a buffer of appropriate size
/// before making a call to SenGetFameDisplayData.
///
HRESULT SenGetFameDisplayDataCount(
size_t *out_count );
/// @brief Retrieve a summary of a user's progress against Fame Challenges.
///
/// @param[in] userIndex
/// The index of the initiating user on the console. Note: This is NOT a XUID.
///
/// @param[in] startIndex
/// Global index of first item to return.
/// This parameter can be used to support results paging.
///
/// @param[in] maxDisplayDataCount
/// Maximum number of items to return.
///
/// @param[out] out_dataCount
/// Location to fill in with number of items actually returned.
///
/// @param[out] out_displayData
/// The structures to fill in with the retrieved information.
/// It is assumed that this is preallocated to at least @a maxDisplayDataCount entries.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// E_POINTER: out_dataCount or out_displayData is NULL.
/// E_INVALIDARG: startIndex is greater than the total number of items available.
/// SENTIENT_S_OPERATION_IN_PROGRESS: The call could not be completed immediately and output parameters have not been filled in.
/// E_FAIL: Internal failure. Check log for output.
/// S_OK: The operation completed successfully.
///
/// @details For titles with weekly Challenge rotations, only Challenges active for the current week are reported.
/// Use SenGetFameDisplayDataCount() to dynamically size a buffer large enough to obtain all the display data entries
/// in a single call, or use the startIndex parameter for paging.
///
HRESULT SenGetFameDisplayData(
int userIndex,
size_t startIndex,
size_t maxDisplayDataCount,
size_t *out_dataCount,
SenFameDisplayData *out_displayData );
/// @brief Notify Sentient about user progress against a Fame Challenge.
///
/// @param[in] userIndex
/// The index of the initiating user on the console. Note: This is NOT a XUID.
///
/// @param[in] milestoneTypeID
/// The id of the Challenge for which progress has been achieved.
///
/// @param[in] xpGained
/// Incremental progress. For binary milestones this can be safely set to 1 each time the awarding event takes place.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// SENTIENT_E_BUFFER_EXHAUSTED: The progress update failed because Sentient's internal buffer is full.
/// E_FAIL: Internal failure. Check log for output.
/// S_OK: The operation completed successfully.
///
/// @details Titles should call this API whenever a user makes progress against a Fame Challenge. Long-term storage for progress exists
/// on the Sentient server, but it may be buffered on the client to prevent excessive server load. Titles should call
/// SenFlushFameProgress as appropriate (e.g. on game save) to ensure that all progress writes are committed to the server.
/// Titles should not submit updates against Fame Challenges whose progress is determined by the server(e.g. First Play)
HRESULT SenUpdateFameProgress(
int userIndex,
unsigned int milestoneTypeID,
unsigned int xpGained );
/// @brief Ensure that all progress writes are committed to the Sentient server.
///
/// @param[in] userIndex
/// The index of the initiating user on the console. Note: This is NOT a XUID.
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// SENTIENT_E_TOO_MANY_CALLS: This call has been rejected to avoid excessive server load. Try again later.
/// E_FAIL: Failed to spawn server call. This may be because there is already a flush scheduled.
/// S_OK: The operation completed successfully.
///
/// @details Long-term storage for progress exists on the Sentient server, but it may be buffered on the client to
/// prevent excessive server load. Titles should call this API as appropriate (e.g. on game save) to ensure
/// that all progress writes are committed to the server. The callback parameters provide a mechanism for
/// detecting when the server call has completed and updating user interface appropriately.
/// When there is no local data that needs flushing, the supplied callback will be invoked before execution
/// returns from this function, and the return code will be S_OK.
///
HRESULT SenFlushFameProgress(
int userIndex,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief Inform the Sentient server about the results of a multiplayer game.
///
/// @param[in] userIndex
/// The index of the initiating user on the console. Note: This is NOT a XUID.
///
/// @param[in] participantCount
/// The number of valid items in @a participants.
///
/// @param[in] participants
/// Structures describing the users who participated in this multiplayer game.
///
/// @param[out] out_senHandle
/// Provides a handle to the async task, which will allow for calling SentientCancel
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_GUEST_ACCESS_VIOLATION: A guest may not spawn this call.
/// E_INVALIDARG: Either userCallback is NULL and out_senHandle is non-NULL, or participantCount is less than 2.
/// E_POINTER: participants is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details Titles should report multiplayer sessions to the Sentient server via this API in order to support
/// tracking of progress against certain Fame Challenges. For proper tracking each user in the multiplayer
/// session should independently call this function on completion of a game.
HRESULT SenRegisterFameMPGame(
int userIndex,
size_t participantCount,
const SenFameMPGameParticipant *participants,
SenHandle *out_senHandle,
SenSysCompletedCallback userCallback,
void *userCallbackData );
} // namespace Sentient

View File

@@ -0,0 +1,134 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client File API
//
// Include this to get access to all File-related Sentient features.
#pragma once
#include "SenClientTypes.h"
namespace Sentient
{
//=======================//
// //
// File Data Types //
// //
//=======================//
struct SenRawDataTransferInfo;
/// @brief A unique file identifier.
///
/// @details A SenFileID represents a unique revision of a file in the file DB.
/// These should only be obtained from the API and never specified manually,
/// with the exception of the SenFileID_Invalid enumeration below.
enum SenFileID : INT32
{
/// A non-existent file. This is expected when a file is not found, for instance.
SenFileID_Invalid = 0x00000000,
};
/// @brief Stores a digest of a file.
///
/// @details This is a 128-bit digest, checksum, CRC, etc. (currently an MD5) of a file.
/// We typically use this to determine whether a file's contents are different or corrupt.
///
struct SenFileDigest
{
UINT8 value[16]; ///< The raw bytes of the digest.
};
/// @brief Basic file transfer information.
///
/// @details Resource-specific data structures use this, or a SenPackageFileTransferInfo,
/// to indicate how one can transfer a file to the console.
/// The internal file download routine takes this structure directly.
///
struct SenFileTransferInfo
{
SenFileID fileID; ///< Used for locating the file data on the server.
SenSysFileSize fileSize; ///< The expected size of the file data. Don't read this directly--use the GetFileSize() method;
SenFileDigest digest; ///< The expected file digest of the file data.
/// @brief Test to see if this contains a real file.
///
/// @details Returns true if this structure appears to refer to an actual file,
/// but does not tell you if the file actually exists on the server.
/// Attempt to download the file to determine whether or not it exists.
///
bool IsValid() const;
/// @brief Get the actual data size.
///
/// @details Returns the exact size of the data--no rounding. Do NOT use this for
/// allocating destination buffers. Use GetBufferSize() for that.
///
SenSysFileSize GetFileSize() const;
/// @brief Get the buffer size necessary to download the data.
///
/// @details This will return a size which is greater than or equal to the data size.
/// It may be rounded up somewhat (to, e.g. a 2k boundary) for the purposes
/// of more efficient data transfers. Make absolutely certain that you use
/// THIS size for allocating destination buffers, and NOT GetFileSize().
///
SenSysFileSize GetBufferSize() const;
};
//======================//
// //
// File Functions //
// //
//======================//
// Handy utility functions to handle digests:
/// @brief Calculate a SenFileDigest from a buffer.
///
/// @param[in] dataSize
/// Number of bytes in data.
///
/// @param[in] data
/// The actual raw data of the file.
///
/// @return A SenFileDigest calculated from the passed data.
///
/// @details Calculate a SenFileDigest from a buffer. Currently, this is an MD5.
///
/// @related SenFileDownload()
/// @related SenFileDigestCreate()
///
SenFileDigest SenFileDigestCreate( size_t dataSize, const BYTE *data );
/// @brief Compare two SenFileDigests for equality.
///
/// @param[in] value0
/// This is the left value for the comparison.
///
/// @param[in] value1
/// This is the right value for the comparison.
///
/// @return Returns a bool: true if value0==value1, false if not.
///
bool operator ==( const SenFileDigest &value0, const SenFileDigest &value1 );
/// @brief Compare two SenFileDigests for inequality.
///
/// @param[in] value0
/// This is the left value for the comparison.
///
/// @param[in] value1
/// This is the right value for the comparison.
///
/// @return Returns a bool: true if value0!=value1, false if not.
///
bool operator !=( const SenFileDigest &value0, const SenFileDigest &value1 );
} // namespace Sentient

View File

@@ -0,0 +1,13 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client AvatarSuperstars HelpFile API
//
// Include this to get access to all HelpFile-related Sentient features.
#pragma once
// SenHelp functionality has been deprecated (and removed)

View File

@@ -0,0 +1,85 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client Main API
//
// Include this to get access to all core Sentient features.
#pragma once
#include "SenClientTypes.h"
namespace Sentient
{
//=======================//
// //
// Main Data Types //
// //
//=======================//
// None at the moment.
//======================//
// //
// Main Functions //
// //
//======================//
/// @brief Initialize and start Sentient.
///
/// @param[in] titleID
/// Tells Sentient what our titleID is.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// E_FAIL (and other E_* codes): Failed to initialize.
/// S_OK: Initialized successfully.
///
/// @details Call this on startup to set up networking system and initialize internal buffers.
///
HRESULT SentientInitialize(
SenSysTitleID titleID );
/// @brief Update Sentient's internal state.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine overall success.
/// The return code contains information about the status of the connection to sentient, including:
/// S_OK: we have a working connection to the Sentient server.
/// SENTIENT_S_NOT_SIGNED_IN_TO_LIVE: no live enabled user user is currently signed in to live.
/// SENTIENT_S_INITIALIZING_CONNECTION: a user has signed in, and we have started first connection attempt, but we have neither succeeded nor failed yet.
/// SENTIENT_S_SERVER_CONNECTION_FAILED: a connection attempt has failed, or that an existing connection was lost.
///
/// @details Call this every frame to handle network message pumping and to trigger asynchronous callbacks on completed ( or failed ) tasks.
///
HRESULT SentientUpdate();
/// @brief Stop and uninitialize Sentient.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// E_FAIL (and other E_* codes): Failed to shut down.
/// S_OK: Shut down successfully.
/// Note that one should consider the library shut down even if an error code is returned.
///
/// @details Call this on app/game shutdown. (not necessary on X360)
///
HRESULT SentientShutdown();
/// @brief Cancel an asynchronous task.
///
/// @param[in] task
/// The task to cancel.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// E_FAIL (and other E_* codes): Failed to cancel task.
/// S_OK: Task cancelled successfully.
///
/// @detail Call this to immediately cancel any task that exposes a SenHandle.
/// The completion callback will be invoked on a successful cancel.
///
HRESULT SentientCancel( SenHandle task );
} // namespace Sentient

View File

@@ -0,0 +1,55 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client UGC API
//
// Include this to get access to Markers.
#pragma once
#include "SenClientSys.h"
namespace Sentient
{
/************************
***** Marker Types *****
************************/
struct SenMarker
{
float x, y, z;
PlayerUID user;
int userData;
int userData2;
};
/****************************
***** Marker Functions *****
****************************/
HRESULT SenMarkerAdd(
int userIndex,
SenSysTitleID titleID,
SenUGCID ugcID,
const SenMarker *marker );
HRESULT SenMarkerGetWithinArea(
SenSysTitleID titleID,
SenUGCID ugcID,
float xMin, float yMin, float zMin,
float xMax, float yMax, float zMax,
int maxCount,
PlayerUID friendsOf,
int minTag,
int maxTag,
int tagMask,
SenMarker **out_buffer,
SenSysCompletedCallback userCallback,
void *userCallbackData );
} // namespace Sentient

View File

@@ -0,0 +1,91 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client News API
//
// Include this to get access to all News-related Sentient features.
#pragma once
#include "SenClientTypes.h"
namespace Sentient
{
// Maximum number of items that will be returned from the service
static const size_t MAX_NEWS_ITEM_COUNT = 20;
// Default news cache expire time
// News cache expire time controls the duration between service synchronization.
// This duration is measured in seconds. Default value is 6 minutes
static const int CACHE_EXPIRE = 5 * 60 * 1000;
// Extern linkage for News Item Count
extern size_t newsItemCount;
class NewsItemCountClass
{
public: NewsItemCountClass() { newsItemCount = MAX_NEWS_ITEM_COUNT; };
};
static NewsItemCountClass newsItemCountClass;
// Extern linkage for cache expire
extern int cacheExpire;
class CacheExpireTimeoutClass
{
public: CacheExpireTimeoutClass() { cacheExpire = CACHE_EXPIRE; };
};
static CacheExpireTimeoutClass cacheExpireTimeoutClass;
// Default characters per second
// Used for displaying local news messages through the PostLocalNews API
// Used for displaying default news messages through the SetDefaultNewsStrings API
static const float DEFAULT_CHARS_PER_SEC = 2.0f;
// Max size for news ticker messages
static const size_t MAX_NEWS_TICKER_MESSAGE_SIZE = 256;
/**************************
***** News Types *****
**************************/
enum SenTickerMessageType
{
SenTickerMessageType_Text = 0,
SenTickerMessageType_MarketplaceOffer,
SenTickerMessageType_Max
};
struct SenTickerData
{
wchar_t message[MAX_NEWS_TICKER_MESSAGE_SIZE];
SenTickerMessageType messageType;
INT64 data1;
INT64 data2;
float charPerSec;
};
/**************************
***** News Functions *****
**************************/
// Ticker messages need to be pulled whenever the ticker is displayed. Call this function to get the next message to display
/// @brief public
///
/// @param[in\out] userIndex
/// @param[in\out] out_tickerData
///
/// @return HRESULT
///
/// @details <Insert detailed method documentation>
///
/// @related <Related API>
HRESULT SenGetTickerMessage(
int userIndex,
SenTickerData *out_tickerData );
} // namespace Sentient

View File

@@ -0,0 +1,73 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client Package API
//
// Include this to get access to all Package-related Sentient features.
#pragma once
#include "SenClientTypes.h"
namespace Sentient
{
//==========================//
// //
// Package Data Types //
// //
//==========================//
/// Private.
struct SenPackageInfo;
/// @brief Basic file transfer information.
///
/// @details Resource-specific data structures use this, or a SenFileTransferInfo,
/// to indicate how one can transfer a file to the console.
/// The internal package file download routine takes this structure directly.
///
struct SenPackageFileTransferInfo
{
const SenPackageInfo *package;
const char *filename;
SenSysFileSize fileSize;
/// @brief Test to see if this contains a real file.
///
/// @details Returns true if this structure appears to refer to an actual file,
/// but does not tell you if the file actually exists in a package.
/// Attempt to download the file to determine whether or not it exists.
///
bool IsValid() const;
/// @brief Get the actual data size.
///
/// @details Returns the exact size of the data--no rounding. Do NOT use this for
/// allocating destination buffers. Use GetBufferSize() for that.
///
SenSysFileSize GetFileSize() const;
/// @brief Get the buffer size necessary to download the data.
///
/// @details This will return a size which is greater than or equal to the data size.
/// It may be rounded up somewhat (to, e.g. a 2k boundary) for the purposes
/// of more efficient data transfers. Make absolutely certain that you use
/// THIS size for allocating destination buffers, and NOT GetFileSize().
///
SenSysFileSize GetBufferSize() const;
};
//=========================//
// //
// Package Functions //
// //
//=========================//
// None at the moment.
} // namespace Sentient

View File

@@ -0,0 +1,83 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client RawData API
//
// Include this to get access to all RawData-related Sentient features.
#pragma once
#include "SenClientFile.h"
#include "SenClientPackage.h"
namespace Sentient
{
//==========================//
// //
// RawData Data Types //
// //
//==========================//
/// @brief Raw data transfer information type.
///
/// @details Used to denote what kind of raw data is being described in a SenRawDataTransferInfo.
///
enum SenRawDataType
{
/// A SenRawDataTransferInfo with this type contains nothing.
SenRawDataType_Invalid,
/// A SenRawDataTransferInfo with this type contains a SenFileTransferInfo.
SenRawDataType_File,
/// A SenRawDataTransferInfo with this type contains a SenPackageFileTransferInfo.
SenRawDataType_Package,
};
/// @brief Basic raw data transfer information.
///
/// @details This structure contains enough information to retrieve any data.
/// Note: The choice of package vs. file is made internally.
/// Developers may use these struct contents for debugging purposes, but
/// should never rely on anything below the level of this struct and its
/// methods in their own code. All manipulation/exploration should be API-based.
///
struct SenRawDataTransferInfo
{
SenRawDataType type; ///< Indicates which part of the union below to use.
union
{
SenFileTransferInfo file; ///< Only valid if type == SenRawDataType_File;
SenPackageFileTransferInfo package; ///< Only valid if type == SenRawDataType_Package;
};
/// @brief Test to see if this contains a real file.
///
/// @details Returns true if this structure appears to refer to an actual file,
/// but does not tell you if the file actually exists.
/// Attempt to download the file to determine whether or not it exists.
///
bool IsValid() const;
/// @brief Get the actual data size.
///
/// @details Returns the exact size of the data--no rounding. Do NOT use this for
/// allocating destination buffers. Use GetBufferSize() for that.
///
SenSysFileSize GetFileSize() const;
/// @brief Get the buffer size necessary to download the data.
///
/// @details This will return a size which is greater than or equal to the data size.
/// It may be rounded up somewhat (to, e.g. a 2k boundary) for the purposes
/// of more efficient data transfers. Make absolutely certain that you use
/// THIS size for allocating destination buffers, and NOT GetFileSize().
///
SenSysFileSize GetBufferSize() const;
};
} // namespace Sentient

View File

@@ -0,0 +1,111 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client Resource API
//
// Include this to get access to all Resource-related Sentient features.
#pragma once
#include "SenClientTypes.h"
namespace Sentient
{
//======================//
// //
// Resource Types //
// //
//======================//
/// @brief Resource types/categories.
///
/// @details This value is normally used to fill the top 8 bits of a resource ID, with the bottom 24 being an index.
///
enum SenResourceType : INT8
{
SenResourceType_Invalid,
SenResourceType_Avatar,
SenResourceType_BoxArt,
SenResourceType_Config,
SenResourceType_Help,
};
/// @brief Resource types/categories.
///
/// @details The top 8 bits are always the SenResourceType. The bottom 24 are typically an index into the category.
/// These categories do not overlap, so that we can choose to store different resource types in the same or
/// different tables, depending on what is more useful. Note, though, that you should expect E_INVALIDARG
/// back if you pass an ID from one category to a call wanting a different category.
/// Some categories' IDs will be hardwired/assumed, while others will be generated inside of Microsoft (e.g. box art).
///
enum SenResourceID : INT32
{
/// This is used to indicate a failed search, an invalid resource structure, or sometimes to substitute for a default.
SenResourceID_Invalid = (INT32)SenResourceType_Invalid << 24,
/// This is the first VIP reward costume and there is one for each title.
SenResourceID_Superstar_0 = (INT32)SenResourceType_Avatar << 24,
/// This is the second VIP reward costume and there is one for each title.
SenResourceID_Superstar_1,
/// This is the third VIP reward costume and there is one for each title.
SenResourceID_Superstar_2,
/// This is the fourth VIP reward costume and there is only one, shared across all titles.
SenResourceID_Superstar_3,
/// This is the fifth VIP reward costume and there is only one, shared across all titles.
SenResourceID_Superstar_4,
/// This is used for the cross-sell screen and contains things such as an image, offerID, strings, etc.
SenResourceID_BoxArt_0 = (INT32)SenResourceType_BoxArt << 24,
/// This is used for game-private config files, and is only the base of the range.
/// Titles may use the entire 24-bit space for various custom config files.
SenResourceID_Config_0 = (INT32)SenResourceType_Config << 24,
/// This is used for server-supplied help files/text.
/// At the moment, this is not supported.
SenResourceID_Help_0 = (INT32)SenResourceType_Help << 24,
};
/// @brief Resource schedule priority.
///
/// @details This is currently reserved for later use in overriding one resource with another on a schedule.
/// It is not currently used and may be changed at a later date.
///
typedef INT32 SenResourcePriority;
enum
{
SenResourcePriority_Default = 0,
};
/// @brief Generic resource information.
///
/// @details This structure contains enough information to uniquely identify
/// one resource at a given time on the schedule, e.g. an avatar or
/// box art at 3am. (Note that schedules are not currently used and
/// may be re-architected in the future.)
///
struct SenResourceInfo
{
SenSysTitleID titleID; ///< This is the title the resource is assigned to, or SenTitleID_Shared for all.
SenResourceID resourceID; ///< This is the resource ID within the title's space.
SenResourcePriority priority; ///< Schedule priority. This is not currently used and may be changed at a later date.
SYSTEMTIME begins; ///< Scheduled begin time (inclusive). This is not currently used and may be changed at a later date.
SYSTEMTIME ends; ///< Scheduled end time (exclusive). This is not currently used and may be changed at a later date.
};
//==========================//
// //
// Resource Functions //
// //
//==========================//
// None at the moment.
} // namespace Sentient

View File

@@ -0,0 +1,133 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client Stats API
//
// Include this to get access to all Stats-related Sentient features.
#pragma once
#include "SenClientTypes.h"
namespace Sentient
{
/***********************
***** Stats Types *****
***********************/
#define SenStatID_Custom 128
// Stats
#define SenStatFlag_Normal 1
#define SenStatFlag_Time 2
#define SenStatFlag_TimeEnd 4
// Params
#define SenStatValueFlag_Inc 1
#define SenStatValueFlag_Accum 2
#define SenStatValueFlag_Min 4
#define SenStatValueFlag_Max 8
// Enable Logging if we are in debug build
#ifdef _DEBUG
#define SEN_LOGTELEMETRY
#endif
struct SenStat
{
DWORD dwUserID;
DWORD dwStatID;
DWORD dwFlags; // SenStatFlag_*
DWORD dwNumProperties;
CHAR* arrProperties;
DWORD dwNumValues;
CHAR* arrValues;
DWORD* arrValueFlags; // SenStatValueFlag_*
};
/***************************
***** Stats Functions *****
***************************/
/// @brief Submit a stat entry to the sentient system
///
/// @param[in] pStat
/// The pointer to SenStat structure. The SentientStatsSend function is usually called from the autogenerated fuctions
/// which use as [in] parameters the userIndex(0 through 3) and the set of the stat properties/values. The rest of the SenStat structure memebers are
/// created automatically from the stat xml file generated code.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
/// @details Calls to this function should use generated Telemetry code, rather than
/// calling the function from title code
HRESULT SentientStatsSend( SenStat *pStat );
/// @brief Sets the send interval for Telemetry. Only works in debug builds
///
/// @param[in] dwIntervalMs
/// The new send interval, in milliseconds. This value is capped at a minimum of 250 ms.
///
/// @details The body of this function is conditionally compiled out of non-debug builds.
///
void SentientSetStatSendInterval( DWORD dwIntervalMs );
/// @brief Requests that Sentient immediately send any stats being buffered
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_TOO_MANY_CALLS: You tried to flush too quickly after a previous flush.
/// S_OK: Buffered stats will be flushed to the server on the next Sentient::Update() call
///
/// @details This API can only be called once every minute. Any attempts to call the API more frequently
/// will result in the call being throttled, and the API returning SENTIENT_E_TOO_MANY_CALLS
/// Data is not actually sent until the next Sentient::Update() call
HRESULT SentientFlushStats( );
/// @brief Requests that Sentient immediately send any stats being buffered because the title is exiting
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_TOO_MANY_CALLS: You tried to flush on Exit more than once
/// S_OK: Buffered stats will be flushed to the server on the next Sentient::Update() call
///
/// @details This API can only be called ONCE. Any attempts to call the API more frequently
/// will result in the call being throttled, and the API returning SENTIENT_E_TOO_MANY_CALLS
/// Data is not actually sent until the next Sentient::Update() call
HRESULT SentientFlushStatsOnExit( );
/// @brief Requests that Sentient immediately send any stats being buffered because the title is going to the marketplace and may not return
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// SENTIENT_E_TOO_MANY_CALLS: You tried to flush on MarketPlace too many times
/// S_OK: Buffered stats will be flushed to the server on the next Sentient::Update() call
///
/// @details Any attempts to call the API too frequently will result in the call being throttled,
/// and the API returning SENTIENT_E_TOO_MANY_CALLS
/// Data is not actually sent until the next Sentient::Update() call
HRESULT SentientFlushStatsOnMarketPlace( );
/// @brief Tells Sentient that an important point in the game was hit and that events should be sent as soon as possible
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// S_OK: Buffered stats will be flushed to the server within the next minute
///
/// @details This API should be caleld when the game hits an important event or point.
/// Sentient Will send the event data to the server within the next minute, calling this method frequently will not cause any additional sends
HRESULT SentientFlushStatsOnKeyEvent( );
#ifdef SEN_LOGTELEMETRY
// if we're in debug build log out the stat to a file for testing
void SentientDebugLogStatSend(const char *statName, const SenStat *pStat);
#endif
} // namespace Sentient

View File

@@ -0,0 +1,20 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client AvatarSuperstars API
//
// Include this to get access to all Superstars-related Sentient features.
#pragma once
// Independent Sentient libraries that get rolled into Superstars
#include "SenClientNews.h"
#include "SenClientBoxArt.h"
// Superstars-specific includes
#include "SenClientAvatar.h"
#include "SenClientHelp.h"
#include "SenClientFame.h"

View File

@@ -0,0 +1,58 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client System API
//
// Include this to get access to all System Sentient features.
#pragma once
#include "SenClientTypes.h"
namespace Sentient
{
/************************
***** System Types *****
************************/
// Standardized callback that all asynchronous functions call either on completion or on failure.
typedef void (*SenSysCompletedCallback)( HRESULT taskResult, void *userCallbackData );
typedef void *(*SenSysMemAllocCallback)( size_t size );
typedef void (*SenSysMemFreeCallback)( void *ptr );
typedef void (*SenSysOutputCallback)( const wchar_t *outputString );
/****************************
***** System Functions *****
****************************/
#ifdef _XBOX
// Call this to get the XDK version number that Sentient was compiled against
int SenSysGetXDKVersion();
#endif
#ifdef __WINLIVE__
// Call this to get the GFWL version number that Sentient was compiled against
int SenSysGetGFWLSDKVersion();
#endif
// Sentient calls this to get total allocated memory.
// (this is only tracked in debug mode - in release mode, this will return 0)
size_t SenSysMemAllocated();
// Redirects all of Sentient's internal memory allocs to a custom allocator.
void SenSysSetMemAllocCallback( SenSysMemAllocCallback callback );
// Redirects all of Sentient's internal memory frees to a custom allocator.
void SenSysSetMemFreeCallback( SenSysMemFreeCallback callback );
// Redirects all of Sentient's internal output to a custom routine.
void SenSysSetOutputCallback( SenSysOutputCallback callback );
} // namespace Sentient

View File

@@ -0,0 +1,160 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client Types
//
// Include this to get access to all basic Sentient Types.
#pragma once
// These guarantees the presence of UINT32 et al, which we will be using
// for specific bitsized-types until we decide to switch to C++0x-style
// uint32_t (et al) types.
#if defined(_XBOX)
#include <xtl.h>
#include <xbox.h>
#else
#define NOD3D
#define WIN32_LEAN_AND_MEAN
#include <winlive.h>
//#include <windows.h>
#endif
#include <assert.h>
namespace Sentient
{
//============================//
// //
// Sentient Basic Types //
// //
//============================//
/// @brief A low-resolution timestamp.
///
/// @details This is the timestamp used by UGC. Its resolution is only ???. // TODO:
/// Full-resolution timestamps generally use SYSTEMTIME structures.
///
typedef UINT32 SenSysDateTime;
/// @brief A unique identifier per title.
///
/// @details Each title on Xbox Live is given a 32-bit title ID. We use these
/// to help identify title-specific resourced, UGC, etc.
/// Note that, except for the two special cases below, all title ID
/// values are considered private and should be obtained only through
/// Sentient APIs and structures. You should never create one manually.
///
enum SenSysTitleID : INT32
{
// Use this for your own title. It will be converted to your true
// title ID internally.
SenSysTitleID_This = (SenSysTitleID)0x00000000,
// Use this if you need to access shared, cross-game entries, which is
// typically the case.
SenSysTitleID_Shared = (SenSysTitleID)0xffffffff,
};
/// @brief A unique identifier for an offer on Xbox/Windows Live Marketplace.
///
/// @details This 64-bit value may be passed off to system routines that prompt
/// the user to browse/buy a product, such as a trial/demo or an avatar
/// item.
/// Note that, except for the the special case below, all offer ID
/// values are considered private and should be obtained only through
/// Sentient APIs and structures. You should never create one manually.
///
enum SenSysOfferID : INT64
{
// This is the value used when no offerID is available.
SenSysOfferID_Invalid = (SenSysOfferID)0x0000000000000000LL,
};
/// @brief The size of a resource file.
///
/// @details Note we're going to use this instead of size_t because the value type
/// coming down from the server will not necessarily match the client's
/// compiler notion of, say, size_t or int, which could be 64 bits.
///
typedef INT32 SenSysFileSize;
/// @brief A Sentient-specific handle.
///
/// @details These handles are currently used only for tracking and cancelling
/// asynchronous tasks.
///
/// @related SentientCancel()
///
typedef VOID *SenHandle;
// TODO: this really doesn't belong in SenCore's global types
typedef UINT64 SenUGCID;
/// @brief A unique identifier for a device.
///
/// @details Some routines want to know which device to default to.
/// This ID is a way to specify one. On Xbox, this is equivalent
/// to an XCONTENTDEVICEID and can be obtained in several ways
/// through the XDK. On Windows, this is TBD.
///
#ifdef _XBOX
typedef XCONTENTDEVICEID SenContentDeviceID;
#define SenContentDeviceID_Any XCONTENTDEVICE_ANY
#else
typedef DWORD SenContentDeviceID;
#define SenContentDeviceID_Any 0
#endif
//=========================//
// //
// Sentient HRESULTs //
// //
//=========================//
// Sentient HRESULT fields
#define SENTIENT_FACILITY 0x58
#define SENTIENT_E_FIRST_ERROR MAKE_HRESULT( SEVERITY_ERROR, SENTIENT_FACILITY, 0x0000 )
#define SENTIENT_S_FIRST_STATUS MAKE_HRESULT( SEVERITY_SUCCESS, SENTIENT_FACILITY, 0x0000 )
// Sentient Error codes
const HRESULT SENTIENT_E_NOT_INITIALIZED = SENTIENT_E_FIRST_ERROR + 0x0001; // 0x80580001 // title has tried to call a Sentient function when the library is not initialized.
const HRESULT SENTIENT_E_ALREADY_INITIALIZED = SENTIENT_E_FIRST_ERROR + 0x0002; // 0x80580002 // title has tried to initialize an already-initialized library.
const HRESULT SENTIENT_E_NO_UGC_PUBLISH_PRIVILEGE = SENTIENT_E_FIRST_ERROR + 0x0003; // 0x80580003 // user does not have the proper UGC upload/publish privilege flag set
const HRESULT SENTIENT_E_NO_UGC_USE_PRIVILEGE = SENTIENT_E_FIRST_ERROR + 0x0004; // 0x80580004 // user does not have the proper UGC download/use privilege flag set
const HRESULT SENTIENT_E_GUEST_ACCESS_VIOLATION = SENTIENT_E_FIRST_ERROR + 0x0005; // 0x80580005 // user is a guest, and therefore should not be accessing certain sentient features
const HRESULT SENTIENT_E_TOO_MANY_CALLS = SENTIENT_E_FIRST_ERROR + 0x0006; // 0x80580006 // title has called this API too frequently. Call has been discarded to avoid excessive server load.
const HRESULT SENTIENT_E_SERVER_ERROR = SENTIENT_E_FIRST_ERROR + 0x0007; // 0x80580007 // call generated an unhandled error on the server. Contact senhelp for assistance.
const HRESULT SENTIENT_E_TIME_OUT = SENTIENT_E_FIRST_ERROR + 0x0008; // 0x80580008 // the operation took too long to complete and has been abandoned.
const HRESULT SENTIENT_E_CANCELED = SENTIENT_E_FIRST_ERROR + 0x0009; // 0x80580009 // the operation was canceled by user sign-out or via an explicit call to SentientCancel
const HRESULT SENTIENT_E_FORBIDDEN = SENTIENT_E_FIRST_ERROR + 0x000a; // 0x8058000a // the server has indicated that the supplied user is not permitted to perform this operation.
const HRESULT SENTIENT_E_USERINDEX_IS_ANY = SENTIENT_E_FIRST_ERROR + 0x000b; // 0x8058000b // userIndex of ANY passed to a routine that requires a specific user.
const HRESULT SENTIENT_E_USERINDEX_IS_NONE = SENTIENT_E_FIRST_ERROR + 0x000c; // 0x8058000c // userIndex of NONE passed to a routine that requires a user.
const HRESULT SENTIENT_E_USERINDEX_IS_INVALID = SENTIENT_E_FIRST_ERROR + 0x000d; // 0x8058000d // userIndex is not a known value
const HRESULT SENTIENT_E_USERINDEX_IS_FOCUS = SENTIENT_E_FIRST_ERROR + 0x000e; // 0x8058000e // userIndex of FOCUS passed to a routine that requires a specific user.
const HRESULT SENTIENT_E_BUFFER_EXHAUSTED = SENTIENT_E_FIRST_ERROR + 0x000f; // 0x8058000f // no more space in buffer, operation was discarded
const HRESULT SENTIENT_E_RETRY_INVALID_DATA = SENTIENT_E_FIRST_ERROR + 0x0010; // 0x80580010 // retry; data was found to be invalid either after step or whole operation finished
const HRESULT SENTIENT_E_UNREACHABLE = SENTIENT_E_FIRST_ERROR + 0x0011; // 0x80580011 // Server was not reachable when called. Contact senhelp for assistance.
const HRESULT SENTIENT_E_RETRY_OVERLOADED = SENTIENT_E_FIRST_ERROR + 0x0012; // 0x80580012 // Server was overloaded when called. Retry later or contact senhelp for assistance.
const HRESULT SENTIENT_E_NO_UGC_DOWNLOAD_PRIVILEGE = SENTIENT_E_FIRST_ERROR + 0x0013; // 0x80580013 // user does not have the proper UGC download privilege flag set
const HRESULT SENTIENT_E_UGC_DOESNT_EXIST = SENTIENT_E_FIRST_ERROR + 0x0014; // 0x80580014 // requested action is aborted because the ugcid passed doesn't exist
const HRESULT SENTIENT_E_INVALID_UGC_PUBLISH_STATE = SENTIENT_E_FIRST_ERROR + 0x0015; // 0x80580015 // requested action is aborted because the UGC is in the wrong publish state
// Sentient Status/Success codes
const HRESULT SENTIENT_S_NOT_SIGNED_IN_TO_LIVE = SENTIENT_S_FIRST_STATUS + 0x0003; // 0x00580003
const HRESULT SENTIENT_S_INITIALIZING_CONNECTION = SENTIENT_S_FIRST_STATUS + 0x0004; // 0x00580004
const HRESULT SENTIENT_S_SERVER_CONNECTION_FAILED = SENTIENT_S_FIRST_STATUS + 0x0005; // 0x00580005
const HRESULT SENTIENT_S_OPERATION_IN_PROGRESS = SENTIENT_S_FIRST_STATUS + 0x0006; // 0x00580006
const HRESULT SENTIENT_S_NEWER_BLOB_EXISTS = SENTIENT_S_FIRST_STATUS + 0x0007; // 0x00580007 // UGC can have different versions of MainDataBlob with Republish API
} // namespace Sentient

View File

@@ -0,0 +1,957 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client UGC API
//
// Include this to get access to all UGC related Sentient features
#pragma once
// Local headers
#include "SenClientMarkers.h"
#include "SenClientUGCLeaderboards.h"
#include "SenClientUGCTypes.h"
// Sentient headers
#include "SenClientSys.h"
#include "SenClientCulture.h"
namespace Sentient
{
/**********************************
***** UGC Creation Functions *****
**********************************/
/// @brief Generate a unique ID that will be used to
/// identify a given instance of UGC. This ID
/// will is referenced by every other UGC function.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[out] outResult
/// The unique ID that has been generated and provisioned
/// for an instance of UGC.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return TBD
///
/// @details All UGC functions require a uniquely provisioned UGC ID.
///
/// @related All UGC related functions.
HRESULT SenUGCCreatePublishingUGCID(
int userIndex,
SenUGCID *outResult,
SenSysCompletedCallback userCallback,
void *userCallbackData );
///
/// @brief Async output information for SenUGCUpload or Download callers
///
/// @details Contains progress or retry information in addition to a cancellation token
///
struct SenUGCProgressInfo
{
SenHandle out_taskHandle; /// token for canceling the upload process
INT8 percentageComplete; /// 1-100, how much percent is complete of upload process for blob
size_t bytesCompleted; /// how many bytes have been successfully transmitted for the task
HRESULT lastStepResult; /// sentient client SDK HRESULT value
int numRetries; /// does not reset between internal steps for a long-running task
};
//************************************
// Method: SenUGCUpload
// FullName: Sentient::SenUGCUpload
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenUGCID ugcID
// Parameter: const SenUGCMetaData * metaData
// Parameter: int nrMainDataBlobs
// Parameter: const void * * mainDataBlobs
// Parameter: const size_t * mainDataBlobSizes
// Parameter: bool pushToFeed
// Parameter: SenSysCompletedCallback userCallback
// Parameter: void * userCallbackData
// Upload the metadata, as well as one or more binary data blobs to the server.
// There are multiple data blobs supported (the exact number is defined in
// SenUGCMainData_NrBlobs). One use would be that a game may want store a
// preview thumbnail that can be downloaded without having to download the
// rest of the UGC. This could save bandwidth and make the game more responsive.
// Note: data blob 0 should be the main level data blob, for the automatic
// download counter to work.
// The metadata will also have a data blob associated, but this should be
// kept to a minimum, as UGC download menus will probably want to download
// metadata for a lot of UGCs at once.
// Note: if a level has been uploaded with main data before, and the creator
// wants to just modify the metadata, they can upload the metadata with the
// maindatablobs being NULL.
// NOTE: for large items, use the SenUGCUploadMainData method with the SenUGCProgressInfo
// signature so you can get the running progress and a cancellation token
// to abort the upload (allowing UI for the user, etc)
//************************************
HRESULT SenUGCUpload(
int userIndex,
SenUGCID ugcID,
const SenUGCMetaData *metaData,
int nrMainDataBlobs,
const void **mainDataBlobs,
const size_t *mainDataBlobSizes,
SenSysCompletedCallback userCallback,
void *userCallbackData );
//************************************
// Method: SenUGCUploadMetadata
// FullName: Sentient::SenUGCUploadMetadata
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenUGCID ugcID
// Parameter: const SenUGCMetaData * metaData
// Parameter: SenSysCompletedCallback userCallback
// Parameter: void * userCallbackData
// Upload the metadata and one binary data blob to the server.
// NOTE: data blob at index 0 should be the main level data blob, for the automatic
// download counter to work.
// The metadata will also have a data blob associated, but this should be
// kept to a minimum, as UGC download menus will probably want to download
// metadata for a lot of UGCs at once.
// NOTE: If a creator uploads metadata again, it will overwrite the previous
// stored blob with the new one.
//************************************
HRESULT SenUGCUploadMetadata(
int userIndex,
SenUGCID ugcID,
const SenUGCMetaData* metaData,
SenSysCompletedCallback userCallback,
void* userCallbackData);
//************************************
// Method: SenUGCUploadMainData
// FullName: Sentient::SenUGCUploadMainData
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenUGCID ugcID
// Parameter: int mainDataBlobIndex
// Parameter: const void * mainDataBlob
// Parameter: const size_t mainDataBlobSize
// Parameter: SenSysCompletedCallback userCallback
// Parameter: void * userCallbackData
// Parameter: SenUGCProcessInfo* out_ugcUploadInfo
// Upload one binary data blob to the server.
// This SenUGCUpload method with the SenUGCProcessInfo signature is so you
// can get the progress percentage and a cancellation token, which can
// be used to abort the upload. This is useful for large uploads where
// you may want to allow the user to cancel.
// NOTE: This call is asynchronous ONLY and will error for synchronous
// attempts with a NULL param for userCallback.
// There are multiple data blobs supported (the exact number is defined in
// SenUGCMainData_NrBlobs) on subsequent calls. Slot zero is to be used by a
// game to store a preview thumbnail, which can then be downloaded without
// having to download the rest of the UGC. This could save bandwidth and
// make the game more responsive.
// NOTE: data blob at index 0 should be the main level data blob, for the automatic
// download counter to work.
// The metadata will also have a data blob associated, but this should be
// kept to a minimum, as UGC download menus will probably want to download
// metadata for a lot of UGCs at once.
// NOTE: if a level has been uploaded with main data before, and the creator
// wants to just modify the metadata, they can upload the metadata with the
// main data blob being NULL.
// NOTE: If a creator uploads a data blob again, it will overwrite the previous
// stored blob with the new one.
//************************************
HRESULT SenUGCUploadMainDataBlob(
int userIndex,
SenUGCID ugcID,
int mainDataBlobIndex,
const void* mainDataBlob,
const size_t mainDataBlobSize,
SenSysCompletedCallback userCallback,
void* userCallbackData,
SenUGCProgressInfo* out_progressInfo);
//************************************
// Method: SenUGCDelete
// FullName: Sentient::SenUGCDelete
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenUGCID ugcID
// Parameter: SenSysCompletedCallback userCallback
// Parameter: void * userCallbackData
// Delete the UGC - only the user that created the UGC can delete it.
//************************************
HRESULT SenUGCDelete(
int userIndex,
SenUGCID ugcID,
SenSysCompletedCallback userCallback,
void* userCallbackData );
/*************************************
***** UGC Consumption Functions *****
*************************************/
//************************************
// Method: SenUGCEnumerate
// FullName: Sentient::SenUGCEnumerate
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenSysTitleID titleID
// Parameter: SenUGCSortBy sortBy
// Parameter: SenUGCType type
// Parameter: SenUGCAuthorType authorType
// Parameter: int nrAuthors
// Parameter: const XUID * authorList
// Parameter: SenUGCMetaDataFlags metaDataFlagFilter
// Parameter: SenUGCPublishState minPublishStateFilter
// Parameter: SenUGCPublishState maxPublishStateFilter
// Parameter: SenSysDateTime newerThan
// Parameter: SenUGCDescriptor descriptor
// Parameter: int maxNrResults
// Parameter: SenUGCSearchResult * outBuffer
// Parameter: unsigned int * outNrResults
// Parameter: SenSysCompletedCallback userCallback
// Parameter: void * userCallbackData
// Search the database for all the UGCs that match various search criteria.
// outBuffer should be an preallocated array of [sizeof(SenUGCSearchResult)*maxNrResults] bytes.
//************************************
HRESULT SenUGCEnumerate(
int userIndex,
SenSysTitleID titleID,
SenUGCSortBy sortBy,
SenUGCType type,
SenUGCAuthorType authorType,
int nrAuthors,
const PlayerUID *authorList,
SenUGCMetaDataFlags metaDataFlagFilter,
SYSTEMTIME *newerThan,
SenUGCDescriptor descriptor,
int maxNrResults,
SenUGCSearchResult *outBuffer,
UINT *outNrResults,
SenSysCompletedCallback userCallback,
void* userCallbackData );
/// @brief public
///
/// @param[in] userIndex
/// @param[in] titleID
/// @param[in] sortBy
/// @param[in] type
/// @param[in] authorType
/// @param[in] nrAuthors
/// @param[in] authorList
/// @param[in] metaDataFlagFilter
/// @param[in] newerThan
/// @param[in] nrDescriptors
/// @param[in] descriptors
/// @param[in] maxNrResults
/// @param[out] outBuffer
/// @param[out] outNrResults
/// @param[in] userCallback
/// @param[in] userCallbackData
///
/// @return Search the database for all the UGCs that match various search criteria.
/// outBuffer should be an preallocated array of [sizeof(SenUGCSearchResult)*maxNrResults] bytes.
///
/// @details Enumerate by name will perform a look based on a various search criteria. The Collection
/// of descriptors will perform an equality lookup on Descriptor
///
/// @related SenUGCEnumerate
HRESULT SenUGCEnumerate(
int userIndex,
SenSysTitleID titleID,
SenUGCSortBy sortBy,
SenUGCType type,
SenUGCAuthorType authorType,
int nrAuthors,
const PlayerUID *authorList,
SenUGCMetaDataFlags metaDataFlagFilter,
SYSTEMTIME *newerThan,
int nrDescriptors,
INT64 *descriptors,
int maxNrResults,
SenUGCSearchResult *outBuffer,
UINT *outNrResults,
SenSysCompletedCallback userCallback,
void* userCallbackData );
/// @brief public
///
/// @param[in] userIndex
/// @param[in] titleID
/// @param[in] sortBy
/// @param[in] type
/// @param[in] authorType
/// @param[in] nrAuthors
/// @param[in] authorList
/// @param[in] metaDataFlagFilter
/// @param[in] newerThan
/// @param[in] nrDescriptors
/// @param[in] descriptors
/// @param[in] maxNrResults
/// @param[out] outBuffer
/// @param[out] outNrResults
/// @param[in] userCallback
/// @param[in] userCallbackData
///
/// @return Search the database for all the UGCs that match various search criteria.
/// outBuffer should be an preallocated array of [sizeof(SenUGCSearchResult)*maxNrResults] bytes.
///
/// @details Enumerate by Descriptor using a Logical And against all submitted Descriptor values.
/// The API filters the results on a specific UGC Type as well as an author
/// list type. Author List type of Everyone is NOT supported.
/// Note: The collection of descriptor bit masks is constrained to four.
///
/// @related SenUGCEnumerate
HRESULT SenUGCEnumerateByDescriptorWithLogicalAnd(
int userIndex,
SenSysTitleID titleID,
SenUGCSortBy sortBy,
SenUGCType type,
SenUGCAuthorType authorType,
int nrAuthors,
const PlayerUID *authorList,
SenUGCMetaDataFlags metaDataFlagFilter,
SYSTEMTIME *newerThan,
int nrDescriptors,
INT64 *descriptors,
int maxNrResults,
SenUGCSearchResult *outBuffer,
UINT *outNrResults,
SenSysCompletedCallback userCallback,
void* userCallbackData );
/// @brief public
///
/// @param[in] userIndex
/// @param[in] titleID
/// @param[in] type
/// @param[in] authorType
/// @param[in] nrAuthors
/// @param[in] authorList
/// @param[in] name
/// @param[in] maxNrResults
/// @param[out] outBuffer
/// @param[out] outNrResults
/// @param[in] userCallback
/// @param[in] userCallbackData
///
/// @return Search the database for all the UGCs that match various search criteria.
/// outBuffer should be an preallocated array of [sizeof(SenUGCSearchResult)*maxNrResults] bytes.
///
/// @details Enumerate by name will perform a wild card lookup on UGC name. The lookup will return anything
/// in the range of "%<NAME>%". The API filters the results on a specific UGC Type as well as an author
/// list type. Author List type of Everyone is NOT supported.
///
/// @related SenUGCEnumerate
__declspec(deprecated("Use SenUGCEnumerateByName() instead"))
HRESULT SenUGCEnumerate(
int userIndex,
SenSysTitleID titleID,
SenUGCType type,
SenUGCAuthorType authorType,
int nrAuthors,
const PlayerUID *authorList,
const wchar_t *name,
int maxNrResults,
SenUGCSearchResult *outBuffer,
UINT *outNrResults,
SenSysCompletedCallback userCallback,
void* userCallbackData );
/// @brief public
///
/// @param[in] userIndex
/// @param[in] titleID
/// @param[in] type
/// @param[in] authorType
/// @param[in] nrAuthors
/// @param[in] authorList
/// @param[in] name
/// @param[in] performWildCardLookup
/// @param[in] maxNrResults
/// @param[out] outBuffer
/// @param[out] outNrResults
/// @param[in] userCallback
/// @param[in] userCallbackData
///
/// @return Search the database for all the UGCs that match various search criteria.
/// outBuffer should be an preallocated array of [sizeof(SenUGCSearchResult)*maxNrResults] bytes.
///
/// @details Enumerate by name will perform an exact or wild card string lookup on UGC name. The API filters the results
/// on a specific UGC Type as well as an author list type. Author List type of Everyone is NOT supported.
///
/// @related SenUGCEnumerate
HRESULT SenUGCEnumerateByName(
int userIndex,
SenSysTitleID titleID,
SenUGCType type,
SenUGCAuthorType authorType,
int nrAuthors,
const PlayerUID *authorList,
const wchar_t *name,
bool performWildCardLookup,
int maxNrResults,
SenUGCSearchResult *outBuffer,
UINT *outNrResults,
SenSysCompletedCallback userCallback,
void* userCallbackData );
//************************************
// Method: SenUGCDownloadMetaData
// FullName: Sentient::SenUGCDownloadMetaData
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenSysTitleID titleID
// Parameter: int nrUGCs
// Parameter: const SenUGCID * ugcIDList
// Parameter: SenUGCDownloadedMetaData2 * outBuffer
// Parameter: SenSysCompletedCallback userCallback
// Parameter: void * userCallbackData
// Download the metadata for an array of UGCs
// Note that the metadata structure is a superset of the uploaded metadata,
// with various other information exposed.
// outBuffer should be an preallocated array of [(sizeof(SenUGCDownloadedMetaData)+SenUGCMetaData::BlobSizeLimit)*nrUGCs] bytes.
// This new signature is compatible with resubmission feature and 64-bit UGC Ids.
//************************************
HRESULT SenUGCDownloadMetaData(
int userIndex,
SenSysTitleID titleID,
int nrUGCs,
const SenUGCID *ugcIDList,
SenUGCDownloadedMetaData2 *out_metaData,
size_t *out_metaDataCount,
SenSysCompletedCallback userCallback,
void *userCallbackData );
__declspec(deprecated("Use signature with SenUGCDownloadedMetaData2."))
HRESULT SenUGCDownloadMetaData(
int userIndex,
SenSysTitleID titleID,
int nrUGCs,
const SenUGCID *ugcIDList,
SenUGCDownloadedMetaData *out_metaData,
size_t *out_metaDataCount,
SenSysCompletedCallback userCallback,
void *userCallbackData );
//************************************
// Method: SenUGCDownloadMainDataBlob
// FullName: Sentient::SenUGCDownloadMainDataBlob
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenUGCID ugcID
// Parameter: int mainDataBlobID
// Parameter: size_t bufferSize
// Parameter: UINT blobVersion
// Parameter: void * outBuffer
// Parameter: size_t * outSize
// Parameter: SenSysCompletedCallback userCallback
// Parameter: void * userCallbackData
// Download a single blob of UGC data
// note that zero byte downloads will fail.
// ID, blobVersion, and bufferSize should be coming
// from SenUGCDownloadedMetaData.
// outBuffer should be an preallocated array of bufferSize bytes.
//************************************
HRESULT SenUGCDownloadMainDataBlob(
int userIndex,
SenSysTitleID titleID,
SenUGCID ugcID,
UINT mainDataBlobIndex,
size_t bufferSize,
UINT blobVersion,
void *outBuffer,
size_t *outSize,
SenSysCompletedCallback userCallback,
void *userCallbackData );
__declspec(deprecated("Use signature with blobVersion."))
HRESULT SenUGCDownloadMainDataBlob(
int userIndex,
SenSysTitleID titleID,
SenUGCID ugcID,
int mainDataBlobIndex,
size_t bufferSize,
void *outBuffer,
size_t *outBytesReceived,
SenSysCompletedCallback userCallback,
void *userCallbackData );
//************************************
// Method: SenUGCDownloadMainDataBlob
// FullName: Sentient::SenUGCDownloadMainDataBlob
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenUGCID ugcID
// Parameter: int mainDataBlobID
// Parameter: size_t bufferSize
// Parameter: UINT blobVersion
// Parameter: void * outBuffer
// Parameter: size_t * outBytesReceived
// Parameter: SenSysCompletedCallback userCallback
// Parameter: void * userCallbackData
// Download a single blob of UGC data
// NOTE: zero byte downloads will fail.
// ID, mainDataRevision and bufferSize should be coming from a
// SenUGCDownloadedMetaData2 (where bufferSize comes from
// SenUGCDownloadedMetaData2's BlobInfo[mainDataBlobID].Size).
// outBuffer should be an preallocated array of bufferSize bytes.
// This signature includes an out param to include the progress
// percentage and cancellation token, etc to monitor and abort
// long running downloads (can be wired up to UI for users).
// BlobVersion is the version of the blob you want to download,
// which is available on the metadata information for the
// main data blobs (via DownloadMetaData).
//************************************
HRESULT SenUGCDownloadMainDataBlob(
int userIndex,
SenSysTitleID titleID,
SenUGCID ugcID,
UINT mainDataBlobIndex,
size_t bufferSize,
UINT blobVersion,
void *outBuffer,
size_t *outBytesReceived,
SenSysCompletedCallback userCallback,
void *userCallbackData,
SenUGCProgressInfo* out_progressInfo);
__declspec(deprecated("Use signature with blobVersion."))
HRESULT SenUGCDownloadMainDataBlob(
int userIndex,
SenSysTitleID titleID,
SenUGCID ugcID,
int mainDataBlobIndex,
size_t bufferSize,
void *outBuffer,
size_t *outBytesReceived,
SenSysCompletedCallback userCallback,
void *userCallbackData,
SenUGCProgressInfo* out_progressInfo);
/**********************************************
***** UGC Reviewing and Rating Functions *****
**********************************************/
//************************************
// Method: SenUGCSetReviewScore
// FullName: Sentient::SenUGCSetReviewScore
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenUGCID ugcId
// Parameter: SenUGCReviewScoreType type
// Parameter: UINT score
// Parameter: bool isFavorite
// Parameter: SenSysCompletedCallback callback
// Parameter: void * callbackData
//************************************
HRESULT SenUGCSetReviewScore(
int userIndex,
SenUGCID ugcId,
SenUGCReviewScoreType type,
unsigned int score,
bool isFavorite,
SenSysCompletedCallback callback,
void *callbackData );
//************************************
// Method: SenUGCGetReviewScore
// FullName: Sentient::SenUGCGetReviewScore
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenUGCID ugcId
// Parameter: SenUGCReviewScoreType type
// Parameter: UINT * out_score
// Parameter: SenSysCompletedCallback callback
// Parameter: void * callbackData
//************************************
HRESULT SenUGCGetReviewScore(
int userIndex,
SenUGCID ugcId,
SenUGCReviewScoreType type,
unsigned int *out_score,
SenSysCompletedCallback callback,
void *callbackData );
//************************************
// Method: SenUGCSetFavoriteFlag
// FullName: Sentient::SenUGCSetFavoriteFlag
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenSysTitleID titleID
// Parameter: SenUGCID ugcID
// Parameter: bool isFavorite
// Parameter: SenSysCompletedCallback userCallback
// Parameter: void * userCallbackData
// Users can flag the UGCs that they really like, which can be used for
// the search results
//************************************
HRESULT SenUGCSetFavoriteFlag(
int userIndex,
SenSysTitleID titleID,
SenUGCID ugcID,
BOOL isFavorite,
SenSysCompletedCallback userCallback,
void *userCallbackData );
//************************************
// Method: SenUGCGetFavoriteFlag
// FullName: Sentient::SenUGCGetFavoriteFlag
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenSysTitleID titleID
// Parameter: SenUGCID ugcID
// Parameter: BOOL * outResult
// Parameter: SenSysCompletedCallback userCallback
// Parameter: void * userCallbackData
// Users can flag the UGCs that they really like, which can be used for
// the search results
//************************************
HRESULT SenUGCGetFavoriteFlag(
int userIndex,
SenSysTitleID titleID,
SenUGCID ugcID,
BOOL *outResult,
SenSysCompletedCallback userCallback,
void *userCallbackData );
//************************************
// Method: SenUGCGetFriendFavoriteCount
// FullName: Sentient::SenUGCGetFriendFavoriteCount
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenSysTitleID titleID
// Parameter: SenUGCID ugcID
// Parameter: int * outResult
// Parameter: SenSysCompletedCallback userCallback
// Parameter: void * userCallbackData
// Find out how many friends of the user have flagged this UGC as
// a favorite (inclusive the user's favorite flag also)
//************************************
HRESULT SenUGCGetFriendFavoriteCount(
int userIndex,
SenSysTitleID titleID,
SenUGCID ugcID,
int *outResult,
SenSysCompletedCallback userCallback,
void *userCallbackData );
//************************************
// Method: SenUGCAddToCustomCounters
// FullName: Sentient::SenUGCAddToCustomCounters
// Access: public
// Returns: HRESULT
// Qualifier:
// Parameter: int userIndex
// Parameter: SenSysTitleID titleID
// Parameter: SenUGCID ugcID
// Parameter: INT64 customCounters[SenUGCDownloadedMetaData_NrCustomCounters]
// Parameter: SenSysCompletedCallback userCallback
// Parameter: void * userCallbackData
// Users can add to a fixed number of global counters stored on the
// servers, to count up a few basic stats per UGC (number of deaths,
// number of enemies killed, total playtime etc.)
//************************************
HRESULT SenUGCAddToCustomCounters(
int userIndex,
SenSysTitleID titleID,
SenUGCID ugcID,
INT64 customCounters[SenUGCDownloadedMetaData_NrCustomCounters],
SenSysCompletedCallback userCallback,
void* userCallbackData );
/// @brief API to flag a given piece of UGC as offensive.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[in] ugcID
/// The unique ID for an instance of UGC.
///
/// @param[in] offensivenessFlag
/// Offensive flag type.
///
/// @param[in] reason
/// Reason for marking a given piece of UGC as offensive.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
///
/// @details Users can flag a level that they think is offensive. The goal is that
/// the Sentient system will automatically be able to take down
/// levels after enough people have flagged a UGC as bad.
/// The number of votes to take something down will depend on the
/// reliability of the reviewers (number of offensiveness flags vs number of
/// downloads etc.) as well as the number of offensive uploads by the creator.
/// This function is also used by moderators to confirm or deny something as
/// being offensive.
///
/// @related <Related API>
HRESULT SenUGCSetOffensivenessFlag(
int userIndex,
SenUGCID ugcID,
SenUGCOffensivenessFlag offensivenessFlag,
const wchar_t *reason,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief This function will return whether or not a particular
/// piece of UGC has been banned.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[in] The unique ID for UGC.
///
/// @param[in] True if content is banned (and should not be viewed by user).
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
///
/// @details Any piece of UGC can been banned by a moderator or
/// moderation engine. This API allows clients to verify
/// if a given piece of UGC has been banned.
///
/// @related SenUGCCreatePublishingUGCID()
/// @related SenUGCSetOffensivenessFlag()
/// @related SenUGCPublish()
HRESULT SenUGCIsBanned(
int userIndex,
SenUGCID ugcID,
BOOL *out_result,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/*********************
***** UGC Feeds *****
*********************/
/// @brief UGC Feed information
///
/// @details When enumerating feeds, these are the available feeds that can be retrieved.
///
struct SenUGCFeedInfo
{
SenUGCFeedType feedType;
wchar_t Name[32];
wchar_t Description[128];
};
/// @brief Retrieves a specific feed based on feedtype.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///`
/// @param[in] titleID
///
/// @param[in] feedType
/// Feed Type identifier for for the given feed being retrieved.
///
/// @param[in] maxNumberOfFeedItems
/// Used to indicate the number of items to be returned by @a out_feedInfo.
/// If the actual number of items exceeds this, you will receive an error.
///
/// @param[out] out_buffer
/// Pointer to the collection of structures to fill with SenUGCFeedItem data.
///
/// @param[out] out_buffersize
/// The number of entries actually enumerated by the call.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
/// E_POINTER: out_buffer or out_buffersize are null.
///
/// @details <Insert detailed method documentation>
///
/// @related SenUGCEnumerateFeeds()
HRESULT SenUGCGetFeed(
int userIndex,
SenSysTitleID titleID,
SenUGCFeedType feedType,
size_t maxNumberOfFeedItems,
SenUGCFeedItem *out_buffer,
UINT *out_buffersize,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief Retrieves a collection of feeds that are viewable by the
/// current user.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[in] culture
/// This is the result of a call to SenCultureFind() or SenCultureGet*().
/// You may also pass NULL to use the culture set with SenCultureSetCurrent().
/// May be NULL for default culture.
///
/// @param[in] maxResults
/// Used to indicate the number of items to be returned by @a out_feedInfo.
/// If the actual number of items exceeds this, you will receive an error.
///
/// @param[out] out_feedInfo
/// Pointer to a collection of structures to fill with SenUGCFeedInfo data.
///
/// @param[out] out_resultCount
/// The number of entries actually enumerated by the call.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
/// E_POINTER: out_feedInfo or out_resultCount are null.
///
/// @details <Insert detailed method documentation>
///
/// @related SenUGCGetFeed()
HRESULT SenUGCEnumerateFeeds(
int userIndex,
size_t maxResults,
SenUGCFeedInfo *out_feedInfo,
size_t *out_resultCount,
SenSysCompletedCallback userCallback,
void *userCallbackData);
/// @brief API that publishes UGC and makes the content accessible
/// to everyone on the Sentient service.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[in] ugcID
/// The unique ID for an instance of UGC.
///
/// @param[in] leaderboardDefinition
/// Optional parameter. Definition for a Leaderboard that
/// will be created and associated to newly published UGC.
///
/// @param[out] out_leaderboardId
/// Created Leaderboard Id. Only returned to the client if
/// a Leaderboards Definition is passed to the server.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
///
/// @details UGC is only accessible to the author until it has been published.
/// The user making the call must be the author of the UGC item.
/// The call will fail if this UGC item has previously been published.
/// By supplying an optional Leaderboard definition a Leaderboard is automatically
// allocated and associated with the UGC item.
/// This is the preferred way of creating UGC Leaderboards.
///
/// @related SenCreateLeaderboard()
HRESULT SenUGCPublish(
int userIndex,
SenUGCID ugcID,
const SenLeaderboardDefinition *leaderboardDefinition,
SenLeaderboardId *out_leaderboardId,
SenSysCompletedCallback userCallback,
void *userCallbackData);
/// @brief API that publishes a new version of a UGC item and makes the revised content accessible
/// to everyone on the Sentient service.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[in] ugcID
/// The unique ID for an instance of UGC.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
///
/// @details New versions of UGC are only accessible to the author until it has been republished.
/// The user making the call must be the author of the UGC item.
///
/// @related SenUGCPublish()
HRESULT SenUGCRepublish(
int userIndex,
SenUGCID ugcID,
SenSysCompletedCallback userCallback,
void* userCallbackData);
} // namespace Sentient

View File

@@ -0,0 +1,397 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client UGC Leaderboard API
//
// Include this to get access to all UGC Leaderboard features
#pragma once
#include "SenClientUGCTypes.h"
#include "SenClientSys.h"
namespace Sentient
{
// This system does not rely on existing XBox Leaderboards, but runs completely in parallel.
/********************************************
***** Leaderboard Creation Functions *****
********************************************/
/// @brief Creates a dynamic Leaderboard based on a given definition.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[in] definition
/// Leaderboard definition that describes the behavior for the to be created Leaderboard.
///
/// @param[in] metadataBlob
/// Binary metadata blob that is associated to the created Leaderboard.
/// Can be used to store information about the Leaderboard being created.
/// This information can be re-uploaded at any time.
///
/// @param[in] metadataBlobSize
/// Used to indelicate the size of the buffer pointed to by @a metadataBlob.
///
/// @param[out] out_leaderboardId
/// The Leaderboard Id that has been created by the service.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
///
/// @details Creates a new Leaderboard based on the supplied Leaderboard Definition.
///
/// @related SenCreateLeaderboard()
HRESULT SenCreateLeaderboard(
int userIndex,
const SenLeaderboardDefinition &definition,
const void *metadataBlob,
size_t metadataBlobSize,
SenLeaderboardId *out_leaderboardId,
SenSysCompletedCallback callback,
void *callbackData );
/********************************************
***** Leaderboard Set Score Functions *****
********************************************/
/// @brief Set a specific Leaderboard entry value.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[in] leaderboardId
/// Leaderboard Id to set a value on.
///
/// @param[in] value
/// Value of the Leaderboard entry.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
///
/// @details The Leaderboard entry value will be set for the given Leaderboard.
/// The actor or owner of the value will be the XUID of user
/// logged in at the specified index.
///
/// @related SenSetUserLeaderboardValue()
__declspec(deprecated("This function is deprecated, and should not be used"))
HRESULT SenSetUserLeaderboardValue(
int userIndex,
SenLeaderboardId leaderboardId,
SenLeaderboardEntryValue value,
SenSysCompletedCallback callback,
void *callbackData );
HRESULT SenSetUserLeaderboardValue(
int userIndex,
SenLeaderboardId leaderboardId,
SenLeaderboardEntryValue value,
LONGLONG descriptor,
SenSysCompletedCallback callback,
void *callbackData );
/// @brief Set a specific Leaderboard entry value and metadata.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[in] leaderboardId
/// Leaderboard Id to set a value on.
///
/// @param[in] value
/// Value of the Leaderboard entry.
///
/// @param[in] metadataBlob
/// Binary metadata blob that is associated to the created Leaderboard Entry.
/// Can be used to store information about the Leaderboard Entry being created.
/// This information can be re-uploaded at any time.
///
/// @param[in] metadataBlobSize
/// Used to indicate the size of the buffer pointed to by @a metadataBlob.
/// If the actual size of the data exceeds this, you will receive an error.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
///
/// @details The Leaderboard entry value will be set for the given Leaderboard.
/// The actor or owner of the value will be the XUID of user
/// logged in at the specified index.
///
/// @related SenSetUserLeaderboardValue()
__declspec(deprecated("This function is deprecated, and should not be used"))
HRESULT SenSetUserLeaderboardValue(
int userIndex,
SenLeaderboardId leaderboardId,
SenLeaderboardEntryValue value,
const void *metadataBlob,
size_t metadataBlobSize,
SenSysCompletedCallback callback,
void *callbackData );
HRESULT SenSetUserLeaderboardValue(
int userIndex,
SenLeaderboardId leaderboardId,
SenLeaderboardEntryValue value,
LONGLONG descriptor,
const void *metadataBlob,
size_t metadataBlobSize,
SenSysCompletedCallback callback,
void *callbackData );
/********************************************
***** Leaderboard Retrieval Functions *****
********************************************/
/*For documentation: the output structure contains a pointer to a buffer that is allocated by Sentient (specifically the transport layer). The pointer is only valid during the callback. If title developers want to hold on to the metadata they'll need to copy the data into a buffer of their own before execution leaves the completion callback.
It's definitely an ugly pattern which is why we strongly prefer to avoid it (and use title-allocated buffers), but I don't see a way round it in this case.*/
/// @brief Retrieves a single Leaderboard Entry.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[in] leaderboardId
/// Leaderboard Id where the entry being retrieved is stored.
///
/// @param[in] leaderboardFlag
/// Flag for determining how Leaderboard specific Metadata should be retrieved.
///
/// @param[in] entryFlag
/// Flag for determining how Leaderboard Entry specific Metadata should be retrieved.
///
/// @param[out] out_leaderboardEntry
/// Leaderboard Entry being retrieved.
///
/// @param[in] maxLeaderboardMetadataBlobSize
/// Used to indicate the size of the buffer pointed to by @a out_leaderboardMetadataBlob.
/// If the actual size of the data exceeds this, you will receive an error.
///
/// @param[out] out_leaderboardMetadataBlob
/// Metadata buffer associated to the Leaderboard.
///
/// @param[out] out_leaderboardMetadataBlobSize
/// Used to return the actual size of the Leaderboard Metadata being returned.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
///
/// @details Retrieves a single Leaderboard Entry.
/// The actor or owner of the value will be the XUID of user
/// logged in at the specified index.
///
/// @related SenGetLeaderboardEntry()
HRESULT SenGetLeaderboardEntry(
int userIndex,
SenLeaderboardId leaderboardId,
SenLeaderboardMetadataFlag leaderboardFlag,
SenLeaderboardMetadataFlag entryFlag,
SenLeaderboardEntry *out_leaderboardEntry,
size_t maxLeaderboardMetadataBlobSize, // LB
void *out_leaderboardMetadataBlob, // LB
size_t *out_leaderboardMetadataBlobSize, // LB
SenSysCompletedCallback callback,
void *callbackData );
/// @brief Retrieves a single Leaderboard Entry for any given actor (XUID).
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[in] actorId
/// Actor Id for the Leaderboard Entry being retrieved.
///
/// @param[in] leaderboardId
/// Leaderboard Id where the entry being retrieved is stored.
///
/// @param[in] leaderboardFlag
/// Flag for determining how Leaderboard specific Metadata should be retrieved.
///
/// @param[in] entryFlag
/// Flag for determining how Leaderboard Entry specific Metadata should be retrieved.
///
/// @param[out] out_leaderboardEntry
/// Leaderboard Entry being retrieved.
///
/// @param[in] maxLeaderboardMetadataBlobSize
/// Used to indicate the size of the buffer pointed to by @a out_leaderboardMetadataBlob.
/// If the actual size of the data exceeds this, you will receive an error.
///
/// @param[out] out_leaderboardMetadataBlob
/// Metadata buffer associated to the Leaderboard.
///
/// @param[out] out_leaderboardMetadataBlobSize
/// Used to return the actual size of the Leaderboard Metadata being returned.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
///
/// @details Retrieves a single Leaderboard Entry for a given actor.
///
/// @related SenGetLeaderboardEntry()
HRESULT SenGetLeaderboardEntry(
int userIndex,
SenLeaderboardActorId actorId,
SenLeaderboardId leaderboardId,
SenLeaderboardMetadataFlag leaderboardFlag,
SenLeaderboardMetadataFlag entryFlag,
SenLeaderboardEntry *out_leaderboardEntry,
size_t maxLeaderboardMetadataBlobSize, // LB
void *out_leaderboardMetadataBlob, // LB
size_t *out_leaderboardMetadataBlobSize, // LB
SenSysCompletedCallback callback,
void *callbackData );
/// @brief Retrieve a specific Leaderboard that is ranked by Xbox Live Friends.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[in] leaderboardId
/// Leaderboard Id where the entry being retrieved is stored.
///
/// @param[in] leaderboardFlag
/// Flag for determining how Leaderboard specific Metadata should be retrieved.
///
/// @param[in] entryFlag
/// Flag for determining how Leaderboard Entry specific Metadata should be retrieved.
///
/// @param[in] maxLeaderboardEntries
/// Used to indicate the number of Leaderboard Entries to be returned by @a out_leaderboardEntries.
/// If the actual number of items exceeds this, you will receive an error.
///
/// @param[out] out_leaderboardEntries
/// Collection of Leaderboard Entries being retrieved.
///
/// @param[out] out_leaderboardEntriesSize
/// Actual size of the returned Leaderboard Entry collection.
///
/// @param[in] maxLeaderboardMetadataBlobSize
/// Used to indicate the size of the buffer pointed to by @a out_leaderboardMetadataBlob.
/// If the actual size of the data exceeds this, you will receive an error.
///
/// @param[out] out_leaderboardMetadataBlob
/// Metadata buffer associated to the Leaderboard.
///
/// @param[out] out_leaderboardMetadataBlobSize
/// Used to return the actual size of the Leaderboard Metadata being returned.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
///
/// @details Returns a ranked Leaderboard.
HRESULT SenGetLeaderboardFriends(
int userIndex,
SenLeaderboardId leaderboardId,
SenLeaderboardMetadataFlag leaderboardFlag,
SenLeaderboardMetadataFlag entryFlag,
size_t maxLeaderboardEntries,
SenLeaderboardEntry *out_leaderboardEntries,
size_t *out_leaderboardEntriesSize,
size_t maxLeaderboardMetadataBlobSize, // LB
void *out_leaderboardMetadataBlob, // LB
size_t *out_leaderboardMetadataBlobSize, // LB
SenSysCompletedCallback callback,
void *callbackData );
/// @brief Retrieve a specific Leaderboard that is ranked by the top Leaderboard Entries.
///
/// @param[in] userIndex
/// The index of the initiating user on the console.
/// Note: This is NOT a XUID.
///
/// @param[in] leaderboardId
/// Leaderboard Id where the entry being retrieved is stored.
///
/// @param[in] maxLeaderboardEntries
/// Used to indicate the number of Leaderboard Entries to be returned by @a out_leaderboardEntries.
/// If the actual number of items exceeds this, you will receive an error.
///
/// @param[out] out_leaderboardEntries
/// Collection of Leaderboard Entries being retrieved.
///
/// @param[out] out_leaderboardEntriesSize
/// Actual size of the returned Leaderboard Entry collection.
///
/// @param[in] userCallback
/// If this call returns a success code,
/// the userCallback will be called at the end of the
/// asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success.
/// Specific values include:
///
/// @details Returns a ranked Leaderboard of all the top Leaderboard Entries.
HRESULT SenGetLeaderboardTop(
int userIndex,
SenLeaderboardId leaderboardId,
size_t maxLeaderboardEntries,
SenLeaderboardEntry *out_leaderboardEntries,
size_t *out_leaderboardEntriesSize,
SenSysCompletedCallback callback,
void *callbackData );
} // namespace Sentient

View File

@@ -0,0 +1,259 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client UGC Types
//
// Include this to get access to all Sentient UGC Types.
#pragma once
#include "SenClientTypes.h"
namespace Sentient
{
//****** UGC Creation
typedef int SenUGCFeedID;
enum SenUGCPublishState
{
SenUGCPublishState_Deleted = 0x00,
SenUGCPublishState_Banned = 0x01,
SenUGCPublishState_Unpublished = 0x10,
SenUGCPublishState_Published = 0x30,
SenUGCPublishState_PendingModeratorReview = 0x31
};
enum SenUGCType
{
SenUGCType_Movie = 0,
SenUGCType_Audio,
SenUGCType_Image,
SenUGCType_FirstCustom = 0x20
};
enum SenUGCDescriptor
{
SenUGCDescriptor_Illegal = 0xffff,
SenUGCDescriptor_None = 0x0000,
SenUGCDescriptor_FirstCustom = 0x0100,
};
typedef unsigned int SenUGCMetaDataFlags;
enum
{
SenUGCMetaDataFlags_NoFlags = 0x00000000,
SenUGCMetaDataFlags_FriendsCanEdit = 0x00000001,
SenUGCMetaDataFlags_EveryoneCanEdit = 0x00000002,
SenUGCMetaDataFlags_Reserved1 = 0x00000004,
SenUGCMetaDataFlags_Reserved2 = 0x00000008,
SenUGCMetaDataFlags_Reserved3 = 0x00000010,
SenUGCMetaDataFlags_Reserved4 = 0x00000020,
SenUGCMetaDataFlags_Reserved5 = 0x00000040,
SenUGCMetaDataFlags_Reserved6 = 0x00000080,
SenUGCMetaDataFlags_FirstCustom = 0X00000100
};
typedef ULONGLONG SenLeaderboardId;
struct SenUGCMetaData
{
SenUGCMetaData()
{
#pragma warning ( disable : 4996 ) // @TODO - Removed once Int16 Descriptors are deprecated
memset(descriptors, 0, sizeof(SenUGCDescriptor) * NrUgcDescriptors);
#pragma warning ( default : 4996 )
memset(descriptors2, 0, sizeof(__int64) * NrUgcDescriptors);
}
SenUGCID parentID;
SenUGCType type;
SenUGCMetaDataFlags flags;
static const int NameLength = 64;
wchar_t name[NameLength];
static const int ShortNameLength = 12;
wchar_t shortName[ShortNameLength];
static const int NrUgcDescriptors = 4;
__declspec(deprecated("Descriptors have increased in size (from Int16 to Int64). Please Use descriptors2 instead"))
SenUGCDescriptor descriptors[NrUgcDescriptors];
__int64 descriptors2[NrUgcDescriptors];
static const int BlobSizeLimit = 1024;
size_t metaDataBlobSize;
void* metaDataBlob;
};
const int SenUGCMainData_NrBlobs = 4;
struct SenUGCSearchResult
{
PlayerUID author;
SenUGCID ID;
int revision;
};
#define SenUGCDownloadedMetaData_NrCustomCounters 4
// This structure contains the original uploaded metadata plus any stats gathered from the UGC server
struct SenUGCDownloadedMetaData
{
PlayerUID author;
SenUGCMetaData base;
SenUGCID ID;
SYSTEMTIME authorTime;
int revision;
SenUGCPublishState publishState;
int averageReviewScore;
int nrReviews;
int nrFavoriteFlags;
INT64 customCounters[SenUGCDownloadedMetaData_NrCustomCounters];
int nrDownloads; //automatically counts how many times MainDataBlob 0 has been downloaded
size_t mainDataSizes[SenUGCMainData_NrBlobs];
SenLeaderboardId leaderboardId;
};
struct SenUGCBlobMetaData
{
size_t Size;
UINT Version;
};
struct SenUGCStatsMetaData
{
UINT AverageReviewScore;
UINT NumberOfReviews;
UINT NumberOfFavorites; // number of times tagged as a favorite item
UINT NumDownloads; // how many times any blob has been downloaded
SenLeaderboardId LeaderboardId;
INT64 CustomCounters[SenUGCDownloadedMetaData_NrCustomCounters];
};
// Matches with documentation and internal server-side value
#define MainDataBlobSizeLimit 16777216
// Version specifically to support Resubmission feature
struct SenUGCDownloadedMetaData2
{
SenUGCID UgcId;
PlayerUID AuthorXuid;
SenUGCMetaData MetaData;
SYSTEMTIME CreationDate; // first time it's created
SYSTEMTIME ModifiedDate; // any modification, metadata included
SYSTEMTIME PublishedDate; // anytime it's published/republished
SenUGCPublishState PublishState;
UINT Revision;
SenUGCBlobMetaData BlobInfo[SenUGCMainData_NrBlobs]; // size and version of each blob, 0's if not present
SenUGCStatsMetaData StatsInfo; // stats of ugc item: counters, aggregates, etc
};
enum SenUGCSortBy
{
SenUGCSortBy_CreationDate,
SenUGCSortBy_TopFavorites,
SenUGCSortBy_TopReviewScoreAverage,
SenUGCSortBy_TopDownloadsTotal
};
enum SenUGCAuthorType
{
SenUGCAuthorType_Everyone,
SenUGCAuthorType_LocalUsers,
SenUGCAuthorType_Friends,
SenUGCAuthorType_List
};
enum SenUGCOffensivenessFlag
{
SenUGCOffensivenessFlag_None = 0x00000000,
SenUGCOffensivenessFlag_Discriminating = 0x00000001,
SenUGCOffensivenessFlag_Explicit = 0x00000002,
SenUGCOffensivenessFlag_Obscene = 0x00000004,
SenUGCOffensivenessFlag_FoulLanguage = 0x00000008,
SenUGCOffensivenessFlag_LicenseInfringement = 0x00000010,
SenUGCOffensivenessFlag_IllegalAdvertising = 0x00000020,
SenUGCOffensivenessFlag_Illegal = 0x00000040,
};
struct SenUGCFeedItem
{
PlayerUID Author;
SenUGCID UgcId;
SYSTEMTIME DateCreated;
};
enum SenUGCFeedType
{
SenUGCFeedType_Unknown = 0x00,
SenUGCFeedType_NewestItems = 0x10,
SenUGCFeedType_TopReviewed = 0x20,
SenUGCFeedType_TopDownloaded = 0x30,
SenUGCFeedType_PendingModeratorReview = 0x60,
SenUGCFeedType_Custom = 0x90
};
enum SenUGCReviewScoreType
{
SenUGCReviewScoreType_Quality = 0x00,
SenUGCReviewScoreType_Difficulty = 0x10
};
// ***** Leaderboard types
typedef __int64 SenLeaderboardEntryValue;
typedef ULONGLONG SenLeaderboardActorId;
enum SenLeaderboardSortType
{
SenLeaderboardSortType_Ascending = 0x00,
SenLeaderboardSortType_Descending = 0x10
};
/// @brief Leaderboard Metadata retrieval flag.
///
/// @details When retrieving Leaderboard information, a client can choose
/// to bypass retrieval or retrieve specific details regarding the
/// Metadata stored for a given Leaderboard or Leaderboard Entry.
///
enum SenLeaderboardMetadataFlag
{
// Bypass the retrieval of metadata blob size and binary data
SenLeaderboardmetadataFlag_BypassRetrieval = 0x00000000,
// Retrieve and populate the size of each metadata blob
SenLeaderboardmetadataFlag_RetrieveSizeOnly = 0x00000001,
// Retrieve and populate both the size and metadata blob binary data
SenLeaderboardmetadataFlag_RetrieveData = 0x00000002,
};
struct SenLeaderboardDefinition
{
static const int NameLength = 50;
WCHAR Name[NameLength];
SenLeaderboardSortType SortType;
};
struct SenLeaderboardEntry
{
SenLeaderboardActorId ActorId;
SenLeaderboardEntryValue Value;
LONGLONG Descriptor;
unsigned int Rank;
size_t metaDataBlobSize;
size_t reserved_metaDataBlobCount;
void *metaDataBlob;
};
} // namespace Sentient

View File

@@ -0,0 +1,104 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client User API
//
// Include this to get access to all user-related Sentient features.
#pragma once
#include "SenClientSys.h"
namespace Sentient
{
//======================//
// //
// User Data Types //
// //
//======================//
/// @brief Roles a user can have in Sentient
///
/// @details Roles are not necessarily mutually exclusive.
/// A single user may be in multiple roles simultaneously.
///
enum SenUserRole
{
/// The user is a UGC moderator.
SenUserRole_UGC_Moderator,
/// The user has been banned from UGC participation.
SenUserRole_UGC_Banned,
};
//======================//
// //
// User Functions //
// //
//======================//
/// @brief Ask Sentient whether a user belongs to the enumerated roles
///
/// @param[in] userIndex
/// Local index [0-3] of the user whose role is being checked
///
/// @param[in] role
/// Role to check
///
/// @param[out] out_isInRole
/// Location to store the output role membership state
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_POINTER: out_isInRole is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
HRESULT SenUserIsInRole(
int userIndex,
SenUserRole role,
bool *out_isInRole,
SenSysCompletedCallback userCallback,
void *userCallbackData );
/// @brief Ask Sentient whether a user belongs to the enumerated roles
///
/// @param[in] xuid
/// XUID of user whose role is being checked
///
/// @param[in] role
/// Role to check
///
/// @param[out] out_isInRole
/// Location to store the output role membership state
///
/// @param[in] userCallback
/// If this call returns a success code, the userCallback will be called at the end of the asynchronous process.
///
/// @param[in] userCallbackData
/// Data to be passed to the @a userCallback on completion.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// SENTIENT_E_NOT_INITIALIZED: You did not call SentientInitialize() first.
/// E_POINTER: out_isInRole is NULL.
/// E_FAIL: Failed to spawn server call.
/// S_OK: Server call spawned successfully.
///
HRESULT SenUserIsInRole(
PlayerUID xuid,
SenUserRole role,
bool *out_isInRole,
SenSysCompletedCallback userCallback,
void *userCallbackData );
}

View File

@@ -0,0 +1,50 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client Utility API
//
// Include this to get access to all Utility-related Sentient features.
#pragma once
#include "SenClientTypes.h"
namespace Sentient
{
/*************************
***** Utility Types *****
*************************/
// This function should return the width (in pixels) of a single
// character, and is used to check how many characters can fit on a
// single line of the screen
typedef unsigned int (*SenUtilGetCharacterWidthCallback)( wchar_t character );
/*****************************
***** Utility Functions *****
*****************************/
// This function takes a multi-line text string, a width (in pixels) that
// a text line can be, and a callback to measure the width of each character.
// It will return the end of the current text line, and the beginning of
// the next text line. Use the beginning of the next text line as input next
// time you call SenUtilWordWrapFindNextLine()
void SenUtilWordWrapFindNextLine(
const wchar_t *startOfThisLine,
unsigned int maxWidth,
SenUtilGetCharacterWidthCallback characterWidthCallback,
const wchar_t **out_endOfThisLine,
const wchar_t **out_beginningOfNextLine );
// This returns a SYSTEMTIME set to its earliest possible value.
SYSTEMTIME SenUtilDateTimeMin();
// This returns a SYSTEMTIME set to its latest possible value.
SYSTEMTIME SenUtilDateTimeMax();
} // namespace Sentient

View File

@@ -0,0 +1,85 @@
/********************************************************
* *
* Copyright (C) Microsoft. All rights reserved. *
* *
********************************************************/
// Sentient Client XML API
//
// Include this to get access to all XML Sentient features.
#pragma once
#include "SenClientTypes.h"
namespace Sentient
{
//======================//
// //
// XML Data Types //
// //
//======================//
/// @brief An easy-to-access pre-parsed XML.
///
/// @details This holds some easily-traversible, easily-searchible representations
/// of the content of a raw UTF-8 XML buffer.
///
/// @related SenXMLParse()
/// @related SenXMLDestroy()
///
struct SenXML
{
void *reserved;
};
//=====================//
// //
// XML Functions //
// //
//=====================//
/// @brief Parse a raw UTF-8 XML buffer into a more useful format.
///
/// @param[in] source
/// The raw UTF-8 XML buffer to be parsed.
///
/// @param[out] out_senXML
/// The (private) object to hold the parsed data.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// E_POINTER: Bad pointer to the raw XML buffer.
/// E_OUTOFMEMORY: Couldn't parse due to lack of memory.
/// E_FAIL: Failed to parse for unspecified reason.
/// S_OK: Parsed successfully.
///
/// @details It is expensive to parse an XML file directly for each attribute fetch.
/// Thus, we pre-parse the whole thing once after (down)loading it and then
/// pass the parsed data to the fetch routines.
///
/// @related SenXMLDestroy()
///
HRESULT SenXMLParse(
const char *source,
SenXML *out_senXML );
/// @brief Free the resources/memory associated with a parsed XML file.
///
/// @param[in] senXML
/// The (private) object holding the parsed data to be freed.
///
/// @return Check SUCCEEDED( hresult ) or FAILED( hresult ) to determine success. Specific values include:
/// E_INVALIDARG: senXML is not a parsed XML.
/// S_OK: Destroyed/freed successfully.
///
/// @details A parsed XML takes up some extra memory. Once done with its contents,
/// you should call this routine to free it up.
///
/// @related SenXMLParse()
///
HRESULT SenXMLDestroy(
SenXML &senXML );
} // namespace Sentient

View File

@@ -0,0 +1,3 @@
#include "SentientTelemetryCommon.h"
#include "TelemetryEnum.h"
#include "SentientStats.h"

View File

@@ -0,0 +1,282 @@
<?xml version="1.0" encoding="utf-8"?>
<SentientStats>
<Stat name="PlayerSessionStart" desc="Player signed in or joined" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="TitleBuildID" type="int" op="none" />
<Param name="SkeletonDistanceInInches" type="int" op="none" />
<Param name="EnrollmentType" type="int" op="none" />
<Param name="NumberOfSkeletonsInView" type="int" op="none" />
<Param name="DeploymentType" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="PlayerSessionExit" desc="Player signed out or left" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="HeartBeat" desc="Sent every 60 seconds by title" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="LevelStart" desc="Level started" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
<Param name="SingleOrMultiplayer" type="int" op="none" />
<Param name="FriendsOrMatch" type="int" op="none" />
<Param name="CompeteOrCoop" type="int" op="none" />
<Param name="DifficultyLevel" type="int" op="none" />
<Param name="NumberOfLocalPlayers" type="int" op="none" />
<Param name="NumberOfOnlinePlayers" type="int" op="none" />
<Param name="License" type="int" op="none" />
<Param name="DefaultGameControls" type="int" op="none" />
<Param name="AudioSettings" type="int" op="none" />
<Param name="SkeletonDistanceInInches" type="int" op="none" />
<Param name="NumberOfSkeletonsInView" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="LevelExit" desc="Level exited" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
<Param name="LevelExitStatus" type="int" op="none" />
<Param name="LevelExitProgressStat1" type="int" op="none" />
<Param name="LevelExitProgressStat2" type="int" op="none" />
<Param name="LevelDurationInSeconds" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="LevelSaveOrCheckpoint" desc="Level saved explicitly or implicitly" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
<Param name="LevelExitProgressStat1" type="int" op="none" />
<Param name="LevelExitProgressStat2" type="int" op="none" />
<Param name="LevelDurationInSeconds" type="int" op="none" />
<Param name="SaveOrCheckPointID" type="int" op="none" />
<Param name="SaveSizeInBytes" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="LevelResume" desc="Level resumed from a save or restarted at a checkpoint" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
<Param name="SingleOrMultiplayer" type="int" op="none" />
<Param name="FriendsOrMatch" type="int" op="none" />
<Param name="CompeteOrCoop" type="int" op="none" />
<Param name="DifficultyLevel" type="int" op="none" />
<Param name="NumberOfLocalPlayers" type="int" op="none" />
<Param name="NumberOfOnlinePlayers" type="int" op="none" />
<Param name="License" type="int" op="none" />
<Param name="DefaultGameControls" type="int" op="none" />
<Param name="SaveOrCheckPointID" type="int" op="none" />
<Param name="AudioSettings" type="int" op="none" />
<Param name="SkeletonDistanceInInches" type="int" op="none" />
<Param name="NumberOfSkeletonsInView" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="PauseOrInactive" desc="Player paused game or has become inactive, level and mode are for what the player is leaving" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="UnpauseOrActive" desc="Player unpaused game or has become active, level and mode are for what the player is entering into" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="MenuShown" desc="A menu screen or major menu area has been shown" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="MenuID" type="int" op="none" />
<Param name="OptionalMenuSubID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="AchievementUnlocked" desc="An achievement was unlocked" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
<Param name="AchievementID" type="int" op="none" />
<Param name="AchievementGamerscore" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="MediaShareUpload" desc="The user uploaded something to Kinect Share" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
<Param name="MediaDestination" type="int" op="none" />
<Param name="MediaType" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="UpsellPresented" desc="The user is shown an upsell to purchase something" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
<Param name="UpsellID" type="int" op="none" />
<Param name="MarketplaceOfferID" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="UpsellResponded" desc="The user responded to the upsell" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
<Param name="UpsellID" type="int" op="none" />
<Param name="MarketplaceOfferID" type="int" op="none" />
<Param name="UpsellOutcome" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="PlayerDiedOrFailed" desc="The player died or failed a challenge - can be used for many types of failure" type="event">
<Parameters>
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
<Param name="LowResMapX" type="int" op="none" />
<Param name="LowResMapY" type="int" op="none" />
<Param name="LowResMapZ" type="int" op="none" />
<Param name="MapID" type="int" op="none" />
<Param name="PlayerWeaponID" type="int" op="none" />
<Param name="EnemyWeaponID" type="int" op="none" />
<Param name="EnemyTypeID" type="int" op="none" />
<Param name="SecondsSinceInitialize" type="int" op="min" />
<Param name="CopyOfSecondsSinceInitialize" type="int" op="max" />
<Param name="Count" type="int" op="increment" />
</Parameters>
</Stat>
<Stat name="EnemyKilledOrOvercome" desc="The player killed an enemy or overcame or solved a major challenge" type="event">
<Parameters>
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
<Param name="LowResMapX" type="int" op="none" />
<Param name="LowResMapY" type="int" op="none" />
<Param name="LowResMapZ" type="int" op="none" />
<Param name="MapID" type="int" op="none" />
<Param name="PlayerWeaponID" type="int" op="none" />
<Param name="EnemyWeaponID" type="int" op="none" />
<Param name="EnemyTypeID" type="int" op="none" />
<Param name="SecondsSinceInitialize" type="int" op="min" />
<Param name="CopyOfSecondsSinceInitialize" type="int" op="max" />
<Param name="Count" type="int" op="increment" />
</Parameters>
</Stat>
<Stat name="SkinChanged" desc="The player has changed their skin, level and mode are for what the player is currently in" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
<Param name="SkinID" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="BanLevel" desc="The player has banned a level, level and mode are for what the player is currently in and banning" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="UnBanLevel" desc="The player has unbanned a level, level and mode are for what the player is currently in and unbanning" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
</Parameters>
</Stat>
<Stat name="TexturePackChanged" desc="The player has changed their texture pack, level and mode are for what the player is currently in" type="event">
<Parameters>
<Param name="SecondsSinceInitialize" type="int" op="none" />
<Param name="ModeID" type="int" op="none" />
<Param name="OptionalSubModeID" type="int" op="none" />
<Param name="LevelID" type="int" op="none" />
<Param name="OptionalSubLevelID" type="int" op="none" />
<Param name="LevelInstanceID" type="int" op="none" />
<Param name="MultiplayerInstanceID" type="int" op="none" />
<Param name="TexturePackId" type="int" op="none" />
<Param name="Purchased" type="int" op="none" />
</Parameters>
</Stat>
</SentientStats>

View File

@@ -0,0 +1,22 @@
------------------------------------------------------------------------
Microsoft Sentient Readme File
January 2012
<20> 2012 Microsoft Corporation. All rights reserved.
------------------------------------------------------------------------
This document provides information on the January Sentient update.
-------------------------------------------------
CONTENTs: WHAT'S NEW AND UPDATED IN THIS RELEASE
-------------------------------------------------
SUMMARY
The December Sentient SDK QFE (2983.1) adds December 2011 XDK support to the December Sentient SDK (2983).
Version header was added (SenClientVersion.h) to allow developers to understand which version they are using.
See below for December SDK notes.
SUMMARY
The January Sentient SDK has no changes to the API.

View File

@@ -0,0 +1,539 @@
#include "stdafx.h"
#include "Include\SenClientCore.h"
#include "Include\SenClientMain.h"
#include "Include\SenClientMain.h"
#include "..\GameConfig\Minecraft.spa.h"
#include "..\..\Minecraft.h"
#include "..\..\MultiplayerLocalPlayer.h"
#include "..\..\..\Minecraft.World\Dimension.h"
#include "..\..\..\Minecraft.World\net.minecraft.world.level.h"
#include "..\..\..\Minecraft.World\net.minecraft.world.level.storage.h"
#include "SentientManager.h"
#include "MinecraftTelemetry.h"
#include "DynamicConfigurations.h"
// Global instance
CTelemetryManager *TelemetryManager = new CSentientManager();
HRESULT CSentientManager::Init()
{
Sentient::SenSysTitleID sentitleID;
sentitleID = (Sentient::SenSysTitleID)TITLEID_MINECRAFT;
HRESULT hr = SentientInitialize( sentitleID );
m_lastHeartbeat = m_initialiseTime;
m_bFirstFlush = true;
return hr;
}
HRESULT CSentientManager::Tick()
{
HRESULT hr = S_OK;
// Update Sentient System
HRESULT sentientResult = Sentient::SentientUpdate();
switch(sentientResult)
{
case S_OK:
{
// Sentient is connected
//OutputDebugString ("\nSentient: CONNECTED\n");
if(g_NetworkManager.IsInSession())
{
float currentTime = app.getAppTime();
if(currentTime - m_lastHeartbeat > 60)
{
m_lastHeartbeat = currentTime;
for(DWORD i = 0; i < XUSER_MAX_COUNT; ++i)
{
if(Minecraft::GetInstance()->localplayers[i] != NULL)
{
SenStatHeartBeat(i, m_lastHeartbeat - m_initialiseTime);
}
}
}
if(m_bFirstFlush)
{
for(DWORD i = 0; i < XUSER_MAX_COUNT; ++i)
{
if(Minecraft::GetInstance()->localplayers[i] != NULL && m_fLevelStartTime[i] - currentTime > 60)
{
Flush();
}
}
}
}
MinecraftDynamicConfigurations::Tick();
}
break;
case Sentient::SENTIENT_S_NOT_SIGNED_IN_TO_LIVE:
{
// Login required
//DebugPrintf("\nSentient: WARNING: an Xbox LIVE-enabled user needs to be logged in.\n");
// Add title specific code here. . .
}
break;
case Sentient::SENTIENT_S_INITIALIZING_CONNECTION:
{
// Server connection in progress
app.DebugPrintf("Sentient: Establishing connection to sentient server.\n");
// Add title specific code here. . .
}
break;
case Sentient::SENTIENT_S_SERVER_CONNECTION_FAILED:
{
// Server connection failed
app.DebugPrintf("\nSentient: WARNING: connection to sentient server failed.\n");
// Add title specific code here. . .
}
break;
default:
{
// Unknown failure
app.DebugPrintf("Sentient: Unknown result from SentientUpdate()");
// Add title specific code here. . .
}
break;
}
return hr;
}
HRESULT CSentientManager::Flush()
{
m_bFirstFlush = false;
return Sentient::SentientFlushStats();
}
BOOL CSentientManager::RecordPlayerSessionStart(DWORD dwUserId)
{
return SenStatPlayerSessionStart( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetTitleBuildId(), 0, 0, 0, (INT)app.getDeploymentType() );
}
BOOL CSentientManager::RecordPlayerSessionExit(DWORD dwUserId, int _)
{
return SenStatPlayerSessionExit( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId) );
}
BOOL CSentientManager::RecordHeartBeat(DWORD dwUserId)
{
// Handled elswhere
return FALSE;
}
BOOL CSentientManager::RecordLevelStart(DWORD dwUserId, ESen_FriendOrMatch friendsOrMatch, ESen_CompeteOrCoop competeOrCoop, int difficulty, DWORD numberOfLocalPlayers, DWORD numberOfOnlinePlayers)
{
if(dwUserId == ProfileManager.GetPrimaryPad() ) m_bFirstFlush = true;
++m_levelInstanceID;
m_fLevelStartTime[dwUserId] = app.getAppTime();
return SenStatLevelStart( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID(), GetSingleOrMultiplayer(), friendsOrMatch, competeOrCoop, GetDifficultyLevel(difficulty), numberOfLocalPlayers, numberOfOnlinePlayers, GetLicense(), GetDefaultGameControls(), GetAudioSettings(dwUserId), 0, 0 );
}
BOOL CSentientManager::RecordLevelExit(DWORD dwUserId, ESen_LevelExitStatus levelExitStatus)
{
float levelDuration = app.getAppTime() - m_fLevelStartTime[dwUserId];
return SenStatLevelExit( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID(), levelExitStatus, GetLevelExitProgressStat1(), GetLevelExitProgressStat2(), (INT)levelDuration );
}
BOOL CSentientManager::RecordLevelSaveOrCheckpoint(DWORD dwUserId, INT saveOrCheckPointID, INT saveSizeInBytes)
{
float levelDuration = app.getAppTime() - m_fLevelStartTime[dwUserId];
return SenStatLevelSaveOrCheckpoint( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID(), GetLevelExitProgressStat1(), GetLevelExitProgressStat2(), (INT)levelDuration, saveOrCheckPointID, saveSizeInBytes );
}
BOOL CSentientManager::RecordLevelResume(DWORD dwUserId, ESen_FriendOrMatch friendsOrMatch, ESen_CompeteOrCoop competeOrCoop, int difficulty, DWORD numberOfLocalPlayers, DWORD numberOfOnlinePlayers, INT saveOrCheckPointID)
{
return SenStatLevelResume( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID(), GetSingleOrMultiplayer(), friendsOrMatch, competeOrCoop, GetDifficultyLevel(difficulty), numberOfLocalPlayers, numberOfOnlinePlayers, GetLicense(), GetDefaultGameControls(), saveOrCheckPointID, GetAudioSettings(dwUserId), 0, 0 );
}
BOOL CSentientManager::RecordPauseOrInactive(DWORD dwUserId)
{
return SenStatPauseOrInactive( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID() );
}
BOOL CSentientManager::RecordUnpauseOrActive(DWORD dwUserId)
{
return SenStatUnpauseOrActive( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID() );
}
BOOL CSentientManager::RecordMenuShown(DWORD dwUserId, INT menuID, INT optionalMenuSubID)
{
return SenStatMenuShown( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), menuID, optionalMenuSubID, GetLevelInstanceID(), GetMultiplayerInstanceID() );
}
BOOL CSentientManager::RecordAchievementUnlocked(DWORD dwUserId, INT achievementID, INT achievementGamerscore)
{
return SenStatAchievementUnlocked( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID(), achievementID, achievementGamerscore );
}
BOOL CSentientManager::RecordMediaShareUpload(DWORD dwUserId, ESen_MediaDestination mediaDestination, ESen_MediaType mediaType)
{
return SenStatMediaShareUpload( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID(), mediaDestination, mediaType );
}
BOOL CSentientManager::RecordUpsellPresented(DWORD dwUserId, ESen_UpsellID upsellId, INT marketplaceOfferID)
{
return SenStatUpsellPresented( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID(), upsellId, marketplaceOfferID );
}
BOOL CSentientManager::RecordUpsellResponded(DWORD dwUserId, ESen_UpsellID upsellId, INT marketplaceOfferID, ESen_UpsellOutcome upsellOutcome)
{
return SenStatUpsellResponded( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID(), upsellId, marketplaceOfferID, upsellOutcome );
}
BOOL CSentientManager::RecordPlayerDiedOrFailed(DWORD dwUserId, INT lowResMapX, INT lowResMapY, INT lowResMapZ, INT mapID, INT playerWeaponID, INT enemyWeaponID, ETelemetryChallenges enemyTypeID)
{
INT secs = GetSecondsSinceInitialize();
return SenStatPlayerDiedOrFailed( dwUserId, GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID(), lowResMapX, lowResMapY, lowResMapZ, mapID, playerWeaponID, enemyWeaponID, enemyTypeID, secs, secs );
}
BOOL CSentientManager::RecordEnemyKilledOrOvercome(DWORD dwUserId, INT lowResMapX, INT lowResMapY, INT lowResMapZ, INT mapID, INT playerWeaponID, INT enemyWeaponID, ETelemetryChallenges enemyTypeID)
{
INT secs = GetSecondsSinceInitialize();
return SenStatEnemyKilledOrOvercome( dwUserId, GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID(), lowResMapX, lowResMapY, lowResMapZ, mapID, playerWeaponID, enemyWeaponID, enemyTypeID, secs, secs );
}
BOOL CSentientManager::RecordSkinChanged(DWORD dwUserId, DWORD dwSkinId)
{
return SenStatSkinChanged( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID(), dwSkinId );
}
BOOL CSentientManager::RecordBanLevel(DWORD dwUserId)
{
return SenStatBanLevel( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID() );
}
BOOL CSentientManager::RecordUnBanLevel(DWORD dwUserId)
{
return SenStatUnBanLevel( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID() );
}
BOOL CSentientManager::RecordTexturePackLoaded(DWORD dwUserId, INT texturePackId, INT purchased)
{
return SenStatTexturePackChanged( dwUserId, GetSecondsSinceInitialize(), GetMode(dwUserId), GetSubMode(dwUserId), GetLevelId(dwUserId), GetSubLevelId(dwUserId), GetLevelInstanceID(), GetMultiplayerInstanceID(), texturePackId, purchased );
}
/*
Number of seconds elapsed since Sentient initialize.
Title needs to track this and report it as a property.
These times will be used to create timelines and understand durations.
This should be tracked independently of saved games (restoring a save should not reset the seconds since initialize)
*/
INT CSentientManager::GetSecondsSinceInitialize()
{
return (INT)(app.getAppTime() - m_initialiseTime);
}
/*
An in-game setting that significantly differentiates the play style of the game.
(This should be captured as an integer and correspond to mode specific to the game.)
Teams will have to provide the game mappings that correspond to the integers.
The intent is to allow teams to capture data on the highest level categories of gameplay in their game.
For example, a game mode could be the name of the specific mini game (eg: golf vs darts) or a specific multiplayer mode (eg: hoard vs beast.) ModeID = 0 means undefined or unknown.
The intent is to answer the question "How are players playing your game?"
*/
INT CSentientManager::GetMode(DWORD dwUserId)
{
INT mode = (INT)eTelem_ModeId_Undefined;
Minecraft *pMinecraft = Minecraft::GetInstance();
if( pMinecraft->localplayers[dwUserId] != NULL && pMinecraft->localplayers[dwUserId]->level != NULL && pMinecraft->localplayers[dwUserId]->level->getLevelData() != NULL )
{
GameType *gameType = pMinecraft->localplayers[dwUserId]->level->getLevelData()->getGameType();
if (gameType->isSurvival())
{
mode = (INT)eTelem_ModeId_Survival;
}
else if (gameType->isCreative())
{
mode = (INT)eTelem_ModeId_Creative;
}
else
{
mode = (INT)eTelem_ModeId_Undefined;
}
}
return mode;
}
/*
Used when a title has more heirarchy required.
OptionalSubMode ID = 0 means undefined or unknown.
For titles that have sub-modes (Sports/Football).
Mode is always an indicator of "How is the player choosing to play my game?" so these do not have to be consecutive.
LevelIDs and SubLevelIDs can be reused as they will always be paired with a Mode/SubModeID, Mode should be unique - SubMode can be shared between modes.
*/
INT CSentientManager::GetSubMode(DWORD dwUserId)
{
INT subMode = (INT)eTelem_SubModeId_Undefined;
if(Minecraft::GetInstance()->isTutorial())
{
subMode = (INT)eTelem_SubModeId_Tutorial;
}
else
{
subMode = (INT)eTelem_SubModeId_Normal;
}
return subMode;
}
/*
This is a more granular view of mode, allowing teams to get a sense of the levels or maps players are playing and providing some insight into how players progress through a game.
Teams will have to provide the game mappings that correspond to the integers.
The intent is that a level is highest level at which modes can be dissected and provides an indication of player progression in a game.
The intent is that level start and ends do not occur more than every 2 minutes or so, otherwise the data reported will be difficult to understand.
Levels are unique only within a given modeID - so you can have a ModeID =1, LevelID =1 and a different ModeID=2, LevelID = 1 indicate two completely different levels.
LevelID = 0 means undefined or unknown.
*/
INT CSentientManager::GetLevelId(DWORD dwUserId)
{
INT levelId = (INT)eTelem_LevelId_Undefined;
levelId = (INT)eTelem_LevelId_PlayerGeneratedLevel;
return levelId;
}
/*
Used when a title has more heirarchy required. OptionalSubLevel ID = 0 means undefined or unknown.
For titles that have sub-levels.
Level is always an indicator of "How far has the player progressed." so when possible these should be consecutive or at least monotonically increasing.
LevelIDs and SubLevelIDs can be reused as they will always be paired with a Mode/SubModeID
*/
INT CSentientManager::GetSubLevelId(DWORD dwUserId)
{
INT subLevelId = (INT)eTelem_SubLevelId_Undefined;
Minecraft *pMinecraft = Minecraft::GetInstance();
if(pMinecraft->localplayers[dwUserId] != NULL)
{
switch(pMinecraft->localplayers[dwUserId]->dimension)
{
case 0:
subLevelId = (INT)eTelem_SubLevelId_Overworld;
break;
case -1:
subLevelId = (INT)eTelem_SubLevelId_Nether;
break;
case 1:
subLevelId = (INT)eTelem_SubLevelId_End;
break;
};
}
return subLevelId;
}
/*
Build version of the title, used to track changes in development as well as patches/title updates
Allows developer to separate out stats from different builds
*/
INT CSentientManager::GetTitleBuildId()
{
return (INT)VER_PRODUCTBUILD;
}
/*
Generated by the game every time LevelStart or LevelResume is called.
This should be a unique ID (can be sequential) within a session.
Helps differentiate level attempts when a play plays the same mode/level - especially with aggregated stats
*/
INT CSentientManager::GetLevelInstanceID()
{
return (INT)m_levelInstanceID;
}
/*
MultiplayerinstanceID is a title-generated value that is the same for all players in the same multiplayer session.
Link up players into a single multiplayer session ID.
*/
INT CSentientManager::GetMultiplayerInstanceID()
{
return m_multiplayerInstanceID;
}
INT CSentientManager::GenerateMultiplayerInstanceId()
{
FILETIME SystemTimeAsFileTime;
GetSystemTimeAsFileTime( &SystemTimeAsFileTime );
return *((INT *)&SystemTimeAsFileTime.dwLowDateTime);
}
void CSentientManager::SetMultiplayerInstanceId(INT value)
{
m_multiplayerInstanceID = value;
}
/*
Indicates whether the game is being played in single or multiplayer mode and whether multiplayer is being played locally or over live.
How social is your game? How do people play it?
*/
INT CSentientManager::GetSingleOrMultiplayer()
{
INT singleOrMultiplayer = (INT)eSen_SingleOrMultiplayer_Undefined;
// Unused
//eSen_SingleOrMultiplayer_Single_Player
//eSen_SingleOrMultiplayer_Multiplayer_Live
if(app.GetLocalPlayerCount() == 1 && g_NetworkManager.GetOnlinePlayerCount() == 0)
{
singleOrMultiplayer = (INT)eSen_SingleOrMultiplayer_Single_Player;
}
else if(app.GetLocalPlayerCount() > 1 && g_NetworkManager.GetOnlinePlayerCount() == 0)
{
singleOrMultiplayer = (INT)eSen_SingleOrMultiplayer_Multiplayer_Local;
}
else if(app.GetLocalPlayerCount() == 1 && g_NetworkManager.GetOnlinePlayerCount() > 0)
{
singleOrMultiplayer = (INT)eSen_SingleOrMultiplayer_Multiplayer_Live;
}
else if(app.GetLocalPlayerCount() > 1 && g_NetworkManager.GetOnlinePlayerCount() > 0)
{
singleOrMultiplayer = (INT)eSen_SingleOrMultiplayer_Multiplayer_Both_Local_and_Live;
}
return singleOrMultiplayer;
}
/*
An in-game setting that differentiates the challenge imposed on the user.
Normalized to a standard 5-point scale. Are players changing the difficulty?
*/
INT CSentientManager::GetDifficultyLevel(INT diff)
{
INT difficultyLevel = (INT)eSen_DifficultyLevel_Undefined;
switch(diff)
{
case 0:
difficultyLevel = (INT)eSen_DifficultyLevel_Easiest;
break;
case 1:
difficultyLevel = (INT)eSen_DifficultyLevel_Easier;
break;
case 2:
difficultyLevel = (INT)eSen_DifficultyLevel_Normal;
break;
case 3:
difficultyLevel = (INT)eSen_DifficultyLevel_Harder;
break;
}
// Unused
//eSen_DifficultyLevel_Hardest = 5,
return difficultyLevel;
}
/*
Differentiates trial/demo from full purchased titles
Is this a full title or demo?
*/
INT CSentientManager::GetLicense()
{
INT license = eSen_License_Undefined;
if(ProfileManager.IsFullVersion())
{
license = (INT)eSen_License_Full_Purchased_Title;
}
else
{
license = (INT)eSen_License_Trial_or_Demo;
}
return license;
}
/*
This is intended to capture whether players played using default control scheme or customized the control scheme.
Are players customizing your controls?
*/
INT CSentientManager::GetDefaultGameControls()
{
INT defaultGameControls = eSen_DefaultGameControls_Undefined;
// Unused
//eSen_DefaultGameControls_Custom_controls
defaultGameControls = eSen_DefaultGameControls_Default_controls;
return defaultGameControls;
}
/*
Are players changing default audio settings?
This is intended to capture whether players are playing with or without volume and whether they make changes from the default audio settings.
*/
INT CSentientManager::GetAudioSettings(DWORD dwUserId)
{
INT audioSettings = (INT)eSen_AudioSettings_Undefined;
if(dwUserId == ProfileManager.GetPrimaryPad())
{
BYTE volume = app.GetGameSettings(dwUserId,eGameSetting_SoundFXVolume);
if(volume == 0)
{
audioSettings = (INT)eSen_AudioSettings_Off;
}
else if(volume == DEFAULT_VOLUME_LEVEL)
{
audioSettings = (INT)eSen_AudioSettings_On_Default;
}
else
{
audioSettings = (INT)eSen_AudioSettings_On_CustomSetting;
}
}
return audioSettings;
}
/*
Refers to the highest level performance metric for your game.
For example, a performance metric could points earned, race time, total kills, etc.
This is entirely up to you and will help us understand how well the player performed, or how far the player progressed <20>in the level before exiting.
How far did users progress before failing/exiting the level?
*/
INT CSentientManager::GetLevelExitProgressStat1()
{
// 4J Stu - Unused
return 0;
}
/*
Refers to the highest level performance metric for your game.
For example, a performance metric could points earned, race time, total kills, etc.
This is entirely up to you and will help us understand how well the player performed, or how far the player progressed <20>in the level before exiting.
How far did users progress before failing/exiting the level?
*/
INT CSentientManager::GetLevelExitProgressStat2()
{
// 4J Stu - Unused
return 0;
}

View File

@@ -0,0 +1,81 @@
#pragma once
#include "MinecraftTelemetry.h"
class CSentientManager : public CTelemetryManager
{
public:
enum ETelemetryEvent
{
eTelemetry_PlayerSessionStart,
eTelemetry_PlayerSessionExit,
eTelemetry_HeartBeat,
eTelemetry_LevelStart,
eTelemetry_LevelExit,
eTelemetry_LevelSaveOrCheckpoint,
eTelemetry_PauseOrInactive,
eTelemetry_UnpauseOrActive,
eTelemetry_MenuShown,
eTelemetry_AchievementUnlocked,
eTelemetry_MediaShareUpload,
eTelemetry_UpsellPresented,
eTelemetry_UpsellResponded,
eTelemetry_PlayerDiedOrFailed,
eTelemetry_EnemyKilledOrOvercome,
};
virtual HRESULT Init();
virtual HRESULT Tick();
virtual HRESULT Flush();
virtual BOOL RecordPlayerSessionStart(DWORD dwUserId);
virtual BOOL RecordPlayerSessionExit(DWORD dwUserId, int exitStatus);
virtual BOOL RecordHeartBeat(DWORD dwUserId);
virtual BOOL RecordLevelStart(DWORD dwUserId, ESen_FriendOrMatch friendsOrMatch, ESen_CompeteOrCoop competeOrCoop, int difficulty, DWORD numberOfLocalPlayers, DWORD numberOfOnlinePlayers);
virtual BOOL RecordLevelExit(DWORD dwUserId, ESen_LevelExitStatus levelExitStatus);
virtual BOOL RecordLevelSaveOrCheckpoint(DWORD dwUserId, INT saveOrCheckPointID, INT saveSizeInBytes);
virtual BOOL RecordLevelResume(DWORD dwUserId, ESen_FriendOrMatch friendsOrMatch, ESen_CompeteOrCoop competeOrCoop, int difficulty, DWORD numberOfLocalPlayers, DWORD numberOfOnlinePlayers, INT saveOrCheckPointID);
virtual BOOL RecordPauseOrInactive(DWORD dwUserId);
virtual BOOL RecordUnpauseOrActive(DWORD dwUserId);
virtual BOOL RecordMenuShown(DWORD dwUserId, INT menuID, INT optionalMenuSubID);
virtual BOOL RecordAchievementUnlocked(DWORD dwUserId, INT achievementID, INT achievementGamerscore);
virtual BOOL RecordMediaShareUpload(DWORD dwUserId, ESen_MediaDestination mediaDestination, ESen_MediaType mediaType);
virtual BOOL RecordUpsellPresented(DWORD dwUserId, ESen_UpsellID upsellId, INT marketplaceOfferID);
virtual BOOL RecordUpsellResponded(DWORD dwUserId, ESen_UpsellID upsellId, INT marketplaceOfferID, ESen_UpsellOutcome upsellOutcome);
virtual BOOL RecordPlayerDiedOrFailed(DWORD dwUserId, INT lowResMapX, INT lowResMapY, INT lowResMapZ, INT mapID, INT playerWeaponID, INT enemyWeaponID, ETelemetryChallenges enemyTypeID);
virtual BOOL RecordEnemyKilledOrOvercome(DWORD dwUserId, INT lowResMapX, INT lowResMapY, INT lowResMapZ, INT mapID, INT playerWeaponID, INT enemyWeaponID, ETelemetryChallenges enemyTypeID);
virtual BOOL RecordTexturePackLoaded(DWORD dwUserId, INT texturePackId, INT purchased);
virtual BOOL RecordSkinChanged(DWORD dwUserId, DWORD dwSkinId);
virtual BOOL RecordBanLevel(DWORD dwUserId);
virtual BOOL RecordUnBanLevel(DWORD dwUserId);
virtual INT GetMultiplayerInstanceID();
virtual INT GenerateMultiplayerInstanceId();
virtual void SetMultiplayerInstanceId(INT value);
private:
float m_lastHeartbeat;
bool m_bFirstFlush;
float m_fLevelStartTime[XUSER_MAX_COUNT];
INT m_multiplayerInstanceID;
DWORD m_levelInstanceID;
// Helper functions to get the various common settings
INT GetSecondsSinceInitialize();
INT GetMode(DWORD dwUserId);
INT GetSubMode(DWORD dwUserId);
INT GetLevelId(DWORD dwUserId);
INT GetSubLevelId(DWORD dwUserId);
INT GetTitleBuildId();
INT GetLevelInstanceID();
INT GetSingleOrMultiplayer();
INT GetDifficultyLevel(INT diff);
INT GetLicense();
INT GetDefaultGameControls();
INT GetAudioSettings(DWORD dwUserId);
INT GetLevelExitProgressStat1();
INT GetLevelExitProgressStat2();
};

View File

@@ -0,0 +1,731 @@
/************************************************************************/
/* THIS FILE WAS AUTOMATICALLY GENERATED */
/* PLEASE DO NOT MODIFY */
/************************************************************************/
// Generated from Version: 24, on (9/4/2013 8:47:23 AM)
#include <xtl.h>
#include "SenClientStats.h"
using namespace Sentient;
/************************************************************************/
/* STATS */
/************************************************************************/
// PlayerSessionStart
BOOL SenStatPlayerSessionStart ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT TitleBuildID, INT SkeletonDistanceInInches, INT EnrollmentType, INT NumberOfSkeletonsInView, INT DeploymentType )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT TitleBuildID;
INT SkeletonDistanceInInches;
INT EnrollmentType;
INT NumberOfSkeletonsInView;
INT DeploymentType;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, TitleBuildID, SkeletonDistanceInInches, EnrollmentType, NumberOfSkeletonsInView, DeploymentType };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 128;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 10;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("PlayerSessionStart", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// PlayerSessionExit
BOOL SenStatPlayerSessionExit ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 129;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 5;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("PlayerSessionExit", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// HeartBeat
BOOL SenStatHeartBeat ( DWORD dwUserID, INT SecondsSinceInitialize )
{
struct
{
INT SecondsSinceInitialize;
} LocalStruct = { SecondsSinceInitialize };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 130;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 1;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("HeartBeat", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// LevelStart
BOOL SenStatLevelStart ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT SingleOrMultiplayer, INT FriendsOrMatch, INT CompeteOrCoop, INT DifficultyLevel, INT NumberOfLocalPlayers, INT NumberOfOnlinePlayers, INT License, INT DefaultGameControls, INT AudioSettings, INT SkeletonDistanceInInches, INT NumberOfSkeletonsInView )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
INT SingleOrMultiplayer;
INT FriendsOrMatch;
INT CompeteOrCoop;
INT DifficultyLevel;
INT NumberOfLocalPlayers;
INT NumberOfOnlinePlayers;
INT License;
INT DefaultGameControls;
INT AudioSettings;
INT SkeletonDistanceInInches;
INT NumberOfSkeletonsInView;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID, SingleOrMultiplayer, FriendsOrMatch, CompeteOrCoop, DifficultyLevel, NumberOfLocalPlayers, NumberOfOnlinePlayers, License, DefaultGameControls, AudioSettings, SkeletonDistanceInInches, NumberOfSkeletonsInView };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 131;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 18;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("LevelStart", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// LevelExit
BOOL SenStatLevelExit ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT LevelExitStatus, INT LevelExitProgressStat1, INT LevelExitProgressStat2, INT LevelDurationInSeconds )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
INT LevelExitStatus;
INT LevelExitProgressStat1;
INT LevelExitProgressStat2;
INT LevelDurationInSeconds;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID, LevelExitStatus, LevelExitProgressStat1, LevelExitProgressStat2, LevelDurationInSeconds };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 132;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 11;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("LevelExit", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// LevelSaveOrCheckpoint
BOOL SenStatLevelSaveOrCheckpoint ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT LevelExitProgressStat1, INT LevelExitProgressStat2, INT LevelDurationInSeconds, INT SaveOrCheckPointID, INT SaveSizeInBytes )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
INT LevelExitProgressStat1;
INT LevelExitProgressStat2;
INT LevelDurationInSeconds;
INT SaveOrCheckPointID;
INT SaveSizeInBytes;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID, LevelExitProgressStat1, LevelExitProgressStat2, LevelDurationInSeconds, SaveOrCheckPointID, SaveSizeInBytes };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 133;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 12;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("LevelSaveOrCheckpoint", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// LevelResume
BOOL SenStatLevelResume ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT SingleOrMultiplayer, INT FriendsOrMatch, INT CompeteOrCoop, INT DifficultyLevel, INT NumberOfLocalPlayers, INT NumberOfOnlinePlayers, INT License, INT DefaultGameControls, INT SaveOrCheckPointID, INT AudioSettings, INT SkeletonDistanceInInches, INT NumberOfSkeletonsInView )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
INT SingleOrMultiplayer;
INT FriendsOrMatch;
INT CompeteOrCoop;
INT DifficultyLevel;
INT NumberOfLocalPlayers;
INT NumberOfOnlinePlayers;
INT License;
INT DefaultGameControls;
INT SaveOrCheckPointID;
INT AudioSettings;
INT SkeletonDistanceInInches;
INT NumberOfSkeletonsInView;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID, SingleOrMultiplayer, FriendsOrMatch, CompeteOrCoop, DifficultyLevel, NumberOfLocalPlayers, NumberOfOnlinePlayers, License, DefaultGameControls, SaveOrCheckPointID, AudioSettings, SkeletonDistanceInInches, NumberOfSkeletonsInView };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 134;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 19;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("LevelResume", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// PauseOrInactive
BOOL SenStatPauseOrInactive ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 135;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 7;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("PauseOrInactive", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// UnpauseOrActive
BOOL SenStatUnpauseOrActive ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 136;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 7;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("UnpauseOrActive", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// MenuShown
BOOL SenStatMenuShown ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT MenuID, INT OptionalMenuSubID, INT LevelInstanceID, INT MultiplayerInstanceID )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT MenuID;
INT OptionalMenuSubID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, MenuID, OptionalMenuSubID, LevelInstanceID, MultiplayerInstanceID };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 137;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 9;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("MenuShown", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// AchievementUnlocked
BOOL SenStatAchievementUnlocked ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT AchievementID, INT AchievementGamerscore )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
INT AchievementID;
INT AchievementGamerscore;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID, AchievementID, AchievementGamerscore };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 138;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 9;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("AchievementUnlocked", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// MediaShareUpload
BOOL SenStatMediaShareUpload ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT MediaDestination, INT MediaType )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
INT MediaDestination;
INT MediaType;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID, MediaDestination, MediaType };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 139;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 9;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("MediaShareUpload", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// UpsellPresented
BOOL SenStatUpsellPresented ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT UpsellID, INT MarketplaceOfferID )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
INT UpsellID;
INT MarketplaceOfferID;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID, UpsellID, MarketplaceOfferID };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 140;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 9;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("UpsellPresented", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// UpsellResponded
BOOL SenStatUpsellResponded ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT UpsellID, INT MarketplaceOfferID, INT UpsellOutcome )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
INT UpsellID;
INT MarketplaceOfferID;
INT UpsellOutcome;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID, UpsellID, MarketplaceOfferID, UpsellOutcome };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 141;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 10;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("UpsellResponded", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// PlayerDiedOrFailed
BOOL SenStatPlayerDiedOrFailed ( DWORD dwUserID, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT LowResMapX, INT LowResMapY, INT LowResMapZ, INT MapID, INT PlayerWeaponID, INT EnemyWeaponID, INT EnemyTypeID, INT SecondsSinceInitialize, INT CopyOfSecondsSinceInitialize )
{
struct
{
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
INT LowResMapX;
INT LowResMapY;
INT LowResMapZ;
INT MapID;
INT PlayerWeaponID;
INT EnemyWeaponID;
INT EnemyTypeID;
INT SecondsSinceInitialize;
INT CopyOfSecondsSinceInitialize;
INT Count;
} LocalStruct = { ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID, LowResMapX, LowResMapY, LowResMapZ, MapID, PlayerWeaponID, EnemyWeaponID, EnemyTypeID, SecondsSinceInitialize, CopyOfSecondsSinceInitialize, 1 };
DWORD arrValueFlags[] = { SenStatValueFlag_Min, SenStatValueFlag_Max, SenStatValueFlag_Inc };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 142;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 13;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 3;
st.arrValues = (CHAR*)&LocalStruct.SecondsSinceInitialize;
st.arrValueFlags = arrValueFlags;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("PlayerDiedOrFailed", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// EnemyKilledOrOvercome
BOOL SenStatEnemyKilledOrOvercome ( DWORD dwUserID, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT LowResMapX, INT LowResMapY, INT LowResMapZ, INT MapID, INT PlayerWeaponID, INT EnemyWeaponID, INT EnemyTypeID, INT SecondsSinceInitialize, INT CopyOfSecondsSinceInitialize )
{
struct
{
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
INT LowResMapX;
INT LowResMapY;
INT LowResMapZ;
INT MapID;
INT PlayerWeaponID;
INT EnemyWeaponID;
INT EnemyTypeID;
INT SecondsSinceInitialize;
INT CopyOfSecondsSinceInitialize;
INT Count;
} LocalStruct = { ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID, LowResMapX, LowResMapY, LowResMapZ, MapID, PlayerWeaponID, EnemyWeaponID, EnemyTypeID, SecondsSinceInitialize, CopyOfSecondsSinceInitialize, 1 };
DWORD arrValueFlags[] = { SenStatValueFlag_Min, SenStatValueFlag_Max, SenStatValueFlag_Inc };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 143;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 13;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 3;
st.arrValues = (CHAR*)&LocalStruct.SecondsSinceInitialize;
st.arrValueFlags = arrValueFlags;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("EnemyKilledOrOvercome", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// SkinChanged
BOOL SenStatSkinChanged ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT SkinID )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
INT SkinID;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID, SkinID };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 144;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 8;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("SkinChanged", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// BanLevel
BOOL SenStatBanLevel ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 145;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 7;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("BanLevel", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// UnBanLevel
BOOL SenStatUnBanLevel ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 146;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 7;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("UnBanLevel", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
// TexturePackChanged
BOOL SenStatTexturePackChanged ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT TexturePackId, INT Purchased )
{
struct
{
INT SecondsSinceInitialize;
INT ModeID;
INT OptionalSubModeID;
INT LevelID;
INT OptionalSubLevelID;
INT LevelInstanceID;
INT MultiplayerInstanceID;
INT TexturePackId;
INT Purchased;
} LocalStruct = { SecondsSinceInitialize, ModeID, OptionalSubModeID, LevelID, OptionalSubLevelID, LevelInstanceID, MultiplayerInstanceID, TexturePackId, Purchased };
SenStat st;
st.dwUserID = dwUserID;
st.dwStatID = 147;
st.dwFlags = SenStatFlag_Normal;
st.dwNumProperties = 9;
st.arrProperties = (CHAR*)&LocalStruct;
st.dwNumValues = 0;
st.arrValues = NULL;
st.arrValueFlags = NULL;
#ifdef SEN_LOGTELEMETRY
// if we're in debug build with logging then log the stat to a file for testing
SentientDebugLogStatSend("TexturePackChanged", &st );
#endif
return Sentient::SentientStatsSend( &st ) == S_OK;
}
namespace Sentient
{
extern int statsVersion;
class StatsVersionClass {
public: StatsVersionClass() { statsVersion = 24; }
};
static StatsVersionClass versionClass;
}

View File

@@ -0,0 +1,92 @@
/************************************************************************/
/* THIS FILE WAS AUTOMATICALLY GENERATED */
/* PLEASE DO NOT MODIFY */
/************************************************************************/
// Generated from Version: 24, on (9/4/2013 8:47:23 AM)
#pragma once
/************************************************************************/
/* STATS */
/************************************************************************/
// PlayerSessionStart
// Player signed in or joined
BOOL SenStatPlayerSessionStart ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT TitleBuildID, INT SkeletonDistanceInInches, INT EnrollmentType, INT NumberOfSkeletonsInView, INT DeploymentType );
// PlayerSessionExit
// Player signed out or left
BOOL SenStatPlayerSessionExit ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID );
// HeartBeat
// Sent every 60 seconds by title
BOOL SenStatHeartBeat ( DWORD dwUserID, INT SecondsSinceInitialize );
// LevelStart
// Level started
BOOL SenStatLevelStart ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT SingleOrMultiplayer, INT FriendsOrMatch, INT CompeteOrCoop, INT DifficultyLevel, INT NumberOfLocalPlayers, INT NumberOfOnlinePlayers, INT License, INT DefaultGameControls, INT AudioSettings, INT SkeletonDistanceInInches, INT NumberOfSkeletonsInView );
// LevelExit
// Level exited
BOOL SenStatLevelExit ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT LevelExitStatus, INT LevelExitProgressStat1, INT LevelExitProgressStat2, INT LevelDurationInSeconds );
// LevelSaveOrCheckpoint
// Level saved explicitly or implicitly
BOOL SenStatLevelSaveOrCheckpoint ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT LevelExitProgressStat1, INT LevelExitProgressStat2, INT LevelDurationInSeconds, INT SaveOrCheckPointID, INT SaveSizeInBytes );
// LevelResume
// Level resumed from a save or restarted at a checkpoint
BOOL SenStatLevelResume ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT SingleOrMultiplayer, INT FriendsOrMatch, INT CompeteOrCoop, INT DifficultyLevel, INT NumberOfLocalPlayers, INT NumberOfOnlinePlayers, INT License, INT DefaultGameControls, INT SaveOrCheckPointID, INT AudioSettings, INT SkeletonDistanceInInches, INT NumberOfSkeletonsInView );
// PauseOrInactive
// Player paused game or has become inactive, level and mode are for what the player is leaving
BOOL SenStatPauseOrInactive ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID );
// UnpauseOrActive
// Player unpaused game or has become active, level and mode are for what the player is entering into
BOOL SenStatUnpauseOrActive ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID );
// MenuShown
// A menu screen or major menu area has been shown
BOOL SenStatMenuShown ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT MenuID, INT OptionalMenuSubID, INT LevelInstanceID, INT MultiplayerInstanceID );
// AchievementUnlocked
// An achievement was unlocked
BOOL SenStatAchievementUnlocked ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT AchievementID, INT AchievementGamerscore );
// MediaShareUpload
// The user uploaded something to Kinect Share
BOOL SenStatMediaShareUpload ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT MediaDestination, INT MediaType );
// UpsellPresented
// The user is shown an upsell to purchase something
BOOL SenStatUpsellPresented ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT UpsellID, INT MarketplaceOfferID );
// UpsellResponded
// The user responded to the upsell
BOOL SenStatUpsellResponded ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT UpsellID, INT MarketplaceOfferID, INT UpsellOutcome );
// PlayerDiedOrFailed
// The player died or failed a challenge - can be used for many types of failure
BOOL SenStatPlayerDiedOrFailed ( DWORD dwUserID, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT LowResMapX, INT LowResMapY, INT LowResMapZ, INT MapID, INT PlayerWeaponID, INT EnemyWeaponID, INT EnemyTypeID, INT SecondsSinceInitialize, INT CopyOfSecondsSinceInitialize );
// EnemyKilledOrOvercome
// The player killed an enemy or overcame or solved a major challenge
BOOL SenStatEnemyKilledOrOvercome ( DWORD dwUserID, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT LowResMapX, INT LowResMapY, INT LowResMapZ, INT MapID, INT PlayerWeaponID, INT EnemyWeaponID, INT EnemyTypeID, INT SecondsSinceInitialize, INT CopyOfSecondsSinceInitialize );
// SkinChanged
// The player has changed their skin, level and mode are for what the player is currently in
BOOL SenStatSkinChanged ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT SkinID );
// BanLevel
// The player has banned a level, level and mode are for what the player is currently in and banning
BOOL SenStatBanLevel ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID );
// UnBanLevel
// The player has unbanned a level, level and mode are for what the player is currently in and unbanning
BOOL SenStatUnBanLevel ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID );
// TexturePackChanged
// The player has changed their texture pack, level and mode are for what the player is currently in
BOOL SenStatTexturePackChanged ( DWORD dwUserID, INT SecondsSinceInitialize, INT ModeID, INT OptionalSubModeID, INT LevelID, INT OptionalSubLevelID, INT LevelInstanceID, INT MultiplayerInstanceID, INT TexturePackId, INT Purchased );

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="SentientStats">
<xs:complexType>
<xs:sequence>
<xs:element ref="Stat" maxOccurs="128"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Stat">
<xs:complexType>
<xs:sequence>
<xs:element ref="Parameters"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="desc" type="xs:string" use="required"/>
<xs:attribute name="type" type="statType" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Parameters">
<xs:complexType>
<xs:sequence>
<xs:element ref="Param" maxOccurs="20"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Param">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="type" type="paramType" use="required"/>
<xs:attribute name="op" type="operator" use="required"/>
</xs:complexType>
</xs:element>
<xs:simpleType name ="statType">
<xs:restriction base="xs:string">
<xs:enumeration value="event"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name ="paramType">
<xs:restriction base="xs:string">
<xs:enumeration value="int"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name ="operator">
<xs:restriction base="xs:string">
<xs:enumeration value="none"/>
<xs:enumeration value="accumulate"/>
<xs:enumeration value="increment"/>
<xs:enumeration value="min"/>
<xs:enumeration value="max"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

View File

@@ -0,0 +1,191 @@
#pragma once
// 4J Stu - Enums as defined by the common Sentient telemetry format
//##################################
// DO NOT CHANGE ANY OF THESE VALUES
//##################################
/*************************************
AudioSettings
*************************************
Are players changing default audio settings?
*/
enum ESen_AudioSettings
{
eSen_AudioSettings_Undefined = 0,
eSen_AudioSettings_Off = 1,
eSen_AudioSettings_On_Default = 2,
eSen_AudioSettings_On_CustomSetting = 3,
};
/*************************************
CompeteOrCoop
*************************************
Indicates whether players are playing a cooperative mode or a competitive mode.
*/
enum ESen_CompeteOrCoop
{
eSen_CompeteOrCoop_Undefined = 0,
eSen_CompeteOrCoop_Cooperative = 1,
eSen_CompeteOrCoop_Competitive = 2,
eSen_CompeteOrCoop_Coop_and_Competitive = 3,
};
/*************************************
DefaultGameControls
*************************************
This is intended to capture whether players played using default control scheme or customized the control scheme.
*/
enum ESen_DefaultGameControls
{
eSen_DefaultGameControls_Undefined = 0,
eSen_DefaultGameControls_Default_controls = 1,
eSen_DefaultGameControls_Custom_controls = 2,
};
/*************************************
DifficultyLevel
*************************************
An in-game setting that differentiates the challenge imposed on the user. Normalized to a standard 5-point scale.
*/
enum ESen_DifficultyLevel
{
eSen_DifficultyLevel_Undefined = 0,
eSen_DifficultyLevel_Easiest = 1,
eSen_DifficultyLevel_Easier = 2,
eSen_DifficultyLevel_Normal = 3,
eSen_DifficultyLevel_Harder = 4,
eSen_DifficultyLevel_Hardest = 5,
};
/*************************************
GameInputType
*************************************
Used to determine the different modes of input used in the game. For gamepad/keyboard/mouse usage, it is not necessary to call this for every single input.
Also, if polling is used, calling this event occasionally may also work.
*/
enum ESen_GameInputType
{
eSen_GameInputType_Undefined = 0,
eSen_GameInputType_Xbox_Controller = 1,
eSen_GameInputType_Gesture = 2,
eSen_GameInputType_Voice = 3,
eSen_GameInputType_Voice_and_Gesture_Together = 4,
eSen_GameInputType_Touch = 5,
eSen_GameInputType_Keyboard = 6,
eSen_GameInputType_Mouse = 7,
};
/*************************************
LevelExitStatus
*************************************
Indicates whether the player successfully completed the level. Critical for understanding the difficulty of a game with checkpoints or saves.
*/
enum ESen_LevelExitStatus
{
eSen_LevelExitStatus_Undefined = 0,
eSen_LevelExitStatus_Exited = 1,
eSen_LevelExitStatus_Succeeded = 2,
eSen_LevelExitStatus_Failed = 3,
};
/*************************************
License
*************************************
Differentiates trial/demo from full purchased titles
*/
enum ESen_License
{
eSen_License_Undefined = 0,
eSen_License_Trial_or_Demo = 1,
eSen_License_Full_Purchased_Title = 2,
};
/*************************************
MediaDestination
*************************************
Tracks where media is uploaded to (like facebook)
*/
enum ESen_MediaDestination
{
ESen_MediaDestination_Undefined = 0,
ESen_MediaDestination_Kinect_Share = 1,
ESen_MediaDestination_Facebook = 2,
ESen_MediaDestination_YouTube = 3,
ESen_MediaDestination_Other = 4
};
/*************************************
MediaType
*************************************
Used to capture the type of media players are uploading to KinectShare
*/
enum ESen_MediaType
{
eSen_MediaType_Undefined = 0,
eSen_MediaType_Picture = 1,
eSen_MediaType_Video = 2,
eSen_MediaType_Other_UGC = 3,
};
/*************************************
SingleOrMultiplayer
*************************************
Indicates whether the game is being played in single or multiplayer mode and whether multiplayer is being played locally or over live.
*/
enum ESen_SingleOrMultiplayer
{
eSen_SingleOrMultiplayer_Undefined = 0,
eSen_SingleOrMultiplayer_Single_Player = 1,
eSen_SingleOrMultiplayer_Multiplayer_Local = 2,
eSen_SingleOrMultiplayer_Multiplayer_Live = 3,
eSen_SingleOrMultiplayer_Multiplayer_Both_Local_and_Live = 4,
};
/*************************************
FriendOrMatch
*************************************
Are players playing with friends or were they matched?
*/
enum ESen_FriendOrMatch
{
eSen_FriendOrMatch_Undefined = 0, // (use if a single player game)
eSen_FriendOrMatch_Playing_With_Invited_Friends = 1,
eSen_FriendOrMatch_Playing_With_Match_Made_Opponents = 2,
eSen_FriendOrMatch_Playing_With_Both_Friends_And_Matched_Opponents = 3,
eSen_FriendOrMatch_Joined_Through_An_Xbox_Live_Party = 4,
eSen_FriendOrMatch_Joined_Through_An_In_Game_Party = 5,
};
/*************************************
UpsellID
*************************************
Which upsell has been presented?
*/
enum ESen_UpsellID
{
eSen_UpsellID_Undefined = 0,
eSen_UpsellID_Full_Version_Of_Game = 1,
// Added TU3
eSet_UpsellID_Skin_DLC = 2,
eSet_UpsellID_Texture_DLC = 3,
//2-max= Up to game
};
/*************************************
UpsellOutcome
*************************************
What was the outcome of the upsell?
*/
enum ESen_UpsellOutcome
{
eSen_UpsellOutcome_Undefined = 0,
eSen_UpsellOutcome_Accepted = 1,
eSen_UpsellOutcome_Declined = 2,
eSen_UpsellOutcome_Went_To_Guide = 3,
eSen_UpsellOutcome_Other = 4,
};

View File

@@ -0,0 +1,229 @@
#pragma once
/*
AchievementGamerscore Value in gamerscore of the achievement
AchievementID ID of achievement unlocked
EnemyTypeID What type of enemy or challenge was the player facing? To prevent data-loss by overflowing the buffer, we recommend enemy type.
EnemyWeaponID What weapon the enemy is holding or what counter/AI the enemy is taking to overcome a challenge
EnrollmentType How did players enroll? (Using Kinect)
LandscapeOrPortrait Are you currently showing in landscape or portrait mode? (Win8 only)
LevelDurationInSeconds How long, total, has the user been playing in this level - whatever best represents this duration for attempting the level you'd like to track.
LevelExitProgressStat1 Refers to the highest level performance metric for your game.<2E> For example, a performance metric could points earned, race time, total kills, etc. This is entirely up to you and will help us understand how well the player performed, or how far the player progressed <20>in the level before exiting.
LevelExitProgressStat2 Refers to the highest level performance metric for your game.<2E> For example, a performance metric could points earned, race time, total kills, etc. This is entirely up to you and will help us understand how well the player performed, or how far the player progressed <20>in the level before exiting.
LevelID This is a more granular view of mode, allowing teams to get a sense of the levels or maps players are playing and providing some insight into how players progress through a game. Teams will have to provide the game mappings that correspond to the integers. The intent is that a level is highest level at which modes can be dissected and provides an indication of player progression in a game. The intent is that level start and ends do not occur more than every 2 minutes or so, otherwise the data reported will be difficult to understand. Levels are unique only within a given modeID - so you can have a ModeID =1, LevelID =1 and a different ModeID=2, LevelID = 1 indicate two completely different levels. LevelID = 0 means undefined or unknown.
LevelInstanceID Generated by the game every time LevelStart or LevelResume is called. This should be a unique ID (can be sequential) within a session.
LowResMapX Player position normalized to 0-255
LowResMapY Player position normalized to 0-255
LowResMapZ Player position normalized to 0-255
MapID Unique ID for the current map the player is on
MarketplaceOfferID Unique ID for the Xbox LIVE marketplace offer that the upsell links to
MicroGoodTypeID Describes the type of consumable or microgood
MultiplayerInstanceID multiplayerinstanceID is a title-generated value that is the same for all players in the same multiplayer session.<2E>
NumberOfLocalPlayers the number of players that are playing together in the game locally in the current session (on the same piece of hardware)
NumberOfOnlinePlayers the number of players that are playing together in the game online in the current session (not on the same piece of hardware)
NumberOfSkeletonsInView the max and min of skeletons that were in view, regardless of enrollment
OptionalSubLevelID Used when a title has more heirarchy required. OptionalSubLevel ID = 0 means undefined or unknown.
OptionalSubModeID Used when a title has more heirarchy required. OptionalSubMode ID = 0 means undefined or unknown.
PlayerLevelUpProgressStat1 Refers to a performance metric for your player when they level or rank up. This is entirely up to you and will help us understand how well the player performed, or how far the player has progressed.
PlayerLevelUpProgressStat2 Refers to a performance metric for your player when they level or rank up. This is entirely up to you and will help us understand how well the player performed, or how far the player has progressed.
PlayerWeaponID What weapon the player is holding or what approach/tact the player is taking to overcome a challenge
PlayspaceFeedbackWarningDirection identifies which side of the playspace players are getting too close to that results in the playspace feedback
SaveOrCheckpointID It is important that you also generate and save a unique SaveOrCheckpointID that can be read and reported when the player resumes from this save file or checkpoint. These IDs should be completely unique across the player<65>s experience, even if they play the same level multiple times. These IDs are critical to allowing us to re-stitch a player<65>s experience in your title and provide an accurate measure of time in level.
SecondsSinceInitialize Number of seconds elapsed since Sentient initialize.
SecondsSinceInitializeMax Number of seconds elapsed since Sentient initialize.
SecondsSinceInitializeMin Number of seconds elapsed since Sentient initialize.
SkeletonDistanceInInches Identifies the distance of the skeleton from the Kinect sensor
TitleBuildID Build version of the title, used to track changes in development as well as patches/title updates
*/
/*
ModeID
An in-game setting that significantly differentiates the play style of the game.
(This should be captured as an integer and correspond to mode specific to the game.)
Teams will have to provide the game mappings that correspond to the integers.
The intent is to allow teams to capture data on the highest level categories of gameplay in their game.
For example, a game mode could be the name of the specific mini game (eg: golf vs darts) or a specific multiplayer mode (eg: hoard vs beast.) ModeID = 0 means undefined or unknown.
*/
enum ETelem_ModeId
{
eTelem_ModeId_Undefined = 0,
eTelem_ModeId_Survival,
eTelem_ModeId_Creative, // Unused in current game version
};
/*
OptionalSubModeID
Used when a title has more heirarchy required.
OptionalSubMode ID = 0 means undefined or unknown.
*/
enum ETelem_SubModeId
{
eTelem_SubModeId_Undefined = 0,
eTelem_SubModeId_Normal,
eTelem_SubModeId_Tutorial,
};
/*
LevelID
This is a more granular view of mode, allowing teams to get a sense of the levels or maps players are playing and providing some insight into how players progress through a game.
Teams will have to provide the game mappings that correspond to the integers.
The intent is that a level is highest level at which modes can be dissected and provides an indication of player progression in a game.
The intent is that level start and ends do not occur more than every 2 minutes or so, otherwise the data reported will be difficult to understand.
Levels are unique only within a given modeID - so you can have a ModeID =1, LevelID =1 and a different ModeID=2, LevelID = 1 indicate two completely different levels.
LevelID = 0 means undefined or unknown.
*/
enum ETelem_LevelId
{
eTelem_LevelId_Undefined = 0,
eTelem_LevelId_PlayerGeneratedLevel = 1,
// 4J Stu - We currently do not have any specific levels (other than the tutorial which is tracked as a mode) so this is unused at the moment
};
/*
OptionalSubLevelID
Used when a title has more heirarchy required. OptionalSubLevel ID = 0 means undefined or unknown.
*/
enum ETelem_SubLevelId
{
eTelem_SubLevelId_Undefined = 0,
eTelem_SubLevelId_Overworld,
eTelem_SubLevelId_Nether,
eTelem_SubLevelId_End,
};
/*
MenuID
Describes the specific menu seen. MenuID = 0 means undefined or unknown.
*/
// 4J Stu - FOR REFERENCE ONLY - Should map 1:1 with the CConsoleMinecraftApp:EUIScene enum
// Values that are commented out here are not currently reported
enum ETelem_MenuId
{
//eTelemMenuId_PartnernetPassword = 0,
//eTelemMenuId_Intro = 1,
//eTelemMenuId_SaveMessage = 2,
//eTelemMenuId_Main = 3,
//eTelemMenuId_FullscreenProgress = 4,
eTelemMenuId_Pause = 5,
//eTelemMenuId_CraftingPanel_2x2 = 6,
//eTelemMenuId_CraftingPanel_3x3 = 7,
//eTelemMenuId_Furnace = 8,
//eTelemMenuId_Container = 9,
//eTelemMenuId_Largecontainer_small = 10,// for splitscreen
//eTelemMenuId_Inventory = 11,
//eTelemMenuId_Trap = 12,
//eTelemMenuId_Debug = 13,
//eTelemMenuId_DebugTips = 14,
//eTelemMenuId_HelpAndOptions = 15,
eTelemMenuId_HowToPlay = 16,
//eTelemMenuId_HowToPlayMenu = 17,
//eTelemMenuId_Controls = 18,
//eTelemMenuId_Settings_Menu = 19,
//eTelemMenuId_Settings_All = 20,
//eTelemMenuId_Leaderboards = 21,
//eTelemMenuId_Credits = 22,
//eTelemMenuId_Death = 23,
//eTelemMenuId_TutorialPopup = 24,
eTelemMenuId_MultiGameCreate = 25,
//eTelemMenuId_MultiGameJoinLoad = 26,
eTelemMenuId_MultiGameInfo = 27,
//eTelemMenuId_SignEntry = 28,
//eTelemMenuId_InGameInfo = 29,
//eTelemMenuId_ConnectingProgress = 30,
eTelemMenuId_DLCOffers = 31,
eTelemMenuId_SocialPost = 32,
//eTelemMenuId_TrialExitUpsell = 33,
eTelemMenuId_LoadSettings = 34,
//eTelemMenuId_Chat = 35,
//eTelemMenuId_Reinstall = 36,
};
/*
OptionalSubMenuID
Used when a title has more heirarchy required. OptionalSubMenuID = 0 means undefined or unknown.
*/
enum ETelemetry_HowToPlay_SubMenuId
{
eTelemetryHowToPlay_Basics = 0,
eTelemetryHowToPlay_HUD,
eTelemetryHowToPlay_Inventory,
eTelemetryHowToPlay_Chest,
eTelemetryHowToPlay_LargeChest,
eTelemetryHowToPlay_InventoryCrafting,
eTelemetryHowToPlay_CraftTable,
eTelemetryHowToPlay_Furnace,
eTelemetryHowToPlay_Dispenser,
eTelemetryHowToPlay_NetherPortal,
};
/*
EnemyTypeID What type of enemy or challenge was the player facing?
To prevent data-loss by overflowing the buffer, we recommend enemy type.
*/
enum ETelemetryChallenges
{
eTelemetryChallenges_Unknown = 0,
eTelemetryTutorial_TrialStart,
eTelemetryTutorial_Halfway,
eTelemetryTutorial_Complete,
eTelemetryTutorial_Inventory,
eTelemetryTutorial_Crafting,
eTelemetryTutorial_Furnace,
eTelemetryTutorial_Fishing,
eTelemetryTutorial_Minecart,
eTelemetryTutorial_Boat,
eTelemetryTutorial_Bed,
eTelemetryTutorial_Redstone_And_Pistons,
eTelemetryTutorial_Portal,
eTelemetryTutorial_FoodBar,
eTelemetryTutorial_CreativeMode,
eTelemetryTutorial_BrewingMenu,
eTelemetryInGame_Ride_Minecart,
eTelemetryInGame_Ride_Boat,
eTelemetryInGame_Ride_Pig,
eTelemetryInGame_UseBed,
eTelemetryTutorial_CreativeInventory, // Added TU5
eTelemetryTutorial_EnchantingMenu,
eTelemetryTutorial_Brewing,
eTelemetryTutorial_Enchanting,
eTelemetryTutorial_Farming,
eTelemetryPlayerDeathSource_Fall,
eTelemetryPlayerDeathSource_Lava,
eTelemetryPlayerDeathSource_Fire,
eTelemetryPlayerDeathSource_Water,
eTelemetryPlayerDeathSource_Suffocate,
eTelemetryPlayerDeathSource_OutOfWorld,
eTelemetryPlayerDeathSource_Cactus,
eTelemetryPlayerDeathSource_Player_Weapon,
eTelemetryPlayerDeathSource_Player_Arrow,
eTelemetryPlayerDeathSource_Explosion_Tnt,
eTelemetryPlayerDeathSource_Explosion_Creeper,
eTelemetryPlayerDeathSource_Wolf,
eTelemetryPlayerDeathSource_Zombie,
eTelemetryPlayerDeathSource_Skeleton,
eTelemetryPlayerDeathSource_Spider,
eTelemetryPlayerDeathSource_Slime,
eTelemetryPlayerDeathSource_Ghast,
eTelemetryPlayerDeathSource_ZombiePigman,
eTelemetryTutorial_Breeding,
eTelemetryTutorial_Golem,
eTelemetryTutorial_Anvil, // Added TU14
eTelemetryTutorial_AnvilMenu,
eTelemetryTutorial_Trading,
eTelemetryTutorial_TradingMenu,
eTelemetryTutorial_Enderchest,
// Sent over network as a byte
};