first commit
This commit is contained in:
3624
Minecraft.Client/PS3/Network/SQRNetworkManager_PS3.cpp
Normal file
3624
Minecraft.Client/PS3/Network/SQRNetworkManager_PS3.cpp
Normal file
File diff suppressed because it is too large
Load Diff
300
Minecraft.Client/PS3/Network/SQRNetworkManager_PS3.h
Normal file
300
Minecraft.Client/PS3/Network/SQRNetworkManager_PS3.h
Normal file
@@ -0,0 +1,300 @@
|
||||
#pragma once
|
||||
#include <np.h>
|
||||
#ifdef __PS3__
|
||||
#include <netex\libnetctl.h>
|
||||
#include <netex\net.h>
|
||||
#else
|
||||
#include <libnetctl.h>
|
||||
#include <net.h>
|
||||
#endif
|
||||
#include <queue>
|
||||
|
||||
#include "..\..\Common\Network\Sony\SQRNetworkManager.h"
|
||||
|
||||
class SQRNetworkPlayer;
|
||||
class ISQRNetworkManagerListener;
|
||||
class SonyVoiceChat;
|
||||
class C4JThread;
|
||||
|
||||
// This is the lowest level manager for providing network functionality on Sony platforms. This manages various network activities including the players within a gaming session.
|
||||
// The game shouldn't directly use this class, it is here to provide functionality required by PlatformNetworkManagerSony.
|
||||
|
||||
class SQRNetworkManager_PS3 : public SQRNetworkManager
|
||||
{
|
||||
|
||||
friend class SonyVoiceChat;
|
||||
friend class SQRNetworkPlayer;
|
||||
static const eSQRNetworkManagerState m_INTtoEXTStateMappings[SNM_INT_STATE_COUNT];
|
||||
|
||||
|
||||
|
||||
public:
|
||||
SQRNetworkManager_PS3(ISQRNetworkManagerListener *listener);
|
||||
|
||||
// General
|
||||
void Tick();
|
||||
void Initialise();
|
||||
void Terminate();
|
||||
eSQRNetworkManagerState GetState();
|
||||
bool IsHost();
|
||||
bool IsReadyToPlayOrIdle();
|
||||
bool IsInSession();
|
||||
|
||||
// Session management
|
||||
void CreateAndJoinRoom(int hostIndex, int localPlayerMask, void *extData, int extDataSize, bool offline);
|
||||
void UpdateExternalRoomData();
|
||||
bool FriendRoomManagerIsBusy();
|
||||
bool FriendRoomManagerSearch();
|
||||
bool FriendRoomManagerSearch2();
|
||||
int FriendRoomManagerGetCount();
|
||||
void FriendRoomManagerGetRoomInfo(int idx, SessionSearchResult *searchResult);
|
||||
bool JoinRoom(SessionSearchResult *searchResult, int localPlayerMask);
|
||||
bool JoinRoom(SceNpMatching2RoomId roomId, SceNpMatching2ServerId serverId, int localPlayerMask, const SQRNetworkManager_PS3::PresenceSyncInfo *presence);
|
||||
void StartGame();
|
||||
void LeaveRoom(bool bActuallyLeaveRoom);
|
||||
void EndGame();
|
||||
bool SessionHasSpace(int spaceRequired);
|
||||
bool AddLocalPlayerByUserIndex(int idx);
|
||||
bool RemoveLocalPlayerByUserIndex(int idx);
|
||||
void SendInviteGUI();
|
||||
void GetInviteDataAndProcess(SceNpBasicAttachmentDataId id);
|
||||
static bool UpdateInviteData(SQRNetworkManager_PS3::PresenceSyncInfo *invite);
|
||||
void GetExtDataForRoom( SceNpMatching2RoomId roomId, void *extData, void (* FriendSessionUpdatedFn)(bool success, void *pParam), void *pParam );
|
||||
|
||||
// Player retrieval
|
||||
int GetPlayerCount();
|
||||
int GetOnlinePlayerCount();
|
||||
SQRNetworkPlayer *GetPlayerByIndex(int idx);
|
||||
SQRNetworkPlayer *GetPlayerBySmallId(int idx);
|
||||
SQRNetworkPlayer *GetPlayerByXuid(PlayerUID xuid);
|
||||
SQRNetworkPlayer *GetLocalPlayerByUserIndex(int idx);
|
||||
SQRNetworkPlayer *GetHostPlayer();
|
||||
|
||||
// Communication parameter storage
|
||||
static const SceNpCommunicationId* GetSceNpCommsId();
|
||||
static const SceNpCommunicationSignature* GetSceNpCommsSig();
|
||||
|
||||
private:
|
||||
void InitialiseAfterOnline();
|
||||
void ErrorHandlingTick();
|
||||
void UpdateOnlineStatus(int status) { m_onlineStatus = status; }
|
||||
int GetOnlineStatus() { return m_onlineStatus; }
|
||||
|
||||
ISQRNetworkManagerListener *m_listener;
|
||||
SQRNetworkPlayer *GetPlayerIfReady(SQRNetworkPlayer *player);
|
||||
|
||||
// Internal state
|
||||
void SetState(eSQRNetworkManagerInternalState state);
|
||||
void ResetToIdle();
|
||||
eSQRNetworkManagerInternalState m_state;
|
||||
eSQRNetworkManagerState m_stateExternal;
|
||||
bool m_nextIdleReasonIsFull;
|
||||
bool m_isHosting;
|
||||
SceNpMatching2RoomMemberId m_localMemberId;
|
||||
int m_localPlayerCount;
|
||||
int m_localPlayerJoined; // Client only, keep a count of how many local players we have confirmed as joined to the application
|
||||
SceNpMatching2RoomId m_room;
|
||||
unsigned char m_currentSmallId;
|
||||
int m_soc;
|
||||
bool m_offlineGame;
|
||||
bool m_offlineSQR;
|
||||
int m_resendExternalRoomDataCountdown;
|
||||
bool m_matching2initialised;
|
||||
PresenceSyncInfo m_inviteReceived[MAX_SIMULTANEOUS_INVITES];
|
||||
int m_inviteIndex;
|
||||
PresenceSyncInfo *m_gameBootInvite;
|
||||
bool m_doBootInviteCheck;
|
||||
bool m_isInSession;
|
||||
static SceNpBasicAttachmentDataId s_lastInviteIdToRetry;
|
||||
int m_onlineStatus;
|
||||
bool m_bLinkDisconnected;
|
||||
private:
|
||||
|
||||
CRITICAL_SECTION m_csRoomSyncData;
|
||||
RoomSyncData m_roomSyncData;
|
||||
void *m_joinExtData;
|
||||
int m_joinExtDataSize;
|
||||
|
||||
std::vector<SQRNetworkPlayer *> m_vecTempPlayers;
|
||||
SQRNetworkPlayer *m_aRoomSlotPlayers[MAX_ONLINE_PLAYER_COUNT]; // Maps from the players in m_roomSyncData, to SQRNetworkPlayers
|
||||
void FindOrCreateNonNetworkPlayer(int slot, int playerType, SceNpMatching2RoomMemberId memberId, int localPlayerIdx, int smallId);
|
||||
|
||||
void MapRoomSlotPlayers(int roomSlotPlayerCount =-1);
|
||||
void UpdateRoomSyncUIDsFromPlayers();
|
||||
void UpdatePlayersFromRoomSyncUIDs();
|
||||
void LocalDataSend(SQRNetworkPlayer *playerFrom, SQRNetworkPlayer *playerTo, const void *data, unsigned int dataSize);
|
||||
int GetSessionIndex(SQRNetworkPlayer *player);
|
||||
|
||||
bool AddRemotePlayersAndSync( SceNpMatching2RoomMemberId memberId, int playerMask, bool *isFull = NULL );
|
||||
void RemoveRemotePlayersAndSync( SceNpMatching2RoomMemberId memberId, int mask );
|
||||
void RemoveNetworkPlayers( int mask );
|
||||
void SetLocalPlayersAndSync();
|
||||
void SyncRoomData();
|
||||
SceNpMatching2RequestId m_setRoomDataRequestId;
|
||||
SceNpMatching2RequestId m_setRoomIntDataRequestId;
|
||||
SceNpMatching2RequestId m_roomExtDataRequestId;
|
||||
|
||||
// Server context management
|
||||
bool GetMatchingContext(eSQRNetworkManagerInternalState asyncState);
|
||||
bool GetServerContext();
|
||||
bool GetServerContext2();
|
||||
bool GetServerContext(SceNpMatching2ServerId serverId);
|
||||
void DeleteServerContext();
|
||||
bool SelectRandomServer();
|
||||
void ServerContextTick();
|
||||
int m_totalServerCount;
|
||||
int m_serverCount;
|
||||
SceNpMatching2ServerId *m_aServerId;
|
||||
SceNpMatching2ServerId m_serverId;
|
||||
bool m_serverContextValid;
|
||||
SceNpMatching2RequestId m_serverSearchRequestId;
|
||||
SceNpMatching2RequestId m_serverContextRequestId;
|
||||
|
||||
// Room creation management
|
||||
SceNpMatching2RequestId m_getWorldRequestId;
|
||||
SceNpMatching2RequestId m_createRoomRequestId;
|
||||
SceNpMatching2WorldId m_worldId;
|
||||
void RoomCreateTick();
|
||||
|
||||
// Room joining management
|
||||
SceNpMatching2RoomId m_roomToJoin;
|
||||
int m_localPlayerJoinMask;
|
||||
SceNpMatching2RequestId m_joinRoomRequestId;
|
||||
SceNpMatching2RequestId m_kickRequestId;
|
||||
|
||||
// Room leaving management
|
||||
SceNpMatching2RequestId m_leaveRoomRequestId;
|
||||
|
||||
// Adding extra network players management
|
||||
SceNpMatching2RequestId m_setRoomMemberInternalDataRequestId;
|
||||
|
||||
// Player state management
|
||||
void NetworkPlayerConnectionComplete(SQRNetworkPlayer *player);
|
||||
void NetworkPlayerSmallIdAllocated(SQRNetworkPlayer *player, unsigned char smallId);
|
||||
void NetworkPlayerInitialDataReceived(SQRNetworkPlayer *player,void *data);
|
||||
void NonNetworkPlayerComplete(SQRNetworkPlayer *player, unsigned char smallId);
|
||||
void HandlePlayerJoined(SQRNetworkPlayer *player);
|
||||
CRITICAL_SECTION m_csPlayerState;
|
||||
|
||||
// State and thread for managing basic event type messages
|
||||
C4JThread *m_basicEventThread;
|
||||
sys_event_port_t m_basicEventPort;
|
||||
sys_event_queue_t m_basicEventQueue;
|
||||
static int BasicEventThreadProc( void *lpParameter);
|
||||
|
||||
// State and storage for managing search for friends' games
|
||||
eSQRNetworkManagerFriendSearchState m_friendSearchState;
|
||||
SceNpMatching2ContextId m_matchingContext;
|
||||
bool m_matchingContextValid;
|
||||
SceNpMatching2RequestId m_friendSearchRequestId;
|
||||
unsigned int m_friendCount;
|
||||
C4JThread *m_getFriendCountThread;
|
||||
static int GetFriendsThreadProc( void* lpParameter );
|
||||
void FriendSearchTick();
|
||||
SceNpMatching2RequestId m_roomDataExternalListRequestId;
|
||||
void (* m_FriendSessionUpdatedFn)(bool success, void *pParam);
|
||||
void *m_pParamFriendSessionUpdated;
|
||||
void *m_pExtDataToUpdate;
|
||||
|
||||
// Results from searching for rooms that friends are playing in - 5 matched arrays to store their NpIds, rooms, servers, whether a room was found, and whether the external data had been received for the room. Also a count of how many elements are used in this array.
|
||||
SceNpId m_aSearchResultNpId[MAX_FRIENDS];
|
||||
SceNpMatching2RoomId m_aSearchResultRoomId[MAX_FRIENDS];
|
||||
SceNpMatching2ServerId m_aSearchResultServerId[MAX_FRIENDS];
|
||||
bool m_aSearchResultRoomFound[MAX_FRIENDS];
|
||||
void *m_aSearchResultRoomExtDataReceived[MAX_FRIENDS];
|
||||
unsigned int m_searchResultCount;
|
||||
|
||||
// Rudp management and local players
|
||||
unordered_map<int,SQRNetworkPlayer *> m_RudpCtxToPlayerMap;
|
||||
bool CreateRudpConnections(SceNpMatching2RoomId roomId, SceNpMatching2RoomMemberId peerMemberId, int playerMask, SceNpMatching2RoomMemberId playersPeerMemberId);
|
||||
SQRNetworkPlayer *GetPlayerFromRudpCtx(int rudpCtx);
|
||||
SQRNetworkPlayer *GetPlayerFromRoomMemberAndLocalIdx(int roomMember, int localIdx);
|
||||
SceNpMatching2RequestId m_roomMemberDataRequestId;
|
||||
|
||||
// Callbacks (for matching)
|
||||
bool RegisterCallbacks();
|
||||
static void ContextCallback(SceNpMatching2ContextId id, SceNpMatching2Event event, SceNpMatching2EventCause eventCause, int errorCode, void *arg);
|
||||
#ifdef __PS3__
|
||||
static void DefaultRequestCallback(SceNpMatching2ContextId id, SceNpMatching2RequestId reqId, SceNpMatching2Event event, SceNpMatching2EventKey eventKey, int errorCode, size_t dataSize, void *arg);
|
||||
static void RoomEventCallback(SceNpMatching2ContextId id, SceNpMatching2RoomId roomId, SceNpMatching2Event event, SceNpMatching2EventKey eventKey, int errorCode, size_t dataSize, void *arg);
|
||||
#else
|
||||
static void DefaultRequestCallback(SceNpMatching2ContextId id, SceNpMatching2RequestId reqId, SceNpMatching2Event event, int errorCode, const void *data, void *arg);
|
||||
static void RoomEventCallback(SceNpMatching2ContextId id, SceNpMatching2RoomId roomId, SceNpMatching2Event event, int errorCode, const void *data, void *arg);
|
||||
#endif
|
||||
static void SignallingCallback(SceNpMatching2ContextId ctxId, SceNpMatching2RoomId roomId, SceNpMatching2RoomMemberId peerMemberId, SceNpMatching2Event event, int errorCode, void *arg);
|
||||
|
||||
// Callback for NpBasic
|
||||
static int BasicEventCallback(int event, int retCode, uint32_t reqId, void *arg);
|
||||
|
||||
// Callback for NpManager
|
||||
static void ManagerCallback(int event, int result, void *arg);
|
||||
|
||||
// Callback for sys util
|
||||
static void SysUtilCallback(uint64_t status, uint64_t param, void *userdata);
|
||||
|
||||
// Callbacks for rudp
|
||||
static void RudpContextCallback(int ctx_id, int event_id, int error_code, void *arg);
|
||||
#ifdef __PS3__
|
||||
static int RudpEventCallback(int event_id, int soc, uint8_t const *data, size_t datalen, struct sockaddr const *addr, socklen_t addrlen, void *arg);
|
||||
#else
|
||||
static int RudpEventCallback(int event_id, int soc, uint8_t const *data, size_t datalen, struct SceNetSockaddr const *addr, SceNetSocklen_t addrlen, void *arg);
|
||||
#endif
|
||||
|
||||
// Callback for netctl
|
||||
static void NetCtlCallback(int prev_state, int new_state, int event, int error_code, void *arg);
|
||||
|
||||
// Methods to be called when the server context has been created
|
||||
void ServerContextValid_CreateRoom();
|
||||
void ServerContextValid_JoinRoom();
|
||||
|
||||
// Mask utilities
|
||||
int GetOldMask(SceNpMatching2RoomMemberId memberId);
|
||||
int GetAddedMask(int newMask, int oldMask);
|
||||
int GetRemovedMask(int newMask, int oldMask);
|
||||
|
||||
#ifdef __PS3__
|
||||
// Response storage
|
||||
char cUserInfoListStorage[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetUserInfoList] __attribute__((__aligned__(4)));
|
||||
char cServerInfoStorage[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetServerInfo] __attribute__((__aligned__(4)));
|
||||
char cWorldListStorage[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetWorldInfoList] __attribute__((__aligned__(4)));
|
||||
char cCreateJoinRoomStorage[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_CreateJoinRoom] __attribute__((__aligned__(4)));
|
||||
char cJoinRoomStorage[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_JoinRoom] __attribute__((__aligned__(4)));
|
||||
char cRoomMemberDataInternal[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetRoomMemberDataInternal] __attribute__((__aligned__(4)));
|
||||
char cRoomDataInternal[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_RoomDataInternalUpdateInfo] __attribute__((__aligned__(4)));
|
||||
char cRoomDataExternalList[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetRoomDataExternalList] __attribute__((__aligned__(4)));
|
||||
char cRoomMemberDataInternalUpdate[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_RoomMemberDataInternalUpdateInfo] __attribute__((__aligned__(4)));
|
||||
char cRoomDataUpdateInfo[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_RoomUpdateInfo] __attribute__((__aligned__(4)));
|
||||
#endif
|
||||
|
||||
#ifndef _CONTENT_PACKAGE
|
||||
static bool aForceError[SNM_FORCE_ERROR_COUNT];
|
||||
#endif
|
||||
bool ForceErrorPoint(eSQRForceError err);
|
||||
|
||||
public:
|
||||
static void AttemptPSNSignIn(int (*SignInCompleteCallbackFn)(void *pParam, bool bContinue, int pad), void *pParam, bool callIfFailed = false);
|
||||
static int (*s_SignInCompleteCallbackFn)(void *pParam, bool bContinue, int pad);
|
||||
static bool s_signInCompleteCallbackIfFailed;
|
||||
static void *s_SignInCompleteParam;
|
||||
|
||||
static int SetRichPresence(const void *data, unsigned int options);
|
||||
void SetPresenceDataStartHostingGame();
|
||||
int GetJoiningReadyPercentage();
|
||||
private:
|
||||
static void UpdateRichPresenceCustomData(void *data, unsigned int dataBytes);
|
||||
static void TickRichPresence();
|
||||
static void SendLastPresenceInfo();
|
||||
|
||||
static SceNpBasicPresenceDetails2 s_lastPresenceInfo;
|
||||
static int s_resendPresenceCountdown;
|
||||
static bool s_presenceStatusDirty;
|
||||
static bool s_presenceDataDirty;
|
||||
static PresenceSyncInfo s_lastPresenceSyncInfo;
|
||||
static PresenceSyncInfo c_presenceSyncInfoNULL;
|
||||
|
||||
// 4J-PB - so we can stop the crash on PS3 when Iggy's LoadMovie is called from the ContextCallback
|
||||
static bool m_bCallPSNSignInCallback;
|
||||
|
||||
// Debug
|
||||
static long long s_roomStartTime;
|
||||
};
|
||||
1513
Minecraft.Client/PS3/Network/SonyCommerce_PS3.cpp
Normal file
1513
Minecraft.Client/PS3/Network/SonyCommerce_PS3.cpp
Normal file
File diff suppressed because it is too large
Load Diff
180
Minecraft.Client/PS3/Network/SonyCommerce_PS3.h
Normal file
180
Minecraft.Client/PS3/Network/SonyCommerce_PS3.h
Normal file
@@ -0,0 +1,180 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <np.h>
|
||||
#include <np/drm.h>
|
||||
#include <np/commerce2.h>
|
||||
#include "Common\Network\Sony\SonyCommerce.h"
|
||||
|
||||
#define SCE_TOOLKIT_NP_SKU_PRICE_LEN (SCE_NP_COMMERCE2_CURRENCY_CODE_LEN \
|
||||
+ SCE_NP_COMMERCE2_CURRENCY_SYMBOL_LEN \
|
||||
+ SCE_NP_COMMERCE2_THOUSAND_SEPARATOR_LEN \
|
||||
+ SCE_NP_COMMERCE2_DECIMAL_LETTER_LEN) ///< The maximum length of a price in characters.
|
||||
|
||||
class SonyCommerce_PS3 : public SonyCommerce
|
||||
{
|
||||
enum State
|
||||
{
|
||||
e_state_noSession,
|
||||
e_state_creatingSession,
|
||||
e_state_createSessionDone,
|
||||
e_state_idle,
|
||||
|
||||
|
||||
};
|
||||
/// This enum is used to verify the current utility that is running
|
||||
enum Phase
|
||||
{
|
||||
e_phase_stopped = 0,
|
||||
e_phase_idle,
|
||||
e_phase_voucherRedeemPhase,
|
||||
e_phase_productBrowsePhase,
|
||||
e_phase_creatingSessionPhase,
|
||||
e_phase_checkoutPhase,
|
||||
e_phase_downloadListPhase
|
||||
};
|
||||
|
||||
enum Message
|
||||
{
|
||||
e_message_commerceNone,
|
||||
e_message_commerceCreateSession, ///< Create a commerce session
|
||||
e_message_commerceGetCategoryInfo, ///< Information about a category in the Store
|
||||
e_message_commerceGetProductList, ///< Get a list of products available in the Store
|
||||
e_message_commerceGetDetailedProductInfo, ///< Get a list of products available in the Store, with additional details
|
||||
e_message_commerceAddDetailedProductInfo, ///< Add additional details to a ProdcutInfo already retrieved
|
||||
e_message_commerceStoreProductBrowse, ///< Launches the Store to a specified product
|
||||
e_message_commerceUpgradeTrial, ///< Upgrade a trial to full game
|
||||
e_message_commerceRedeemVoucher, ///< Redeem a voucher code
|
||||
e_message_commerceGetEntitlementList, ///< Get a list of entitlements associated with the current PSN user.
|
||||
e_message_commerceConsumeEntitlement, ///< Consume an amount from a consumable entitlement.
|
||||
e_message_commerceCheckout, ///< Launch the Store checkout
|
||||
e_message_commerceDownloadList, ///< Launch the download list
|
||||
e_message_commerceEnd ///< End commerce2 processing
|
||||
};
|
||||
|
||||
enum Event
|
||||
{
|
||||
e_event_none,
|
||||
e_event_commerceSessionCreated, ///< An event generated when a commerce session has successfully been created.
|
||||
e_event_commerceSessionAborted, ///< An event generated when the creation of commerce session has been aborted.
|
||||
e_event_commerceGotCategoryInfo, ///< An event generated when some category information has been retrieved from the store.
|
||||
e_event_commerceGotProductList, ///< An event generated when a list of products that are available has been retrieved from the store.
|
||||
e_event_commerceGotDetailedProductInfo, ///< An event generated when some detailed product information has been retrieved from the store.
|
||||
e_event_commerceAddedDetailedProductInfo, ///< An event generated when some detailed product information has been retrieved from the store.
|
||||
e_event_commerceProductBrowseStarted, ///< An event generated when product overlay has started.
|
||||
e_event_commerceProductBrowseSuccess, ///< An event generated when a product browse was completed successfully, and the user purchased the product.
|
||||
e_event_commerceProductBrowseAborted, ///< An event generated when a product browse was aborted by the user (the user pressed back).
|
||||
e_event_commerceProductBrowseFinished, ///< An event generated when a product browse has finished and it is now safe to free memory.
|
||||
e_event_commerceVoucherInputStarted, ///< An event generated when a voucher code input overlay was started.
|
||||
e_event_commerceVoucherInputSuccess, ///< An event generated when a voucher code input completed successfully.
|
||||
e_event_commerceVoucherInputAborted, ///< An event generated when a voucher code input was aborted by the user (user pressed back).
|
||||
e_event_commerceVoucherInputFinished, ///< An event generated when a voucher code input has finished. It is now safe to free memory.
|
||||
e_event_commerceGotEntitlementList, ///< An event generated when a the list of entitlements has been received for the current user.
|
||||
e_event_commerceConsumedEntitlement, ///< An event generated when the has successfully consumed an entitlement.
|
||||
e_event_commerceCheckoutStarted, ///< An event generated when a store checkout overlay has started.
|
||||
e_event_commerceCheckoutSuccess, ///< An event generated when user has successfully purchased from the checkout.
|
||||
e_event_commerceCheckoutAborted, ///< An event generated when the checkout was aborted by the user (user pressed back).
|
||||
e_event_commerceCheckoutFinished, ///< An event generated when a store checkout overlay has finished.
|
||||
e_event_commerceDownloadListStarted, ///< An event generated when a download list overlay has started.
|
||||
e_event_commerceDownloadListSuccess, ///< An event generated when the user has ended the download list.
|
||||
e_event_commerceDownloadListFinished, ///< An event generated when a download list overlay has finished.
|
||||
e_event_commerceError ///< An event generated when a commerce error has occurred.
|
||||
};
|
||||
|
||||
static bool m_bLicenseChecked;
|
||||
static bool m_bCommerceInitialised;
|
||||
static SceNpCommerce2SessionInfo m_sessionInfo;
|
||||
static State m_state;
|
||||
static int m_errorCode;
|
||||
static LPVOID m_callbackParam;
|
||||
static Event m_event;
|
||||
static Message m_message;
|
||||
// static uint32_t m_requestID;
|
||||
static void* m_receiveBuffer;
|
||||
static std::vector<ProductInfo> *m_pProductInfoList;
|
||||
static ProductInfoDetailed *m_pProductInfoDetailed;
|
||||
static ProductInfo *m_pProductInfo;
|
||||
static CategoryInfo* m_pCategoryInfo;
|
||||
static char* m_pCategoryID;
|
||||
static const char* m_pProductID;
|
||||
static std::queue<Message> m_messageQueue;
|
||||
static CallbackFunc m_callbackFunc;
|
||||
static CheckoutInputParams m_checkoutInputParams;
|
||||
static DownloadListInputParams m_downloadInputParams;
|
||||
static sys_memory_container_t m_memContainer;
|
||||
static bool m_bUpgradingTrial;
|
||||
static C4JThread* m_tickThread;
|
||||
static CallbackFunc m_trialUpgradeCallbackFunc;
|
||||
static LPVOID m_trialUpgradeCallbackParam;
|
||||
static CRITICAL_SECTION m_queueLock;
|
||||
|
||||
static void runCallback()
|
||||
{
|
||||
assert(m_callbackFunc);
|
||||
CallbackFunc func = m_callbackFunc;
|
||||
m_callbackFunc = NULL;
|
||||
if(func)
|
||||
func(m_callbackParam, m_errorCode);
|
||||
m_errorCode = CELL_OK;
|
||||
}
|
||||
static void setCallback(CallbackFunc cb,LPVOID lpParam)
|
||||
{
|
||||
assert(m_callbackFunc == NULL);
|
||||
m_callbackFunc = cb;
|
||||
m_callbackParam = lpParam;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t m_contextId; ///< The npcommerce2 context ID
|
||||
static bool m_contextCreated; ///< npcommerce2 context ID created?
|
||||
static Phase m_currentPhase; ///< Current commerce2 util
|
||||
static char m_commercebuffer[SCE_NP_COMMERCE2_RECV_BUF_SIZE];
|
||||
|
||||
|
||||
|
||||
static void commerce2Handler(uint32_t contextId, uint32_t subjectId, int event, int errorCode, void *arg);
|
||||
static void processMessage();
|
||||
static void processEvent();
|
||||
|
||||
static int createContext();
|
||||
static int createSession();
|
||||
static void setError(int err) { m_errorCode = err; }
|
||||
static int getCategoryInfo(CategoryInfo *info, char *categoryId);
|
||||
static int getProductList(std::vector<ProductInfo>* productList, char *categoryId);
|
||||
static int getDetailedProductInfo(ProductInfoDetailed *info, const char *productId, char *categoryId);
|
||||
static int addDetailedProductInfo(ProductInfo *info, const char *productId, char *categoryId);
|
||||
static int checkout(CheckoutInputParams ¶ms);
|
||||
static int downloadList(DownloadListInputParams ¶ms);
|
||||
static void UpgradeTrialCallback1(LPVOID lpParam,int err);
|
||||
static void UpgradeTrialCallback2(LPVOID lpParam,int err);
|
||||
static void Delete();
|
||||
|
||||
|
||||
static int commerceEnd();
|
||||
// static int upgradeTrial();
|
||||
|
||||
static int TickLoop(void* lpParam);
|
||||
|
||||
static void Init();
|
||||
static int Shutdown();
|
||||
|
||||
static void CheckForTrialUpgradeKey_Callback(LPVOID param, bool bFullVersion);
|
||||
|
||||
public:
|
||||
|
||||
virtual void CreateSession(CallbackFunc cb, LPVOID lpParam);
|
||||
virtual void CloseSession();
|
||||
|
||||
virtual void GetCategoryInfo(CallbackFunc cb, LPVOID lpParam, CategoryInfo *info, const char *categoryId);
|
||||
virtual void GetProductList(CallbackFunc cb, LPVOID lpParam, std::vector<ProductInfo>* productList, const char *categoryId);
|
||||
virtual void GetDetailedProductInfo(CallbackFunc cb, LPVOID lpParam, ProductInfoDetailed* productInfoDetailed, const char *productId, const char *categoryId);
|
||||
virtual void AddDetailedProductInfo( CallbackFunc cb, LPVOID lpParam, ProductInfo* productInfo, const char *productId, const char *categoryId );
|
||||
virtual void Checkout(CallbackFunc cb, LPVOID lpParam, const char* skuID);
|
||||
virtual void DownloadAlreadyPurchased(CallbackFunc cb, LPVOID lpParam, const char* skuID);
|
||||
virtual void UpgradeTrial(CallbackFunc cb, LPVOID lpParam);
|
||||
virtual void CheckForTrialUpgradeKey();
|
||||
virtual bool LicenseChecked();
|
||||
|
||||
};
|
||||
289
Minecraft.Client/PS3/Network/SonyHttp_PS3.cpp
Normal file
289
Minecraft.Client/PS3/Network/SonyHttp_PS3.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
#include "stdafx.h"
|
||||
#include "SonyHttp_PS3.h"
|
||||
|
||||
|
||||
|
||||
// static const int sc_HTTPPoolSize = (32 * 1024);
|
||||
// static const int sc_SSLPoolSize = (256 * 1024U);
|
||||
// static const int sc_CookiePoolSize = (256 * 1024U);
|
||||
static const int sc_HTTPPoolSize = (32 * 1024);
|
||||
static const int sc_SSLPoolSize = (512 * 1024U);
|
||||
static const int sc_CookiePoolSize = (256 * 1024U);
|
||||
|
||||
void* SonyHttp_PS3::uriPool = NULL;
|
||||
void* SonyHttp_PS3::httpPool = NULL;
|
||||
void* SonyHttp_PS3::sslPool = NULL;
|
||||
void* SonyHttp_PS3::cookiePool = NULL;
|
||||
CellHttpClientId SonyHttp_PS3::client;
|
||||
CellHttpTransId SonyHttp_PS3::trans;
|
||||
bool SonyHttp_PS3:: bInitialised = false;
|
||||
|
||||
|
||||
|
||||
bool SonyHttp_PS3::loadCerts(size_t *numBufPtr, CellHttpsData **caListPtr)
|
||||
{
|
||||
CellHttpsData *caList = NULL;
|
||||
size_t size = 0;
|
||||
int ret = 0;
|
||||
char *buf = NULL;
|
||||
|
||||
caList = (CellHttpsData *)malloc(sizeof(CellHttpsData)*2);
|
||||
if (NULL == caList) {
|
||||
app.DebugPrintf("failed to malloc cert data");
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = cellSslCertificateLoader(CELL_SSL_LOAD_CERT_ALL, NULL, 0, &size);
|
||||
if (ret < 0) {
|
||||
app.DebugPrintf("cellSslCertifacateLoader() failed(1): 0x%08x", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
buf = (char*)malloc(size);
|
||||
if (NULL == buf) {
|
||||
app.DebugPrintf("failed to malloc cert buffer");
|
||||
free(caList);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = cellSslCertificateLoader(CELL_SSL_LOAD_CERT_ALL, buf, size, NULL);
|
||||
if (ret < 0) {
|
||||
app.DebugPrintf("cellSslCertifacateLoader() failed(2): 0x%08x", ret);
|
||||
free(buf);
|
||||
free(caList);
|
||||
return false;
|
||||
}
|
||||
|
||||
(&caList[0])->ptr = buf;
|
||||
(&caList[0])->size = size;
|
||||
|
||||
*caListPtr = caList;
|
||||
*numBufPtr = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SonyHttp_PS3::init()
|
||||
{
|
||||
int ret;
|
||||
client = 0;
|
||||
trans = 0;
|
||||
|
||||
/*E startup procedures */
|
||||
httpPool = malloc(sc_HTTPPoolSize);
|
||||
if (httpPool == NULL) {
|
||||
app.DebugPrintf("failed to malloc libhttp memory pool\n");
|
||||
return false;
|
||||
}
|
||||
ret = cellHttpInit(httpPool, sc_HTTPPoolSize);
|
||||
if (0 > ret)
|
||||
{
|
||||
app.DebugPrintf("unable to start libhttp... (0x%x)\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
cookiePool = malloc(sc_CookiePoolSize);
|
||||
if (cookiePool == NULL) {
|
||||
app.DebugPrintf("failed to malloc ssl memory pool\n");
|
||||
return false;
|
||||
}
|
||||
ret = cellHttpInitCookie(cookiePool, sc_CookiePoolSize);
|
||||
if (ret < 0 && ret != CELL_HTTP_ERROR_ALREADY_INITIALIZED)
|
||||
{
|
||||
app.DebugPrintf("cellHttpInitCookie failed... (0x%x)\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
sslPool = malloc(sc_SSLPoolSize);
|
||||
if (sslPool == NULL) {
|
||||
app.DebugPrintf("failed to malloc ssl memory pool\n");
|
||||
return false;
|
||||
}
|
||||
ret = cellSslInit(sslPool, sc_SSLPoolSize);
|
||||
if (0 > ret)
|
||||
{
|
||||
app.DebugPrintf("unable to start cellSslInit... (0x%x)\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t numBuf = 0;
|
||||
CellHttpsData *caList = NULL;
|
||||
if(!loadCerts(&numBuf, &caList))
|
||||
return false;
|
||||
|
||||
ret = cellHttpsInit(numBuf, caList);
|
||||
free(caList->ptr);
|
||||
free(caList);
|
||||
if (ret < 0 && ret != CELL_HTTP_ERROR_ALREADY_INITIALIZED)
|
||||
{
|
||||
app.DebugPrintf("unable to start https: 0x%08x", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = cellHttpCreateClient(&client);
|
||||
if (0 > ret)
|
||||
{
|
||||
app.DebugPrintf("unable to create http client... (0x%x)\n", ret);
|
||||
return false;
|
||||
}
|
||||
bInitialised = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SonyHttp_PS3::shutdown()
|
||||
{
|
||||
if (trans)
|
||||
{
|
||||
cellHttpDestroyTransaction(trans);
|
||||
trans = 0;
|
||||
}
|
||||
if (client)
|
||||
{
|
||||
cellHttpDestroyClient(client);
|
||||
client = 0;
|
||||
}
|
||||
cellHttpEnd();
|
||||
free(httpPool);
|
||||
}
|
||||
|
||||
|
||||
bool SonyHttp_PS3::parseUri(const char* szUri, CellHttpUri& parsedUri)
|
||||
{
|
||||
/*E the main part */
|
||||
size_t poolSize = 0;
|
||||
int ret = cellHttpUtilParseUri(NULL, szUri, NULL, 0, &poolSize);
|
||||
if (0 > ret)
|
||||
{
|
||||
app.DebugPrintf("error parsing URI... (0x%x)\n\n", ret);
|
||||
return false;
|
||||
}
|
||||
if (NULL == (uriPool = malloc(poolSize)))
|
||||
{
|
||||
app.DebugPrintf("error mallocing uriPool (%d)\n", poolSize);
|
||||
return false;
|
||||
}
|
||||
ret = cellHttpUtilParseUri(&parsedUri, szUri, uriPool, poolSize, NULL);
|
||||
if (0 > ret)
|
||||
{
|
||||
free(uriPool);
|
||||
app.DebugPrintf("error parsing URI... (0x%x)\n\n", ret);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void* SonyHttp_PS3::getData(const char* url, int* pDataSize)
|
||||
{
|
||||
CellHttpUri uri;
|
||||
int ret;
|
||||
bool has_cl = true;
|
||||
uint64_t length = 0;
|
||||
uint64_t recvd;
|
||||
const char *serverName;
|
||||
size_t localRecv = 0;
|
||||
|
||||
if(!parseUri(url, uri))
|
||||
return NULL;
|
||||
|
||||
app.DebugPrintf(" scheme: %s\n", uri.scheme);
|
||||
app.DebugPrintf(" hostname: %s\n", uri.hostname);
|
||||
app.DebugPrintf(" port: %d\n", uri.port);
|
||||
app.DebugPrintf(" path: %s\n", uri.path);
|
||||
app.DebugPrintf(" username: %s\n", uri.username);
|
||||
app.DebugPrintf(" password: %s\n", uri.password);
|
||||
|
||||
ret = cellHttpCreateTransaction(&trans, client, CELL_HTTP_METHOD_GET, &uri);
|
||||
free(uriPool);
|
||||
if (0 > ret)
|
||||
{
|
||||
app.DebugPrintf("failed to create http transaction... (0x%x)\n\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = cellHttpSendRequest(trans, NULL, 0, NULL);
|
||||
if (0 > ret)
|
||||
{
|
||||
app.DebugPrintf("failed to complete http transaction... (0x%x)\n\n", ret);
|
||||
/*E continue down to check status code, just in case */
|
||||
cellHttpDestroyTransaction(trans);
|
||||
trans = 0;
|
||||
}
|
||||
|
||||
{
|
||||
int code = 0;
|
||||
ret = cellHttpResponseGetStatusCode(trans, &code);
|
||||
if (0 > ret)
|
||||
{
|
||||
app.DebugPrintf("failed to receive http response... (0x%x)\n\n", ret);
|
||||
cellHttpDestroyTransaction(trans);
|
||||
trans = 0;
|
||||
return NULL;
|
||||
}
|
||||
app.DebugPrintf("Status Code is %d\n", code);
|
||||
}
|
||||
|
||||
ret = cellHttpResponseGetContentLength(trans, &length);
|
||||
if (0 > ret)
|
||||
{
|
||||
if (ret == CELL_HTTP_ERROR_NO_CONTENT_LENGTH)
|
||||
{
|
||||
app.DebugPrintf("Only supporting data that has a content length : CELL_HTTP_ERROR_NO_CONTENT_LENGTH\n", ret);
|
||||
cellHttpDestroyTransaction(trans);
|
||||
trans = 0;
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("error in receiving content length... (0x%x)\n\n", ret);
|
||||
cellHttpDestroyTransaction(trans);
|
||||
trans = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int bufferSize = length;
|
||||
char* buffer = (char*)malloc(bufferSize+1);
|
||||
|
||||
recvd = 0;
|
||||
|
||||
// 4J-PB - seems to be some limit to a read with cellHttpRecvResponse, even though it claims it's read all the data, it hasn't
|
||||
// reducing this to read 10k at a time.
|
||||
int iMaxRead=10240;
|
||||
app.DebugPrintf("\n===BEGINNING OF TRANSMISSION===\n");
|
||||
while(recvd<length)
|
||||
{
|
||||
ret = cellHttpRecvResponse(trans, &buffer[recvd], iMaxRead, &localRecv);
|
||||
if (0 > ret)
|
||||
{
|
||||
app.DebugPrintf("error receiving body... (0x%x)\n\n", ret);
|
||||
free(buffer);
|
||||
cellHttpDestroyTransaction(trans);
|
||||
trans = 0;
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(localRecv==0) break;
|
||||
}
|
||||
recvd += localRecv;
|
||||
}
|
||||
buffer[bufferSize] = '\0';
|
||||
ret = 0;
|
||||
app.DebugPrintf("\n===END OF TRANSMISSION===\n\n");
|
||||
*pDataSize = bufferSize;
|
||||
cellHttpDestroyTransaction(trans);
|
||||
trans = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool SonyHttp_PS3::getDataFromURL( const char* szURL, void** ppOutData, int* pDataSize)
|
||||
{
|
||||
if(!bInitialised)
|
||||
return false;
|
||||
*ppOutData = getData(szURL, pDataSize);
|
||||
if(*ppOutData)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
25
Minecraft.Client/PS3/Network/SonyHttp_PS3.h
Normal file
25
Minecraft.Client/PS3/Network/SonyHttp_PS3.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <cell/http.h>
|
||||
|
||||
|
||||
class SonyHttp_PS3
|
||||
{
|
||||
static bool loadCerts(size_t *numBufPtr, CellHttpsData **caListPtr);
|
||||
static void* getData(const char* url, int* pDataSize);
|
||||
static bool parseUri(const char* szUri, CellHttpUri& parsedUri);
|
||||
|
||||
static void *uriPool;
|
||||
static void *httpPool;
|
||||
static void* sslPool;
|
||||
static void* cookiePool;
|
||||
static CellHttpClientId client;
|
||||
static CellHttpTransId trans;
|
||||
static bool bInitialised;
|
||||
|
||||
public:
|
||||
bool init();
|
||||
void shutdown();
|
||||
bool getDataFromURL(const char* szURL, void** ppOutData, int* pDataSize);
|
||||
|
||||
};
|
||||
518
Minecraft.Client/PS3/Network/SonyRemoteStorage_PS3.cpp
Normal file
518
Minecraft.Client/PS3/Network/SonyRemoteStorage_PS3.cpp
Normal file
@@ -0,0 +1,518 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "SonyRemoteStorage_PS3.h"
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
// #include <cell/sysmodule.h>
|
||||
// #include <cell/http.h>
|
||||
// #include <cell/ssl.h>
|
||||
// #include <netex/net.h>
|
||||
// #include <netex/libnetctl.h>
|
||||
// #include <np.h>
|
||||
// #include <sysutil/sysutil_common.h>
|
||||
// #include <sys/timer.h>
|
||||
// #include <sys/paths.h>
|
||||
// #include <sysutil\sysutil_savedata.h>
|
||||
|
||||
|
||||
|
||||
// 4J-PB - ticketing changed to our SCEE product id
|
||||
#define TICKETING_SERVICE_ID "EP4433-NPEB01899_00" //"EP9009-NPWA00114_00"
|
||||
#define CLIENT_ID "969e9d21-527c-4c22-b539-f8e479f690bc"
|
||||
|
||||
|
||||
|
||||
|
||||
void SonyRemoteStorage_PS3::npauthhandler(int event, int result, void *arg)
|
||||
{
|
||||
#ifdef __PS3__
|
||||
if (event != SCE_NP_MANAGER_EVENT_GOT_TICKET || result <= 0)
|
||||
{
|
||||
app.DebugPrintf("Could not retrieve ticket: 0x%x\n", result);
|
||||
}
|
||||
else
|
||||
{
|
||||
psnTicketSize = result;
|
||||
psnTicket = malloc(psnTicketSize);
|
||||
if (psnTicket == NULL)
|
||||
{
|
||||
app.DebugPrintf("Failed to allocate for ticket\n");
|
||||
}
|
||||
|
||||
int ret = sceNpManagerGetTicket(psnTicket, &psnTicketSize);
|
||||
if (ret < 0)
|
||||
{
|
||||
app.DebugPrintf("Could not retrieve ticket: 0x%x\n", ret);
|
||||
free(psnTicket);
|
||||
psnTicket = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_waitingForTicket = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int SonyRemoteStorage_PS3::initPreconditions()
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
SceNpId npId;
|
||||
|
||||
ret = sceNpManagerGetNpId(&npId);
|
||||
if(ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
SceNpTicketVersion ticketVersion;
|
||||
ticketVersion.major = 3;
|
||||
ticketVersion.minor = 0;
|
||||
ret = sceNpManagerRequestTicket2(&npId, &ticketVersion, TICKETING_SERVICE_ID, NULL, 0, NULL, 0);
|
||||
if(ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
m_waitingForTicket = true;
|
||||
while(m_waitingForTicket)
|
||||
{
|
||||
cellSysutilCheckCallback();
|
||||
sys_timer_usleep(50000); //50 milliseconds.
|
||||
}
|
||||
if(psnTicket == NULL)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SonyRemoteStorage_PS3::staticInternalCallback(const SceRemoteStorageEvent event, int32_t retCode, void * userData)
|
||||
{
|
||||
((SonyRemoteStorage_PS3*)userData)->internalCallback(event, retCode);
|
||||
}
|
||||
|
||||
void SonyRemoteStorage_PS3::internalCallback(const SceRemoteStorageEvent event, int32_t retCode)
|
||||
{
|
||||
m_lastErrorCode = retCode;
|
||||
|
||||
switch(event)
|
||||
{
|
||||
case ERROR_OCCURRED:
|
||||
app.DebugPrintf("An error occurred with retCode: 0x%x \n", retCode);
|
||||
// shutdown(); // removed, as the remote storage lib now tries to reconnect if an error has occurred
|
||||
m_status = e_error;
|
||||
runCallback();
|
||||
m_bTransferStarted = false;
|
||||
break;
|
||||
|
||||
case GET_DATA_RESULT:
|
||||
if(retCode >= 0)
|
||||
{
|
||||
app.DebugPrintf("Get Data success \n");
|
||||
m_status = e_getDataSucceeded;
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("An error occurred while Get Data was being processed. retCode: 0x%x \n", retCode);
|
||||
m_status = e_error;
|
||||
}
|
||||
runCallback();
|
||||
m_bTransferStarted = false;
|
||||
break;
|
||||
|
||||
case GET_DATA_PROGRESS:
|
||||
app.DebugPrintf("Get data progress: %i%%\n", retCode);
|
||||
m_status = e_getDataInProgress;
|
||||
m_dataProgress = retCode;
|
||||
m_startTime = System::currentTimeMillis();
|
||||
break;
|
||||
|
||||
case GET_STATUS_RESULT:
|
||||
if(retCode >= 0)
|
||||
{
|
||||
app.DebugPrintf("Get Status success \n");
|
||||
app.DebugPrintf("Remaining Syncs for this user: %llu\n", outputGetStatus->remainingSyncs);
|
||||
app.DebugPrintf("Number of files on the cloud: %d\n", outputGetStatus->numFiles);
|
||||
for(int i = 0; i < outputGetStatus->numFiles; i++)
|
||||
{
|
||||
app.DebugPrintf("\n*** File %d information: ***\n", (i + 1));
|
||||
app.DebugPrintf("File name: %s \n", outputGetStatus->data[i].fileName);
|
||||
app.DebugPrintf("File description: %s \n", outputGetStatus->data[i].fileDescription);
|
||||
app.DebugPrintf("MD5 Checksum: %s \n", outputGetStatus->data[i].md5Checksum);
|
||||
app.DebugPrintf("Size of the file: %u bytes \n", outputGetStatus->data[i].fileSize);
|
||||
app.DebugPrintf("Timestamp: %s \n", outputGetStatus->data[i].timeStamp);
|
||||
app.DebugPrintf("Visibility: \"%s\" \n", (outputGetStatus->data[i].visibility == 0)?"Private":((outputGetStatus->data[i].visibility == 1)?"Public read only":"Public read and write"));
|
||||
}
|
||||
m_status = e_getStatusSucceeded;
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("An error occurred while Get Status was being processed. retCode: 0x%x \n", retCode);
|
||||
m_status = e_error;
|
||||
}
|
||||
runCallback();
|
||||
break;
|
||||
|
||||
case PSN_SIGN_IN_REQUIRED:
|
||||
app.DebugPrintf("User's PSN sign-in through web browser is required \n");
|
||||
m_status = e_signInRequired;
|
||||
runCallback();
|
||||
break;
|
||||
|
||||
case SET_DATA_RESULT:
|
||||
if(retCode >= 0)
|
||||
{
|
||||
app.DebugPrintf("Set Data success \n");
|
||||
m_status = e_setDataSucceeded;
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("An error occurred while Set Data was being processed. retCode: 0x%x \n", retCode);
|
||||
m_status = e_error;
|
||||
}
|
||||
runCallback();
|
||||
m_bTransferStarted = false;
|
||||
break;
|
||||
|
||||
case SET_DATA_PROGRESS:
|
||||
app.DebugPrintf("Set data progress: %i%%\n", retCode);
|
||||
m_status = e_setDataInProgress;
|
||||
m_dataProgress = retCode;
|
||||
|
||||
break;
|
||||
|
||||
case USER_ACCOUNT_LINKED:
|
||||
app.DebugPrintf("User's account has been linked with PSN \n");
|
||||
m_bInitialised = true;
|
||||
m_status = e_accountLinked;
|
||||
runCallback();
|
||||
break;
|
||||
|
||||
case WEB_BROWSER_RESULT:
|
||||
app.DebugPrintf("This function is not used on PS Vita, as the account will be linked, it is not needed to open a browser to link it \n");
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
app.DebugPrintf("This should never happen \n");
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool SonyRemoteStorage_PS3::init(CallbackFunc cb, LPVOID lpParam)
|
||||
{
|
||||
m_callbackFunc = cb;
|
||||
m_callbackParam = lpParam;
|
||||
m_bTransferStarted = false;
|
||||
m_bAborting = false;
|
||||
|
||||
if(m_bInitialised)
|
||||
{
|
||||
runCallback();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if(m_bInitialised)
|
||||
{
|
||||
internalCallback(USER_ACCOUNT_LINKED, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
int ret = initPreconditions();
|
||||
if(ret < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SceRemoteStorageInitParams params;
|
||||
|
||||
params.callback = staticInternalCallback;
|
||||
params.userData = this;
|
||||
params.thread.threadAffinity = 0; //Not used in PS3
|
||||
params.thread.threadPriority = 1000; //Must be between [0-3071], being 0 the highest.
|
||||
params.psnTicket = psnTicket;
|
||||
params.psnTicketSize = psnTicketSize;
|
||||
strcpy(params.clientId, CLIENT_ID);
|
||||
params.timeout.connectMs = 30 * 1000; //30 seconds is the default
|
||||
params.timeout.resolveMs = 30 * 1000; //30 seconds is the default
|
||||
params.timeout.receiveMs = 120 * 1000; //120 seconds is the default
|
||||
params.timeout.sendMs = 120 * 1000; //120 seconds is the default
|
||||
params.pool.memPoolSize = 7 * 1024 * 1024;
|
||||
if(m_memPoolBuffer == NULL)
|
||||
m_memPoolBuffer = malloc(params.pool.memPoolSize);
|
||||
params.pool.memPoolBuffer = m_memPoolBuffer;
|
||||
|
||||
// SceRemoteStorageAbortReqParams abortParams;
|
||||
|
||||
ret = sceRemoteStorageInit(params);
|
||||
if(ret >= 0 || ret == SCE_REMOTE_STORAGE_ERROR_ALREADY_INITIALISED)
|
||||
{
|
||||
// abortParams.requestId = ret;
|
||||
//ret = sceRemoteStorageAbort(abortParams);
|
||||
app.DebugPrintf("Session will be created \n");
|
||||
//if(ret >= 0)
|
||||
//{
|
||||
// printf("Session aborted \n");
|
||||
//} else
|
||||
//{
|
||||
// printf("Error aborting session: 0x%x \n", ret);
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("Error creating session: 0x%x \n", ret);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SonyRemoteStorage_PS3::getRemoteFileInfo(SceRemoteStorageStatus* pInfo, CallbackFunc cb, LPVOID lpParam)
|
||||
{
|
||||
m_callbackFunc = cb;
|
||||
m_callbackParam = lpParam;
|
||||
outputGetStatus = pInfo;
|
||||
|
||||
SceRemoteStorageStatusReqParams params;
|
||||
reqId = sceRemoteStorageGetStatus(params, outputGetStatus);
|
||||
m_status = e_getStatusInProgress;
|
||||
|
||||
if(reqId >= 0)
|
||||
{
|
||||
app.DebugPrintf("Get Status request sent \n");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("Error sending Get Status request: 0x%x \n", reqId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void SonyRemoteStorage_PS3::abort()
|
||||
{
|
||||
m_bAborting = true;
|
||||
app.DebugPrintf("Aborting...\n");
|
||||
if(m_bTransferStarted)
|
||||
{
|
||||
app.DebugPrintf("transfer has started so we'll call sceRemoteStorageAbort...\n");
|
||||
|
||||
SceRemoteStorageAbortReqParams params;
|
||||
params.requestId = reqId;
|
||||
int ret = sceRemoteStorageAbort(params);
|
||||
|
||||
if(ret >= 0)
|
||||
{
|
||||
app.DebugPrintf("Abort request done \n");
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("Error in Abort request: 0x%x \n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SonyRemoteStorage_PS3::setDataInternal()
|
||||
{
|
||||
CompressSaveData(); // check if we need to re-save the file compressed first
|
||||
|
||||
|
||||
strcpy(m_saveFilename, m_setDataSaveInfo->UTF8SaveFilename);
|
||||
strcpy(m_saveFileDesc, m_setDataSaveInfo->UTF8SaveTitle);
|
||||
|
||||
|
||||
SceRemoteStorageSetDataReqParams params;
|
||||
params.visibility = PUBLIC_READ_WRITE;
|
||||
strcpy(params.pathLocation, m_saveFilename);
|
||||
sprintf(params.fileName, getRemoteSaveFilename());
|
||||
|
||||
DescriptionData descData;
|
||||
ZeroMemory(&descData, sizeof(DescriptionData));
|
||||
descData.m_platform[0] = SAVE_FILE_PLATFORM_LOCAL & 0xff;
|
||||
descData.m_platform[1] = (SAVE_FILE_PLATFORM_LOCAL >> 8) & 0xff;
|
||||
descData.m_platform[2] = (SAVE_FILE_PLATFORM_LOCAL >> 16) & 0xff;
|
||||
descData.m_platform[3] = (SAVE_FILE_PLATFORM_LOCAL >> 24)& 0xff;
|
||||
|
||||
if(m_thumbnailData)
|
||||
{
|
||||
unsigned int uiHostOptions;
|
||||
bool bHostOptionsRead;
|
||||
DWORD uiTexturePack;
|
||||
char seed[22];
|
||||
app.GetImageTextData(m_thumbnailData, m_thumbnailDataSize,(unsigned char *)seed, uiHostOptions, bHostOptionsRead, uiTexturePack);
|
||||
|
||||
__int64 iSeed = strtoll(seed,NULL,10);
|
||||
char seedHex[17];
|
||||
sprintf(seedHex,"%016llx",iSeed);
|
||||
memcpy(descData.m_seed,seedHex,16); // Don't copy null
|
||||
|
||||
// Save the host options that this world was last played with
|
||||
char hostOptions[9];
|
||||
sprintf(hostOptions,"%08x",uiHostOptions);
|
||||
memcpy(descData.m_hostOptions,hostOptions,8); // Don't copy null
|
||||
|
||||
// Save the texture pack id
|
||||
char texturePack[9];
|
||||
sprintf(texturePack,"%08x",uiTexturePack);
|
||||
memcpy(descData.m_texturePack,texturePack,8); // Don't copy null
|
||||
}
|
||||
|
||||
memcpy(descData.m_saveNameUTF8, m_saveFileDesc, strlen(m_saveFileDesc)+1); // plus null
|
||||
memcpy(params.fileDescription, &descData, sizeof(descData));
|
||||
strcpy(params.ps3DataFilename, "GAMEDATA");
|
||||
|
||||
params.ps3FileType = CELL_SAVEDATA_FILETYPE_NORMALFILE;
|
||||
memcpy(params.secureFileId, m_secureFileId, CELL_SAVEDATA_SECUREFILEID_SIZE);
|
||||
|
||||
|
||||
if(m_bAborting)
|
||||
{
|
||||
runCallback();
|
||||
return false;
|
||||
}
|
||||
reqId = sceRemoteStorageSetData(params);
|
||||
|
||||
app.DebugPrintf("\n*******************************\n");
|
||||
if(reqId >= 0)
|
||||
{
|
||||
app.DebugPrintf("Set Data request sent \n");
|
||||
m_bTransferStarted = true;
|
||||
m_status = e_setDataInProgress;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("Error sending Set Data request: 0x%x \n", reqId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SonyRemoteStorage_PS3::getData( const char* remotePath, const char* localPath, CallbackFunc cb, LPVOID lpParam )
|
||||
{
|
||||
m_callbackFunc = cb;
|
||||
m_callbackParam = lpParam;
|
||||
|
||||
SceRemoteStorageGetDataReqParams params;
|
||||
strcpy(params.pathLocation, localPath);//"ABCD12345-RS-DATA");
|
||||
strcpy(params.fileName, remotePath);//"/test/small.txt");
|
||||
strcpy(params.ps3DataFilename, "GAMEDATA");
|
||||
params.ps3FileType = CELL_SAVEDATA_FILETYPE_NORMALFILE;
|
||||
memcpy(params.secureFileId, m_secureFileId, CELL_SAVEDATA_SECUREFILEID_SIZE);
|
||||
|
||||
reqId = sceRemoteStorageGetData(params, &outputGetData);
|
||||
|
||||
app.DebugPrintf("\n*******************************\n");
|
||||
if(reqId >= 0)
|
||||
{
|
||||
app.DebugPrintf("Get Data request sent \n");
|
||||
m_bTransferStarted = true;
|
||||
m_status = e_getDataInProgress;
|
||||
} else
|
||||
{
|
||||
app.DebugPrintf("Error sending Get Data request: 0x%x \n", reqId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SonyRemoteStorage_PS3::runCallback()
|
||||
{
|
||||
assert(m_callbackFunc);
|
||||
if(m_callbackFunc)
|
||||
{
|
||||
m_callbackFunc(m_callbackParam, m_status, m_lastErrorCode);
|
||||
}
|
||||
m_lastErrorCode = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
int SonyRemoteStorage_PS3::SaveCompressCallback(LPVOID lpParam,bool bRes)
|
||||
{
|
||||
SonyRemoteStorage_PS3* pRS = (SonyRemoteStorage_PS3*)lpParam;
|
||||
pRS->m_compressedSaveState = e_state_Idle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SonyRemoteStorage_PS3::LoadCompressCallback(void *pParam,bool bIsCorrupt, bool bIsOwner)
|
||||
{
|
||||
SonyRemoteStorage_PS3* pRS = (SonyRemoteStorage_PS3*)pParam;
|
||||
int origFilesize = StorageManager.GetSaveSize();
|
||||
void* pOrigSaveData = malloc(origFilesize);
|
||||
unsigned int retFilesize;
|
||||
StorageManager.GetSaveData( pOrigSaveData, &retFilesize );
|
||||
// check if this save file is already compressed
|
||||
if(*((int*)pOrigSaveData) != 0)
|
||||
{
|
||||
app.DebugPrintf("compressing save data\n");
|
||||
|
||||
// Assume that the compression will make it smaller so initially attempt to allocate the current file size
|
||||
// We add 4 bytes to the start so that we can signal compressed data
|
||||
// And another 4 bytes to store the decompressed data size
|
||||
unsigned int compLength = origFilesize+8;
|
||||
byte *compData = (byte *)malloc( compLength );
|
||||
Compression::UseDefaultThreadStorage();
|
||||
Compression::getCompression()->Compress(compData+8,&compLength,pOrigSaveData,origFilesize);
|
||||
ZeroMemory(compData,8);
|
||||
int saveVer = 0;
|
||||
memcpy( compData, &saveVer, sizeof(int) );
|
||||
memcpy( compData+4, &origFilesize, sizeof(int) );
|
||||
|
||||
StorageManager.FreeSaveData();
|
||||
StorageManager.SetSaveData(compData,compLength+8);
|
||||
pRS->m_compressedSaveState = e_state_CompressedSave;
|
||||
}
|
||||
else
|
||||
{
|
||||
// already compressed, do nothing
|
||||
pRS->m_compressedSaveState = e_state_Idle;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SonyRemoteStorage_PS3::CompressSaveData()
|
||||
{
|
||||
app.DebugPrintf("CompressSaveData\n");
|
||||
m_compressedSaveState = e_state_LoadingSave;
|
||||
app.DebugPrintf("Loading save\n");
|
||||
waitForStorageManagerIdle();
|
||||
C4JStorage::ESaveGameState eLoadStatus=StorageManager.LoadSaveData(m_setDataSaveInfo, &LoadCompressCallback, this);
|
||||
if(eLoadStatus != C4JStorage::ESaveGame_Load)
|
||||
{
|
||||
app.DebugPrintf("Failed to load savegame for compression!!!!!!\n");
|
||||
m_compressedSaveState = e_state_Idle;
|
||||
return;
|
||||
}
|
||||
while(m_compressedSaveState == e_state_LoadingSave)
|
||||
{
|
||||
Sleep(10);
|
||||
}
|
||||
if(m_compressedSaveState == e_state_CompressedSave)
|
||||
{
|
||||
|
||||
waitForStorageManagerIdle();
|
||||
app.DebugPrintf("Saving compressed save\n");
|
||||
waitForStorageManagerIdle();
|
||||
StorageManager.SetDefaultSaveImage(); // we can't get the save image back to overwrite, so set it to the default
|
||||
C4JStorage::ESaveGameState storageState = StorageManager.SaveSaveData( &SaveCompressCallback, this, true ); // only save the data file, so we don't overwrite the icon
|
||||
if(storageState == C4JStorage::ESaveGame_Save)
|
||||
{
|
||||
m_compressedSaveState = e_state_SavingSave;
|
||||
while(m_compressedSaveState == e_state_SavingSave)
|
||||
{
|
||||
Sleep(10);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("StorageManager.SaveSaveData failed, save is left uncompressed\n");
|
||||
}
|
||||
}
|
||||
waitForStorageManagerIdle();
|
||||
|
||||
app.DebugPrintf("done\n");
|
||||
assert(m_compressedSaveState == e_state_Idle);
|
||||
}
|
||||
|
||||
64
Minecraft.Client/PS3/Network/SonyRemoteStorage_PS3.h
Normal file
64
Minecraft.Client/PS3/Network/SonyRemoteStorage_PS3.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Common\Network\Sony\sceRemoteStorage\header\sceRemoteStorage.h"
|
||||
|
||||
class SonyRemoteStorage_PS3 : public SonyRemoteStorage
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual bool init(CallbackFunc cb, LPVOID lpParam);
|
||||
|
||||
virtual bool getRemoteFileInfo(SceRemoteStorageStatus* pInfo, CallbackFunc cb, LPVOID lpParam);
|
||||
virtual bool getData(const char* remotePath, const char* localPath, CallbackFunc cb, LPVOID lpParam);
|
||||
|
||||
virtual void abort();
|
||||
virtual bool setDataInternal();
|
||||
|
||||
bool isWaitingForTicket() { return m_waitingForTicket; }
|
||||
void npauthhandler(int event, int result, void *arg);
|
||||
|
||||
void SetSecureID(char* id) { memcpy(m_secureFileId, id, CELL_SAVEDATA_SECUREFILEID_SIZE); }
|
||||
|
||||
void CompressSaveData();
|
||||
bool dataCompressDone() { return (m_compressedSaveState == e_state_Idle);}
|
||||
private:
|
||||
int reqId;
|
||||
void * psnTicket;
|
||||
size_t psnTicketSize;
|
||||
bool m_waitingForTicket;
|
||||
bool initialized;
|
||||
SceRemoteStorageStatus* outputGetStatus;
|
||||
SceRemoteStorageData outputGetData;
|
||||
|
||||
enum CompressSaveState
|
||||
{
|
||||
e_state_LoadingSave,
|
||||
e_state_CompressedSave,
|
||||
e_state_SavingSave,
|
||||
e_state_Idle
|
||||
};
|
||||
|
||||
CompressSaveState m_compressedSaveState;
|
||||
char m_secureFileId[CELL_SAVEDATA_SECUREFILEID_SIZE];
|
||||
|
||||
int32_t m_lastErrorCode;
|
||||
int m_getDataProgress;
|
||||
int m_setDataProgress;
|
||||
char m_saveFilename[SCE_REMOTE_STORAGE_DATA_NAME_MAX_LEN];
|
||||
char m_saveFileDesc[SCE_REMOTE_STORAGE_DATA_DESCRIPTION_MAX_LEN];
|
||||
char m_remoteFilename[SCE_REMOTE_STORAGE_DATA_NAME_MAX_LEN];
|
||||
int initPreconditions();
|
||||
static void staticInternalCallback(const SceRemoteStorageEvent event, int32_t retCode, void * userData);
|
||||
void internalCallback(const SceRemoteStorageEvent event, int32_t retCode);
|
||||
|
||||
virtual void runCallback();
|
||||
|
||||
|
||||
static int SaveCompressCallback(LPVOID lpParam,bool bRes);
|
||||
static int LoadCompressCallback(void *pParam,bool bIsCorrupt, bool bIsOwner);
|
||||
|
||||
|
||||
};
|
||||
|
||||
764
Minecraft.Client/PS3/Network/SonyVoiceChat.cpp
Normal file
764
Minecraft.Client/PS3/Network/SonyVoiceChat.cpp
Normal file
@@ -0,0 +1,764 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/* SCE CONFIDENTIAL
|
||||
PlayStation(R)3 Programmer Tool Runtime Library 430.001
|
||||
* Copyright (C) 2008 Sony Computer Entertainment Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
#include "SonyVoiceChat.h"
|
||||
#include <arpa/inet.h> /* inet_ntoa() */
|
||||
|
||||
/* for displaying extra information */
|
||||
#ifndef _CONTENT_PACKAGE
|
||||
#define AVC2_GAME_DEBUG
|
||||
#endif
|
||||
|
||||
#ifdef AVC2_GAME_DEBUG
|
||||
#define INF(...) printf( "INF:" __VA_ARGS__ )
|
||||
#define ERR(...) printf( "ERR:" __VA_ARGS__ )
|
||||
#else
|
||||
#define INF(...)
|
||||
#define ERR(...)
|
||||
#endif
|
||||
|
||||
#define UNUSED_VARIABLE(x) (void)(x)
|
||||
|
||||
//#define DISABLE_VOICE_CHAT
|
||||
|
||||
static CellSysutilAvc2InitParam g_chat_avc2param;
|
||||
|
||||
EAVCEvent SonyVoiceChat::sm_event = AVC_EVENT_EPSILON;
|
||||
EAVCState SonyVoiceChat::sm_state = AVC_STATE_IDLE;
|
||||
SQRNetworkManager_PS3* SonyVoiceChat::sm_pNetworkManager;
|
||||
bool SonyVoiceChat::sm_bEnabled = true;
|
||||
uint8_t SonyVoiceChat::sm_micStatus = CELL_AVC2_MIC_STATUS_UNKNOWN;
|
||||
bool SonyVoiceChat::sm_bLoaded = false;
|
||||
bool SonyVoiceChat::sm_bUnloading = false;
|
||||
unordered_map<SceNpMatching2RoomMemberId, bool> SonyVoiceChat::sm_bTalkingMap;
|
||||
bool SonyVoiceChat::sm_bCanStart = false;
|
||||
bool SonyVoiceChat::sm_isChatRestricted = false;
|
||||
int SonyVoiceChat::sm_currentBitrate = 28000;
|
||||
|
||||
void SonyVoiceChat::init( SQRNetworkManager_PS3* pNetMan )
|
||||
{
|
||||
if(sm_state != AVC_STATE_IDLE)
|
||||
return;
|
||||
|
||||
sm_pNetworkManager = pNetMan;
|
||||
setState(AVC_STATE_CHAT_INIT);
|
||||
ProfileManager.GetChatAndContentRestrictions(0,false,&sm_isChatRestricted,NULL,NULL);
|
||||
}
|
||||
|
||||
void SonyVoiceChat::shutdown()
|
||||
{
|
||||
if( sm_state == AVC_STATE_IDLE ||
|
||||
sm_state == AVC_STATE_CHAT_LEAVE ||
|
||||
sm_state == AVC_STATE_CHAT_UNLOAD ||
|
||||
sm_state == AVC_STATE_CHAT_RESET )
|
||||
{
|
||||
// we're either shut down already, or in the process
|
||||
return;
|
||||
}
|
||||
|
||||
setEvent(AVC_EVENT_EXIT_GAME);
|
||||
}
|
||||
|
||||
void SonyVoiceChat::setEnabled( bool bEnabled )
|
||||
{
|
||||
if(sm_bEnabled != bEnabled)
|
||||
{
|
||||
if(sm_bCanStart)
|
||||
{
|
||||
if(bEnabled)
|
||||
startStream();
|
||||
else
|
||||
stopStream();
|
||||
}
|
||||
sm_bEnabled = bEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SonyVoiceChat::eventcb_load(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata)
|
||||
{
|
||||
int ret = CELL_OK;
|
||||
|
||||
UNUSED_VARIABLE( event_param );
|
||||
UNUSED_VARIABLE( userdata );
|
||||
|
||||
if( event_id == CELL_AVC2_EVENT_LOAD_SUCCEEDED )
|
||||
{
|
||||
INF( "<AVC CB>CELL_AVC2_EVENT_LOAD_SUCCEEDED(0x%x), param(0x%x)\n", event_id, (int)event_param );
|
||||
setEvent(AVC_EVENT_CHAT_LOAD_SUCCEEDED);
|
||||
sm_bLoaded = true;
|
||||
|
||||
// set the packet contention value here
|
||||
CellSysutilAvc2Attribute attr;
|
||||
memset( &attr, 0x00, sizeof(attr) );
|
||||
attr.attr_id = CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_PACKET_CONTENTION;
|
||||
attr.attr_param.int_param = 3;
|
||||
int ret = cellSysutilAvc2SetAttribute(&attr);
|
||||
if( ret != CELL_OK )
|
||||
{
|
||||
app.DebugPrintf("CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_PACKET_CONTENTION failed !!! 0x%08x\n", ret);
|
||||
}
|
||||
|
||||
}
|
||||
else /* if( event_id == CELL_AVC2_EVENT_LOAD_FAILED ) */
|
||||
{
|
||||
INF( "<AVC CB>CELL_AVC2_EVENT_LOAD_FAILED(0x%x), param(0x%x)\n", event_id, (int)event_param );
|
||||
setEvent(AVC_EVENT_CHAT_LOAD_FAILED);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SonyVoiceChat::eventcb_join(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata)
|
||||
{
|
||||
int ret = CELL_OK;
|
||||
|
||||
UNUSED_VARIABLE( event_param );
|
||||
UNUSED_VARIABLE( userdata );
|
||||
|
||||
if( event_id == CELL_AVC2_EVENT_JOIN_SUCCEEDED )
|
||||
{
|
||||
INF( "<AVC CB>CELL_AVC2_EVENT_JOIN_SUCCEEDED(0x%x), param(0x%x)\n", event_id, (int)event_param );
|
||||
setEvent(AVC_EVENT_CHAT_JOIN_SUCCEEDED);
|
||||
}
|
||||
else /* if( event_id == CELL_AVC2_EVENT_JOIN_FAILED ) */
|
||||
{
|
||||
INF( "<AVC CB>CELL_AVC2_EVENT_JOIN_FAILED(0x%x), param(0x%x)\n", event_id, (int)event_param );
|
||||
setEvent(AVC_EVENT_ERROR);
|
||||
}
|
||||
sm_bTalkingMap.clear();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SonyVoiceChat::eventcb_leave( CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata)
|
||||
{
|
||||
int ret = CELL_OK;
|
||||
|
||||
UNUSED_VARIABLE( event_param );
|
||||
UNUSED_VARIABLE( userdata );
|
||||
|
||||
if( event_id == CELL_AVC2_EVENT_LEAVE_SUCCEEDED )
|
||||
{
|
||||
INF( "<AVC CB>CELL_AVC2_EVENT_LEAVE_SUCCEEDED(0x%x), param(0x%x)\n", event_id, (int)event_param );
|
||||
setState(AVC_STATE_CHAT_LEAVE);
|
||||
setEvent(AVC_EVENT_CHAT_LEAVE_SUCCEEDED);
|
||||
}
|
||||
else /* if( event_id == CELL_AVC2_EVENT_LEAVE_FAILED ) */
|
||||
{
|
||||
INF( "<AVC CB>CELL_AVC2_EVENT_LEAVE_FAILED(0x%x), param(0x%x)\n", event_id, (int)event_param );
|
||||
setState(AVC_STATE_CHAT_LEAVE);
|
||||
setEvent(AVC_EVENT_ERROR);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SonyVoiceChat::eventcb_unload(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata)
|
||||
{
|
||||
int ret = CELL_OK;
|
||||
|
||||
UNUSED_VARIABLE( event_param );
|
||||
UNUSED_VARIABLE( userdata );
|
||||
|
||||
if( event_id == CELL_AVC2_EVENT_UNLOAD_SUCCEEDED )
|
||||
{
|
||||
INF( "<AVC CB>CELL_AVC2_EVENT_UNLOAD_SUCCEEDED(0x%x), param(0x%x)\n", event_id, (int)event_param );
|
||||
setEvent(AVC_EVENT_CHAT_UNLOAD_SUCCEEDED);
|
||||
sm_bLoaded = false;
|
||||
sm_bUnloading = false;
|
||||
}
|
||||
else /* if( event_id == CELL_AVC2_EVENT_UNLOAD_FAILED ) */
|
||||
{
|
||||
INF( "<AVC CB>CELL_AVC2_EVENT_UNLOAD_FAILED(0x%x), param(0x%x)\n", event_id, (int)event_param );
|
||||
setEvent(AVC_EVENT_ERROR);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SonyVoiceChat::eventcb_voiceDetected(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata)
|
||||
{
|
||||
UNUSED_VARIABLE( userdata );
|
||||
|
||||
// To the upper 32 bits, the room member ID of the player is passed.
|
||||
// In the lower 32 bits, a value of 0 (mute) or a value between 1 (low volume)
|
||||
// and 10 (high volume) is passed as the audio signal value when the notification
|
||||
// method is the level method, or a value of 1 (start of speaking) or 0 (end of speaking)
|
||||
// is stored when the notification method is the trigger method.
|
||||
|
||||
SceNpMatching2RoomMemberId roomMemberID = (SceNpMatching2RoomMemberId)(event_param >> 32);
|
||||
uint32_t volume = (uint32_t)(event_param & 0xffffffff);
|
||||
|
||||
// The precision of voice detection is not very high. Since the audio signal values may
|
||||
// always be relatively high depending on the audio input device and the noise level in the
|
||||
// room, you should set a large reference value for determining whether or not a player is
|
||||
// speaking. Relatively good results can be obtained when an audio signal value of at
|
||||
// least 9 is used to determine if a player is speaking.
|
||||
bool bTalking = false;
|
||||
if(volume >= 9)
|
||||
bTalking = true;
|
||||
|
||||
sm_bTalkingMap[roomMemberID] = bTalking;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
/* Callback function for handling AV Chat2 Utility events */
|
||||
void SonyVoiceChat::eventcb( CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata)
|
||||
{
|
||||
static struct _cb_func_tbl
|
||||
{
|
||||
CellSysutilAvc2EventId event;
|
||||
int (*func)( CellSysutilAvc2EventId event_id,
|
||||
CellSysutilAvc2EventParam event_param,
|
||||
void *userdata );
|
||||
} event_tbl[] =
|
||||
{
|
||||
{ CELL_AVC2_EVENT_LOAD_SUCCEEDED, eventcb_load },
|
||||
{ CELL_AVC2_EVENT_LOAD_FAILED, eventcb_load },
|
||||
{ CELL_AVC2_EVENT_JOIN_SUCCEEDED, eventcb_join },
|
||||
{ CELL_AVC2_EVENT_JOIN_FAILED, eventcb_join },
|
||||
{ CELL_AVC2_EVENT_LEAVE_SUCCEEDED, eventcb_leave },
|
||||
{ CELL_AVC2_EVENT_LEAVE_FAILED, eventcb_leave },
|
||||
{ CELL_AVC2_EVENT_UNLOAD_SUCCEEDED, eventcb_unload },
|
||||
{ CELL_AVC2_EVENT_UNLOAD_FAILED, eventcb_unload },
|
||||
{ CELL_AVC2_EVENT_SYSTEM_NEW_MEMBER_JOINED, NULL },
|
||||
{ CELL_AVC2_EVENT_SYSTEM_MEMBER_LEFT, NULL },
|
||||
{ CELL_AVC2_EVENT_SYSTEM_SESSION_ESTABLISHED, NULL },
|
||||
{ CELL_AVC2_EVENT_SYSTEM_SESSION_CANNOT_ESTABLISHED,NULL },
|
||||
{ CELL_AVC2_EVENT_SYSTEM_SESSION_DISCONNECTED, NULL },
|
||||
{ CELL_AVC2_EVENT_SYSTEM_VOICE_DETECTED, eventcb_voiceDetected },
|
||||
|
||||
};
|
||||
|
||||
int ret = 0;
|
||||
for( unsigned int i=0; i<sizeof(event_tbl)/sizeof(struct _cb_func_tbl) ; ++i )
|
||||
{
|
||||
if( event_tbl[ i ].event == event_id && event_tbl[ i ].func )
|
||||
{
|
||||
ret = (*event_tbl[ i ].func)( event_id, event_param, userdata );
|
||||
if( ret < 0 )
|
||||
{
|
||||
ERR("ret=0x%x\n", ret );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int SonyVoiceChat::load()
|
||||
{
|
||||
int ret = CELL_OK;
|
||||
INF("----------------------------\n");
|
||||
INF("| cellSysutilAvc2LoadAsync |\n");
|
||||
INF("----------------------------\n");
|
||||
ret = cellSysutilAvc2LoadAsync( sm_pNetworkManager->m_matchingContext,
|
||||
SYS_MEMORY_CONTAINER_ID_INVALID,
|
||||
eventcb,
|
||||
NULL,
|
||||
&g_chat_avc2param );
|
||||
if( ret != CELL_OK )
|
||||
{
|
||||
ERR( "cellSysutilAvc2LoadAsync: ret=0x%x\n", ret );
|
||||
setEvent(AVC_EVENT_ERROR);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SonyVoiceChat::join()
|
||||
{
|
||||
int ret = CELL_OK;
|
||||
|
||||
INF("---------------------------------------------------\n");
|
||||
INF("| cellSysutilAvc2JoinChatRequest \n");
|
||||
INF("---------------------------------------------------\n");
|
||||
ret = cellSysutilAvc2JoinChatRequest( &sm_pNetworkManager->m_room );
|
||||
if( ret != CELL_OK )
|
||||
{
|
||||
ERR( "cellSysutilAvc2JoinChatRequest: ret=0x%x\n", ret );
|
||||
setEvent(AVC_EVENT_ERROR);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SonyVoiceChat::leave()
|
||||
{
|
||||
int ret = CELL_OK;
|
||||
|
||||
INF("-----------------------------------\n");
|
||||
INF("| cellSysutilAvc2LeaveChatRequest |\n");
|
||||
INF("-----------------------------------\n");
|
||||
ret = cellSysutilAvc2LeaveChatRequest();
|
||||
if( ret != CELL_OK )
|
||||
{
|
||||
ERR( "cellSysutilAvc2LeaveChatRequest() = 0x%x\n", ret );
|
||||
setEvent(AVC_EVENT_ERROR);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SonyVoiceChat::unload()
|
||||
{
|
||||
int ret = CELL_OK;
|
||||
|
||||
INF("------------------------------\n");
|
||||
INF("| cellSysutilAvc2UnloadAsync |\n");
|
||||
INF("------------------------------\n");
|
||||
|
||||
ret = cellSysutilAvc2UnloadAsync();
|
||||
if( ret != CELL_OK )
|
||||
{
|
||||
ERR( "cellSysutilAvcUnloadAsync() = 0x%x\n", ret );
|
||||
setEvent(AVC_EVENT_ERROR);
|
||||
return ret;
|
||||
}
|
||||
sm_bUnloading = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SonyVoiceChat::start()
|
||||
{
|
||||
sm_bCanStart = (sm_isChatRestricted == false);
|
||||
|
||||
int ret = CELL_OK;
|
||||
if(sm_bEnabled)
|
||||
ret = startStream();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SonyVoiceChat::stop()
|
||||
{
|
||||
sm_bCanStart = false;
|
||||
|
||||
int ret = CELL_OK;
|
||||
if(sm_bEnabled)
|
||||
ret = stopStream();
|
||||
|
||||
setEvent(AVC_EVENT_CHAT_SESSION_STOPPED);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SonyVoiceChat::startStream()
|
||||
{
|
||||
int ret = CELL_OK;
|
||||
|
||||
INF("---------------------------------\n");
|
||||
INF("| cellSysutilAvc2StartStreaming |\n");
|
||||
INF("---------------------------------\n");
|
||||
ret = cellSysutilAvc2StartStreaming();
|
||||
if( ret != CELL_OK )
|
||||
{
|
||||
ERR( "cellSysutilAvc2StartStreaming: ret=0x%x\n", ret );
|
||||
}
|
||||
|
||||
ret = cellSysutilAvc2StartVoiceDetection();
|
||||
if( ret != CELL_OK )
|
||||
{
|
||||
ERR( "cellSysutilAvc2StartVoiceDetection: ret=0x%x\n", ret );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SonyVoiceChat::stopStream()
|
||||
{
|
||||
int ret = cellSysutilAvc2StopVoiceDetection();
|
||||
if( ret != CELL_OK )
|
||||
{
|
||||
ERR( "cellSysutilAvc2StopVoiceDetection: ret=0x%x\n", ret );
|
||||
}
|
||||
|
||||
INF("--------------------------------\n");
|
||||
INF("| cellSysutilAvc2StopStreaming |\n");
|
||||
INF("--------------------------------\n");
|
||||
ret = cellSysutilAvc2StopStreaming();
|
||||
if( ret != CELL_OK )
|
||||
{
|
||||
ERR( "cellSysutilAvc2StopStreaming: ret=0x%x\n", ret );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SonyVoiceChat::initialize(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Must use cellSysutilAvc2InitParam() for clearing CellSysutilAvc2InitParam struct*/
|
||||
ret = cellSysutilAvc2InitParam(CELL_SYSUTIL_AVC2_INIT_PARAM_VERSION, &g_chat_avc2param);
|
||||
if( ret != CELL_OK )
|
||||
{
|
||||
ERR( "cellSysutilAvc2InitParam failed (0x%x)\n", ret );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Setting application specific parameters */
|
||||
g_chat_avc2param.media_type = CELL_SYSUTIL_AVC2_VOICE_CHAT;
|
||||
g_chat_avc2param.max_players = AVC2_PARAM_DEFAULT_MAX_PLAYERS;
|
||||
g_chat_avc2param.voice_param.voice_quality = CELL_SYSUTIL_AVC2_VOICE_QUALITY_NORMAL;
|
||||
g_chat_avc2param.voice_param.max_speakers = AVC2_PARAM_DEFAULT_MAX_SPEAKERS;
|
||||
g_chat_avc2param.spu_load_average = 50;
|
||||
g_chat_avc2param.streaming_mode.mode = CELL_SYSUTIL_AVC2_STREAMING_MODE_NORMAL;
|
||||
|
||||
setEvent(AVC_EVENT_CHAT_INIT_SUCCEEDED);
|
||||
setState(AVC_STATE_CHAT_INIT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SonyVoiceChat::finalize(void)
|
||||
{
|
||||
setEvent(AVC_EVENT_CHAT_FINALIZE_SUCCEEDED);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
void SonyVoiceChat::tick()
|
||||
{
|
||||
#ifdef DISABLE_VOICE_CHAT
|
||||
return;
|
||||
#endif
|
||||
|
||||
static state_transition_table tbl[] =
|
||||
{
|
||||
/* now state event func after the transition state */
|
||||
{ AVC_STATE_CHAT_INIT, AVC_EVENT_EPSILON, initialize, AVC_STATE_CHAT_INIT },
|
||||
{ AVC_STATE_CHAT_INIT, AVC_EVENT_EXIT_GAME, invoke_epsilon_event, AVC_STATE_CHAT_RESET },
|
||||
{ AVC_STATE_CHAT_INIT, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_RESET },
|
||||
{ AVC_STATE_CHAT_INIT, AVC_EVENT_LAN_DISCONNECT, invoke_epsilon_event, AVC_STATE_CHAT_RESET },
|
||||
{ AVC_STATE_CHAT_INIT, AVC_EVENT_LAN_DISCONNECT, invoke_epsilon_event, AVC_STATE_CHAT_RESET },
|
||||
{ AVC_STATE_CHAT_INIT, AVC_EVENT_CHAT_INIT_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_LOAD },
|
||||
{ AVC_STATE_CHAT_INIT, AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT,invoke_epsilon_event, AVC_STATE_CHAT_RESET },
|
||||
|
||||
{ AVC_STATE_CHAT_LOAD, AVC_EVENT_EPSILON, load, AVC_STATE_CHAT_LOAD },
|
||||
{ AVC_STATE_CHAT_LOAD, AVC_EVENT_EXIT_GAME, invoke_epsilon_event, AVC_STATE_CHAT_RESET },
|
||||
{ AVC_STATE_CHAT_LOAD, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_RESET },
|
||||
{ AVC_STATE_CHAT_LOAD, AVC_EVENT_LAN_DISCONNECT, invoke_epsilon_event, AVC_STATE_CHAT_RESET },
|
||||
{ AVC_STATE_CHAT_LOAD, AVC_EVENT_CHAT_LOAD_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_JOIN },
|
||||
{ AVC_STATE_CHAT_LOAD, AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT,invoke_epsilon_event, AVC_STATE_CHAT_RESET },
|
||||
|
||||
{ AVC_STATE_CHAT_JOIN, AVC_EVENT_EPSILON, join, AVC_STATE_CHAT_JOIN },
|
||||
{ AVC_STATE_CHAT_JOIN, AVC_EVENT_EXIT_GAME, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD },
|
||||
{ AVC_STATE_CHAT_JOIN, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD },
|
||||
{ AVC_STATE_CHAT_JOIN, AVC_EVENT_LAN_DISCONNECT, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD },
|
||||
{ AVC_STATE_CHAT_JOIN, AVC_EVENT_CHAT_JOIN_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_SESSION_PROCESSING },
|
||||
{ AVC_STATE_CHAT_JOIN, AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT,invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD },
|
||||
|
||||
{ AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_EPSILON, start, AVC_STATE_CHAT_SESSION_PROCESSING },
|
||||
{ AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_EXIT_GAME, stop, AVC_STATE_CHAT_SESSION_PROCESSING },
|
||||
{ AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_ERROR, stop, AVC_STATE_CHAT_SESSION_PROCESSING },
|
||||
{ AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_LAN_DISCONNECT, stop, AVC_STATE_CHAT_SESSION_PROCESSING },
|
||||
{ AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_CHAT_SESSION_STOPPED, invoke_epsilon_event, AVC_STATE_CHAT_LEAVE },
|
||||
{ AVC_STATE_CHAT_SESSION_PROCESSING,AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT,stop, AVC_STATE_CHAT_SESSION_PROCESSING },
|
||||
|
||||
{ AVC_STATE_CHAT_LEAVE, AVC_EVENT_EPSILON, leave, AVC_STATE_CHAT_LEAVE },
|
||||
{ AVC_STATE_CHAT_LEAVE, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD },
|
||||
{ AVC_STATE_CHAT_LEAVE, AVC_EVENT_CHAT_LEAVE_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_UNLOAD },
|
||||
|
||||
{ AVC_STATE_CHAT_UNLOAD, AVC_EVENT_EPSILON, unload, AVC_STATE_CHAT_UNLOAD },
|
||||
{ AVC_STATE_CHAT_UNLOAD, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_RESET },
|
||||
{ AVC_STATE_CHAT_UNLOAD, AVC_EVENT_CHAT_UNLOAD_SUCCEEDED, invoke_epsilon_event, AVC_STATE_CHAT_RESET },
|
||||
|
||||
{ AVC_STATE_CHAT_RESET, AVC_EVENT_EPSILON, finalize, AVC_STATE_CHAT_RESET },
|
||||
{ AVC_STATE_CHAT_RESET, AVC_EVENT_ERROR, invoke_epsilon_event, AVC_STATE_CHAT_LEAVE },
|
||||
{ AVC_STATE_CHAT_RESET, AVC_EVENT_CHAT_FINALIZE_SUCCEEDED, invoke_epsilon_event, AVC_STATE_IDLE },
|
||||
|
||||
};
|
||||
do_state_transition( &tbl[0], sizeof( tbl ) / sizeof( state_transition_table ) );
|
||||
|
||||
setBitRate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SonyVoiceChat::do_state_transition( state_transition_table *tbl, int tbl_size )
|
||||
{
|
||||
int ret = CELL_OK;
|
||||
|
||||
// if( sm_event == AVC_EVENT_LAN_DISCONNECT ||
|
||||
// sm_event == AVC_EVENT_EXIT_GAME ||
|
||||
// sm_event == AVC_EVENT_ERROR ||
|
||||
// sm_event == AVC_EVENT_FATAL_ERROR )
|
||||
// {
|
||||
// g_gamedata.finalize = 1;
|
||||
// }
|
||||
// if( sm_event == AVC_EVENT_FATAL_ERROR )
|
||||
// {
|
||||
// g_gamedata.exit = true;
|
||||
// }
|
||||
bool bCalledFunc = false;
|
||||
for( int i = 0; i < tbl_size; i++ )
|
||||
{
|
||||
if( sm_state == ( tbl + i )->state )
|
||||
{
|
||||
if( sm_event == ( tbl + i )->event )
|
||||
{
|
||||
sm_event = AVC_EVENT_NON;
|
||||
ret = (*( tbl + i )->func)();
|
||||
bCalledFunc = true;
|
||||
if( ret != CELL_OK )
|
||||
{
|
||||
ERR("ret = 0x%x\n", ret );
|
||||
}
|
||||
|
||||
setState(( tbl + i )->new_state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bCalledFunc == false)
|
||||
{
|
||||
assert( (sm_event == AVC_EVENT_NON) ||
|
||||
(sm_state == AVC_STATE_IDLE && sm_event == AVC_EVENT_EPSILON) );
|
||||
}
|
||||
}
|
||||
|
||||
int SonyVoiceChat::invoke_epsilon_event(void)
|
||||
{
|
||||
setEvent(AVC_EVENT_EPSILON);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
bool SonyVoiceChat::hasMicConnected(const SceNpMatching2RoomMemberId *players_id)
|
||||
{
|
||||
CellSysutilAvc2PlayerInfo players_info;
|
||||
int err = cellSysutilAvc2GetPlayerInfo(players_id, &players_info);
|
||||
if(err == CELL_OK)
|
||||
{
|
||||
if(players_info.connected && players_info.joined)
|
||||
{
|
||||
if(players_info.mic_attached == CELL_AVC2_MIC_STATUS_ATTACHED_ON)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SonyVoiceChat::mute( bool bMute )
|
||||
{
|
||||
if(sm_bLoaded && !sm_bUnloading)
|
||||
{
|
||||
int err = cellSysutilAvc2SetVoiceMuting(bMute);
|
||||
assert(err == CELL_OK);
|
||||
}
|
||||
}
|
||||
|
||||
void SonyVoiceChat::mutePlayer( const SceNpMatching2RoomMemberId member_id, bool bMute ) /*Turn chat audio from a specified player on or off */
|
||||
{
|
||||
if(sm_bLoaded && !sm_bUnloading)
|
||||
{
|
||||
int err = cellSysutilAvc2SetPlayerVoiceMuting(member_id, bMute);
|
||||
assert(err == CELL_OK);
|
||||
}
|
||||
}
|
||||
|
||||
void SonyVoiceChat::muteLocalPlayer( bool bMute ) /*Turn microphone input on or off */
|
||||
{
|
||||
if(sm_bLoaded && !sm_bUnloading)
|
||||
{
|
||||
int err = cellSysutilAvc2SetVoiceMuting(bMute);
|
||||
assert(err == CELL_OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SonyVoiceChat::isMuted()
|
||||
{
|
||||
if(sm_bLoaded && !sm_bUnloading)
|
||||
{
|
||||
uint8_t bMute;
|
||||
int err = cellSysutilAvc2GetVoiceMuting(&bMute);
|
||||
assert(err == CELL_OK);
|
||||
return bMute;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SonyVoiceChat::isMutedPlayer( const SceNpMatching2RoomMemberId member_id)
|
||||
{
|
||||
if(sm_bLoaded && !sm_bUnloading)
|
||||
{
|
||||
uint8_t bMute;
|
||||
int err = cellSysutilAvc2GetPlayerVoiceMuting(member_id, &bMute);
|
||||
assert(err == CELL_OK);
|
||||
return bMute;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SonyVoiceChat::isMutedLocalPlayer()
|
||||
{
|
||||
if(sm_bLoaded && !sm_bUnloading)
|
||||
{
|
||||
uint8_t bMute;
|
||||
int err = cellSysutilAvc2GetVoiceMuting(&bMute);
|
||||
assert(err == CELL_OK);
|
||||
return bMute;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SonyVoiceChat::setVolume( float vol )
|
||||
{
|
||||
if(sm_bLoaded && !sm_bUnloading)
|
||||
{
|
||||
// The volume level can be set to a value in the range 0.0 to 40.0.
|
||||
// Volume levels are linear values such that if 1.0 is specified, the
|
||||
// volume level will be 1 times the reference power (0dB), and if 0.5
|
||||
// is specified, the volume level will be 0.5 times the reference power
|
||||
// (-6dB). If 0.0 is specified, chat audio will no longer be audible.
|
||||
|
||||
int err =cellSysutilAvc2SetSpeakerVolumeLevel(vol * 40.0f);
|
||||
assert(err==CELL_OK);
|
||||
}
|
||||
}
|
||||
|
||||
float SonyVoiceChat::getVolume()
|
||||
{
|
||||
if(sm_bLoaded && !sm_bUnloading)
|
||||
{
|
||||
float vol;
|
||||
int err = cellSysutilAvc2GetSpeakerVolumeLevel(&vol);
|
||||
assert(err == CELL_OK);
|
||||
return (vol / 40.0f);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SonyVoiceChat::isTalking( SceNpMatching2RoomMemberId* players_id )
|
||||
{
|
||||
AUTO_VAR(it, sm_bTalkingMap.find(*players_id));
|
||||
if (it != sm_bTalkingMap.end() )
|
||||
return it->second;
|
||||
return false;
|
||||
}
|
||||
|
||||
void SonyVoiceChat::setBitRate()
|
||||
{
|
||||
if(sm_state != AVC_STATE_CHAT_SESSION_PROCESSING)
|
||||
return;
|
||||
|
||||
int numPlayers = sm_pNetworkManager->GetPlayerCount();
|
||||
// This internal attribute represents the maximum voice bit rate. attr_param
|
||||
// is an integer value. The units are bps, and the specifiable values are
|
||||
// 4000, 8000, 16000, 20000, 24000, and 28000. The initial value is 28000.
|
||||
|
||||
static int bitRates[8] = { 28000, 28000,
|
||||
28000, 28000,
|
||||
24000, 20000,
|
||||
16000, 16000};
|
||||
int bitRate = bitRates[numPlayers-1];
|
||||
if(bitRate == sm_currentBitrate)
|
||||
return;
|
||||
|
||||
CellSysutilAvc2Attribute attr;
|
||||
memset( &attr, 0x00, sizeof(attr) );
|
||||
attr.attr_id = CELL_SYSUTIL_AVC2_ATTRIBUTE_VOICE_MAX_BITRATE;
|
||||
attr.attr_param.int_param = bitRate;
|
||||
int ret = cellSysutilAvc2SetAttribute(&attr);
|
||||
if( ret == CELL_OK )
|
||||
{
|
||||
sm_currentBitrate = bitRate;
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("SonyVoiceChat::setBitRate failed !!! 0x%08x\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define CASE_STR_VALUE(s) case s: return #s;
|
||||
|
||||
const char* getStateString(EAVCState state)
|
||||
{
|
||||
|
||||
switch(state)
|
||||
{
|
||||
|
||||
CASE_STR_VALUE(AVC_STATE_IDLE);
|
||||
CASE_STR_VALUE(AVC_STATE_CHAT_INIT)
|
||||
CASE_STR_VALUE(AVC_STATE_CHAT_LOAD);
|
||||
CASE_STR_VALUE(AVC_STATE_CHAT_JOIN);
|
||||
CASE_STR_VALUE(AVC_STATE_CHAT_SESSION_PROCESSING);
|
||||
CASE_STR_VALUE(AVC_STATE_CHAT_LEAVE);
|
||||
CASE_STR_VALUE(AVC_STATE_CHAT_RESET);
|
||||
CASE_STR_VALUE(AVC_STATE_CHAT_UNLOAD);
|
||||
CASE_STR_VALUE(AVC_STATE_EXIT);
|
||||
default:
|
||||
return "unknown state";
|
||||
}
|
||||
}
|
||||
|
||||
const char* getEventString(EAVCEvent state)
|
||||
{
|
||||
switch(state)
|
||||
{
|
||||
CASE_STR_VALUE(AVC_EVENT_NON);
|
||||
CASE_STR_VALUE(AVC_EVENT_EPSILON);
|
||||
CASE_STR_VALUE(AVC_EVENT_LAN_DISCONNECT);
|
||||
CASE_STR_VALUE(AVC_EVENT_ONLINE);
|
||||
CASE_STR_VALUE(AVC_EVENT_OFFLINE);
|
||||
CASE_STR_VALUE(AVC_EVENT_EXIT_GAME);
|
||||
CASE_STR_VALUE(AVC_EVENT_ROOM_CREATE);
|
||||
CASE_STR_VALUE(AVC_EVENT_ROOM_SEARCH);
|
||||
CASE_STR_VALUE(AVC_EVENT_ERROR);
|
||||
CASE_STR_VALUE(AVC_EVENT_FATAL_ERROR);
|
||||
CASE_STR_VALUE(AVC_EVENT_NETDIALOG_FINISHED);
|
||||
CASE_STR_VALUE(AVC_EVENT_NETDIALOG_UNLOADED);
|
||||
CASE_STR_VALUE(AVC_EVENT_NP2_INIT_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_NP2_FINALIZE_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_NP2_START_CONTEXT_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_NP2_STOP_CONTEXT_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT);
|
||||
CASE_STR_VALUE(AVC_EVENT_NP2_ROOM_MEMBER_LEFT);
|
||||
CASE_STR_VALUE(AVC_EVENT_NP2_ROOM_MEMBER_JOINED);
|
||||
CASE_STR_VALUE(AVC_EVENT_CHAT_LOAD_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_CHAT_LOAD_FAILED);
|
||||
CASE_STR_VALUE(AVC_EVENT_CHAT_JOIN_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_CHAT_JOIN_FAILED);
|
||||
CASE_STR_VALUE(AVC_EVENT_CHAT_LEAVE_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_CHAT_LEAVE_FAILED);
|
||||
CASE_STR_VALUE(AVC_EVENT_CHAT_UNLOAD_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_CHAT_UNLOAD_FAILED);
|
||||
CASE_STR_VALUE(AVC_EVENT_CHAT_INIT_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_CHAT_FINALIZE_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_CHAT_SESSION_STOPPED);
|
||||
CASE_STR_VALUE(AVC_EVENT_CREATE_JOIN_ROOM_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_SEARCH_ROOM_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_JOIN_ROOM_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_LEAVE_ROOM_SUCCEEDED);
|
||||
CASE_STR_VALUE(AVC_EVENT_SIGNALING_ESTABLISHED);
|
||||
CASE_STR_VALUE(AVC_EVENT_SIGNALING_DEAD);
|
||||
CASE_STR_VALUE(AVC_EVENT_UI_CLOSE_SUCCEEDED);
|
||||
default:
|
||||
return "unknown event";
|
||||
}
|
||||
}
|
||||
|
||||
void SonyVoiceChat::printStateAndEvent()
|
||||
{
|
||||
app.DebugPrintf("============== State %20s, Event %20s\n", getStateString(sm_state), getEventString(sm_event));
|
||||
}
|
||||
|
||||
|
||||
void SonyVoiceChat::setEvent( EAVCEvent event )
|
||||
{
|
||||
sm_event = event;
|
||||
printStateAndEvent();
|
||||
}
|
||||
|
||||
void SonyVoiceChat::setState( EAVCState state )
|
||||
{
|
||||
sm_state = state;
|
||||
printStateAndEvent();
|
||||
}
|
||||
157
Minecraft.Client/PS3/Network/SonyVoiceChat.h
Normal file
157
Minecraft.Client/PS3/Network/SonyVoiceChat.h
Normal file
@@ -0,0 +1,157 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cell/sysmodule.h>
|
||||
#include <sys/process.h>
|
||||
#include <sysutil/sysutil_avc2.h> /* for using AV Chat2 Utility */
|
||||
#include <np.h> /* for using NP Matching */
|
||||
#include <netex/net.h>
|
||||
#include <netex/libnetctl.h>
|
||||
#include <sysutil/sysutil_sysparam.h>
|
||||
|
||||
|
||||
#define AVC2_PARAM_DEFAULT_MAX_PLAYERS (8)
|
||||
#define AVC2_PARAM_DEFAULT_MAX_SPEAKERS (4)
|
||||
|
||||
/* state list */
|
||||
enum EAVCState
|
||||
{
|
||||
AVC_STATE_IDLE = 0,
|
||||
|
||||
AVC_STATE_CHAT_INIT,
|
||||
AVC_STATE_CHAT_LOAD,
|
||||
AVC_STATE_CHAT_JOIN,
|
||||
AVC_STATE_CHAT_SESSION_PROCESSING,
|
||||
AVC_STATE_CHAT_LEAVE,
|
||||
AVC_STATE_CHAT_RESET,
|
||||
AVC_STATE_CHAT_UNLOAD,
|
||||
|
||||
AVC_STATE_EXIT,
|
||||
};
|
||||
/* event list */
|
||||
enum EAVCEvent
|
||||
{
|
||||
AVC_EVENT_NON = AVC_STATE_EXIT + 1,
|
||||
|
||||
AVC_EVENT_EPSILON,
|
||||
AVC_EVENT_LAN_DISCONNECT,
|
||||
AVC_EVENT_ONLINE,
|
||||
AVC_EVENT_OFFLINE,
|
||||
AVC_EVENT_EXIT_GAME,
|
||||
AVC_EVENT_ROOM_CREATE,
|
||||
AVC_EVENT_ROOM_SEARCH,
|
||||
AVC_EVENT_ERROR,
|
||||
AVC_EVENT_FATAL_ERROR,
|
||||
AVC_EVENT_NETDIALOG_FINISHED,
|
||||
AVC_EVENT_NETDIALOG_UNLOADED,
|
||||
AVC_EVENT_NP2_INIT_SUCCEEDED,
|
||||
AVC_EVENT_NP2_FINALIZE_SUCCEEDED,
|
||||
AVC_EVENT_NP2_START_CONTEXT_SUCCEEDED,
|
||||
AVC_EVENT_NP2_STOP_CONTEXT_SUCCEEDED,
|
||||
AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT,
|
||||
AVC_EVENT_NP2_ROOM_MEMBER_LEFT,
|
||||
AVC_EVENT_NP2_ROOM_MEMBER_JOINED,
|
||||
AVC_EVENT_CHAT_LOAD_SUCCEEDED,
|
||||
AVC_EVENT_CHAT_LOAD_FAILED,
|
||||
AVC_EVENT_CHAT_JOIN_SUCCEEDED,
|
||||
AVC_EVENT_CHAT_JOIN_FAILED,
|
||||
AVC_EVENT_CHAT_LEAVE_SUCCEEDED,
|
||||
AVC_EVENT_CHAT_LEAVE_FAILED,
|
||||
AVC_EVENT_CHAT_UNLOAD_SUCCEEDED,
|
||||
AVC_EVENT_CHAT_UNLOAD_FAILED,
|
||||
AVC_EVENT_CHAT_INIT_SUCCEEDED,
|
||||
AVC_EVENT_CHAT_FINALIZE_SUCCEEDED,
|
||||
AVC_EVENT_CHAT_SESSION_STOPPED,
|
||||
AVC_EVENT_CREATE_JOIN_ROOM_SUCCEEDED,
|
||||
AVC_EVENT_SEARCH_ROOM_SUCCEEDED,
|
||||
AVC_EVENT_JOIN_ROOM_SUCCEEDED,
|
||||
AVC_EVENT_LEAVE_ROOM_SUCCEEDED,
|
||||
AVC_EVENT_SIGNALING_ESTABLISHED,
|
||||
AVC_EVENT_SIGNALING_DEAD,
|
||||
AVC_EVENT_UI_CLOSE_SUCCEEDED,
|
||||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int state;
|
||||
int event;
|
||||
int (*func)(void);
|
||||
EAVCState new_state;
|
||||
} state_transition_table;
|
||||
|
||||
|
||||
class SonyVoiceChat
|
||||
{
|
||||
public:
|
||||
|
||||
static void init(SQRNetworkManager_PS3* pNetMan);
|
||||
static void shutdown();
|
||||
static void tick();
|
||||
static void setEnabled(bool bEnabled);
|
||||
static bool hasMicConnected(const SceNpMatching2RoomMemberId *players_id);
|
||||
static bool isTalking(SceNpMatching2RoomMemberId* players_id);
|
||||
static void mute(bool bMute); //Turn chat audio on or off
|
||||
static void mutePlayer(const SceNpMatching2RoomMemberId member_id, bool bMute); //Turn chat audio from a specified player on or off;
|
||||
static void muteLocalPlayer(bool bMute); //Turn microphone input on or off;
|
||||
|
||||
static bool isMuted();
|
||||
static bool isMutedPlayer(const SceNpMatching2RoomMemberId member_id);
|
||||
static bool isMutedLocalPlayer(); //Turn microphone input on or off;
|
||||
|
||||
static void setVolume(float vol); // 0.0f - 1.0f range
|
||||
static float getVolume(); // 0.0f - 1.0f range
|
||||
|
||||
static bool isShuttingDown() { return (sm_state == AVC_STATE_CHAT_LEAVE || sm_state == AVC_STATE_CHAT_UNLOAD || AVC_STATE_CHAT_RESET); }
|
||||
static void signalRoomDestroyed() { if(!isShuttingDown()) sm_event = AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT;}
|
||||
static void signalRoomKickedOut() { if(!isShuttingDown()) sm_event = AVC_EVENT_NP2_ROOM_DESTROY_OR_KICKEDOUT;}
|
||||
static void signalDisconnected() { if(!isShuttingDown()) sm_event = AVC_EVENT_LAN_DISCONNECT;}
|
||||
private:
|
||||
// static np2_matching2_info sm_matchingInfo;
|
||||
static EAVCEvent sm_event;
|
||||
static EAVCState sm_state;
|
||||
static SQRNetworkManager_PS3* sm_pNetworkManager;
|
||||
static bool sm_bEnabled;
|
||||
static uint8_t sm_micStatus;
|
||||
static bool sm_bLoaded;
|
||||
static bool sm_bUnloading;
|
||||
static unordered_map<SceNpMatching2RoomMemberId, bool> sm_bTalkingMap;
|
||||
static bool sm_bCanStart; // set to true on init, false on disconnect, used to see if we should start after a re-enable
|
||||
static bool sm_isChatRestricted; // true if the parental controls have been set on the main users account
|
||||
static int sm_currentBitrate;
|
||||
static int eventcb_load(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata);
|
||||
static int eventcb_join(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata);
|
||||
static int eventcb_leave( CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata);
|
||||
static int eventcb_unload(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata);
|
||||
static int eventcb_voiceDetected(CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata);
|
||||
static void eventcb( CellSysutilAvc2EventId event_id, CellSysutilAvc2EventParam event_param, void *userdata);
|
||||
|
||||
static int initialize();
|
||||
static int finalize();
|
||||
|
||||
static int load();
|
||||
static int unload();
|
||||
|
||||
static int join();
|
||||
static int leave();
|
||||
|
||||
static int start();
|
||||
static int stop();
|
||||
|
||||
static int startStream();
|
||||
static int stopStream();
|
||||
// static int update_target();
|
||||
|
||||
static void do_state_transition( state_transition_table *tbl, int tbl_size);
|
||||
static int invoke_epsilon_event();
|
||||
|
||||
static void setBitRate();
|
||||
|
||||
static void setEvent(EAVCEvent event);
|
||||
static void setState(EAVCState state);
|
||||
static void printStateAndEvent();
|
||||
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user