//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // UDP Layer must be initialized // When a message handler is done or shutting down, the message handler should remove // itself from the UDP Layer // The header cannot be empty GSUdpErrorCode gsUdpEngineRemoveMsgHandler(char theHeader[GS_UDP_MSG_HEADER_LEN]) { GSUdpEngineObject *aUdp = gsUdpEngineGetEngine(); GSUdpMsgHandler aHandler; int index; GS_ASSERT(aUdp->mInitialized); GS_ASSERT(theHeader); if (!aUdp->mInitialized) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug, "[Udp Engine] Engine not initialized\n"); return GS_UDP_NETWORK_ERROR; } if (!theHeader || !theHeader[0]) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug, "[Udp Engine] invalid or empty header\n"); return GS_UDP_PARAMETER_ERROR; } memcpy(aHandler.mHeader, theHeader, GS_UDP_MSG_HEADER_LEN); index = ArraySearch(aUdp->mMsgHandlers, &aHandler, gsUdpMsgHandlerCompare2, 0, 0); if (index != NOT_FOUND) { ArrayDeleteAt(aUdp->mMsgHandlers, index); } return GS_UDP_NO_ERROR; }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // UDP Layer must be initialized // theIp and thePort cannot be 0 (Zero) // Rejects a Peer's request for communication // Should only be used by App GSUdpErrorCode gsUdpEngineRejectPeer(unsigned int theIp, unsigned short thePort) { GSUdpRemotePeer aRemotePeer; GSUdpEngineObject *aUdp = gsUdpEngineGetEngine(); int index; GS_ASSERT(aUdp->mInitialized); GS_ASSERT(theIp); GS_ASSERT(thePort); if (!aUdp->mInitialized) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug, "[Udp Engine] Engine not initialized\n"); return GS_UDP_NETWORK_ERROR; } if (theIp == 0 || thePort == 0) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug, "[Udp Engine] Invalid parameter(s), check ip, port\n"); return GS_UDP_PARAMETER_ERROR; } // Find the connection to reject in our array of peers aRemotePeer.mAddr = theIp; aRemotePeer.mPort = thePort; index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0); if (index != NOT_FOUND) { GSUdpRemotePeer *aPeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index); gt2Reject(aPeerFound->mConnection, NULL, 0); ArrayDeleteAt(aUdp->mRemotePeers, index); } return GS_UDP_NO_ERROR; }
void gpiPeerAcceptedCallback(unsigned int ip, unsigned short port, GSUdpErrorCode error, gsi_bool rejected, void *userData) { GPConnection *connection = (GPConnection *)userData; GPIPeer *aPeer; IN_ADDR anAddr; anAddr.s_addr = ip; aPeer = gpiGetPeerByAddr(connection, ip, port); if (!aPeer) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_HotError, "Peer does not exist: ip-port: %s:%d\n", inet_ntoa(anAddr), port); } else { if (rejected) { aPeer->state = GPI_PEER_DISCONNECTED; gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_Notice, "Peer Connection rejected: ip-port: %s:%d\n", inet_ntoa(anAddr), port); return; } } gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Network, GSIDebugLevel_Notice, "Peer Connection accepted: ip-port: %s:%d\n", inet_ntoa(anAddr), port); GSI_UNUSED(userData); GSI_UNUSED(rejected); GSI_UNUSED(error); GSI_UNUSED(anAddr); }
// gpiPeerAddOp notes: // Assumes non-null inputs! // The queue should be empty when the first element is added. // Any new element added will be added to the end of the queue. void gpiPeerAddOp(GPIPeer *peer, GPIPeerOp *operation) { GS_ASSERT(peer); GS_ASSERT(operation); if (!peer || !operation) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_WarmError, "Peer operation not added"); return; } // Three cases can occur: // The list is empty - set all pointers to the new node // The list has only one element - set the first element's next to the new // and set the last element to the new // The list has more than one element - add the new element to the end of // the queue if (peer->peerOpQueue.opList == NULL) { peer->peerOpQueue.first = operation; peer->peerOpQueue.last = operation; peer->peerOpQueue.opList = operation; } else if (peer->peerOpQueue.first == peer->peerOpQueue.last) { peer->peerOpQueue.first->next = operation; peer->peerOpQueue.last = operation; } else { peer->peerOpQueue.last->next = operation; peer->peerOpQueue.last = operation; } gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_Notice, "Peer Operation Added"); }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Pings are passed on to higher level app or message handlers void gsUdpPingRoutingCB(GT2Connection theConnection, int theLatency) { GSUdpEngineObject *aUdp = gsUdpEngineGetEngine(); int index, len; char anAddr[GS_IP_ADDR_AND_PORT]; gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, "[Udp Engine] Received ping from %s\n", gt2AddressToString(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), anAddr)); len = ArrayLength(aUdp->mMsgHandlers); for (index = 0; index < len; index++) { GSUdpMsgHandler *aHandler = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, index); if (aHandler->mPingReply) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, "[Udp Engine] Passed to message handler\n"); aHandler->mPingReply(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), (unsigned int)theLatency, aHandler->mUserData); return; } } if (aUdp->mAppPingReply) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, "[Udp Engine] Passed to app\n"); aUdp->mAppPingReply(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), (unsigned int)theLatency, aUdp->mAppUserData); } GSI_UNUSED(anAddr); }
/////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // This will be triggered when scCreateSession() has completed. // Expected to occur once per reported game session. void createSessionCallback(SCInterfacePtr theInterface, GHTTPResult theHttpResult, SCResult theResult, void * theUserData) { gsDebugFormat(GSIDebugCat_App, GSIDebugType_Misc, GSIDebugLevel_Notice, "CreateSessionCallback: theHttpResult = %d, theResult = %s\r\n", theHttpResult, SCResultStr[theResult]); if (theHttpResult == GHTTPSuccess && theResult == SCResult_NO_ERROR) { const char * sessionId = scGetSessionId(theInterface); const char * connectionId = scGetConnectionId(theInterface); gsDebugFormat(GSIDebugCat_App, GSIDebugType_Misc, GSIDebugLevel_Debug, "Session ID: %s\r\n", sessionId); gsDebugFormat(GSIDebugCat_App, GSIDebugType_Misc, GSIDebugLevel_Debug, "Connection ID: %s\r\n", connectionId); GSI_UNUSED(sessionId); GSI_UNUSED(connectionId); } gServerData.mWaitCount--; // one less request to wait for GSI_UNUSED(theInterface); GSI_UNUSED(theUserData); }
static void myPlayerLogin(gsi_u8 logintype, const gsi_char * nick, const gsi_char * password, int localPlayerNumber) { gsi_u32 result; if (logintype == SCTEST_LOGIN_PROFILE) { if (0 != wsLoginProfile(SCTEST_LOGIN_PARTNERCODE, SCTEST_LOGIN_NAMESPACE, nick, SCTEST_EMAIL, password, _T(""), myLoginCallback, (void*)localPlayerNumber)) { gsDebugFormat(GSIDebugCat_App, GSIDebugType_Misc, GSIDebugLevel_HotError, "Failed on wsLoginProfile\r\n"); getc(stdin); exit(0); } } else if (logintype == SCTEST_LOGIN_UNIQUE) { result = wsLoginUnique(SCTEST_LOGIN_PARTNERCODE, SCTEST_LOGIN_NAMESPACE, nick, password, _T(""), myLoginCallback, (void*)localPlayerNumber); if (result != WSLogin_Success) { gsDebugFormat(GSIDebugCat_App, GSIDebugType_Misc, GSIDebugLevel_HotError, "Failed on wsLoginUnique. Result: %d\r\n", result); getc(stdin); exit(0); } } else if (logintype == SCTEST_LOGIN_REMOTEAUTH) { result = wsLoginRemoteAuth(SCTEST_REMOTE_PARTNERCODE, SCTEST_REMOTE_NAMESPACEID, nick, password, myLoginCallback, (void*)localPlayerNumber); if (result != WSLogin_Success) { gsDebugFormat(GSIDebugCat_App, GSIDebugType_Misc, GSIDebugLevel_HotError, "Failed on wsLoginUnique. Result: %d\r\n", result); getc(stdin); exit(0); } } /*result = wsLoginPs3Cert(0, 19, 28, "IQAAAAAAAPAwAACkAAgAFJM+TMa5EdVMnN4uVUeVHCBFZWMTAAEABAAAAAEABwAIAAABDNXa36MABwAIAAABDNXtLXAAAgAIMkQh9jjX3f0ABAAgZ3NpLXNuYWRlcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEdXMAAQAEAARhMAAAAAgAGFNDRUktWFgtWFRDTTAwMDAzLTAwAAAAAAABAARqAAAAAAAAAAAAAAAwAgBEAAgABFoOxO8ACAA4MDUCGQDoMjq/8ZeDFo0Bdo7FPBmAFoWLEzJHbRgCGGX88UQim5OJqDzp7N048ZBmjZcS7xP0dQA=", strlen("IQAAAAAAAPAwAACkAAgAFJM+TMa5EdVMnN4uVUeVHCBFZWMTAAEABAAAAAEABwAIAAABDNXa36MABwAIAAABDNXtLXAAAgAIMkQh9jjX3f0ABAAgZ3NpLXNuYWRlcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAEdXMAAQAEAARhMAAAAAgAGFNDRUktWFgtWFRDTTAwMDAzLTAwAAAAAAABAARqAAAAAAAAAAAAAAAwAgBEAAgABFoOxO8ACAA4MDUCGQDoMjq/8ZeDFo0Bdo7FPBmAFoWLEzJHbRgCGGX88UQim5OJqDzp7N048ZBmjZcS7xP0dQA="), myPs3LoginCallback, (void*)localPlayerNumber); if (result != WSLogin_Success) { gsDebugFormat(GSIDebugCat_App, GSIDebugType_Misc, GSIDebugLevel_HotError, "Failed on wsLoginPs3Cert. Result: %d\r\n", result); getc(stdin); exit(0); }*/ // wait for it to complete gServerData.mWaitCount++; while(gServerData.mWaitCount > 0) { msleep(SLEEP_MS); gsCoreThink(0); } }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Requests for communication from a peer is handled by first checking if the // initial message has a message handler registered for it. Otherwise // the message is passed onto the app. void gsUdpConnAttemptCB(GT2Socket socket, GT2Connection connection, unsigned int ip, unsigned short port, int latency, GT2Byte * message, int len) { // Get the message handler for the connection int index; GSUdpMsgHandler aHandler; GSUdpRemotePeer aRemotePeer; GSUdpEngineObject *aUdp = gsUdpEngineGetEngine(); char anAddr[GS_IP_ADDR_AND_PORT]; gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, "[Udp Engine] Connection attempt from %s\n", gt2AddressToString(ip, port, anAddr)); //If there is a handler, automatically accept a connection if the initial message is //the same as the handler's registered initial message if (len >= GS_UDP_MSG_HEADER_LEN) { memcpy(aHandler.mInitialMsg, message, GS_UDP_MSG_HEADER_LEN); aRemotePeer.mAddr = ip; aRemotePeer.mPort = port; aRemotePeer.mConnection = connection; ArrayAppend(aUdp->mRemotePeers, &aRemotePeer); index = ArraySearch(aUdp->mMsgHandlers, &aHandler, gsUdpMsgHandlerCompare, 0, 0); if (index != NOT_FOUND) { GT2ConnectionCallbacks aCallbacks; aCallbacks.closed = gsUdpClosedRoutingCB; aCallbacks.connected = gsUdpConnectedRoutingCB; aCallbacks.ping = gsUdpPingRoutingCB; aCallbacks.received = gsUdpReceivedRoutingCB; // Automatically accept connections for Message Handlers gt2Accept(aRemotePeer.mConnection, &aCallbacks); gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, "[Udp Engine] Connection attempt auto-accepted for message handler\n"); return; } } // all other messages go to the app if (aUdp->mAppConnAttempt) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, "[Udp Engine] Connection attempt from %s, asking app to accept/reject\n", gt2AddressToString(ip, port, anAddr)); aUdp->mAppConnAttempt(ip, port, latency, (unsigned char *)message, (unsigned int)len, aUdp->mAppUserData); } else { // Reject any un-handled connections or unknown connections gt2Reject(connection, NULL, 0); ArrayRemoveAt(aUdp->mRemotePeers, ArrayLength(aUdp->mRemotePeers) -1); } GSI_UNUSED(socket); GSI_UNUSED(anAddr); }
/**************** ** SOCKET INIT ** ****************/ void ghiDoSocketInit ( GHIConnection * connection ) { gsDebugFormat(GSIDebugCat_HTTP, GSIDebugType_State, GSIDebugLevel_Comment, "Socket Initialization\n"); // Progress. //////////// ghiCallProgressCallback(connection, NULL, 0); // Init sockets. //////////////// SocketStartUp(); // Parse the URL. ///////////////// if(!ghiParseURL(connection)) { connection->completed = GHTTPTrue; connection->result = GHTTPParseURLFailed; return; } // Check if an encryption type was set. /////////////////////////////////////// if((connection->protocol == GHIHttps) && (connection->encryptor.mEngine == GHTTPEncryptionEngine_None)) { // default to gamespy engine ghttpSetRequestEncryptionEngine(connection->request, GHTTPEncryptionEngine_GameSpy); gsDebugFormat(GSIDebugCat_HTTP, GSIDebugType_Network, GSIDebugLevel_WarmError, "Encryption engine not set for HTTPS. Defaulting to GameSpy engine\r\n"); } else if ((connection->protocol != GHIHttps) && (connection->encryptor.mEngine != GHTTPEncryptionEngine_None)) { // URL is not secured ghttpSetRequestEncryptionEngine(connection->request, GHTTPEncryptionEngine_None); gsDebugFormat(GSIDebugCat_HTTP, GSIDebugType_Network, GSIDebugLevel_WarmError, "Encryption engine set for unsecured URL. Removing encryption.\r\n"); } // Progress. //////////// connection->state = GHTTPHostLookup; ghiCallProgressCallback(connection, NULL, 0); }
GPResult gpiInitializeNpBasic( GPConnection * connection ) { int ret = 0; GPIConnection * iconnection = (GPIConnection*)*connection; iconnection->npInitialized = gsi_true; // Initial NP init - after this we wait for status to get to online //////////////////////////////////////////////////////////////////// ret = sceNpInit(SCE_NP_MIN_POOL_SIZE, gpi_np_pool); if (ret == SCE_NP_ERROR_ALREADY_INITIALIZED) { // If already initialized - DO NOT terminate after sync (game might need it) //////////////////////////////////////////////////////////////////////////// iconnection->npBasicGameInitialized = gsi_true; } else if (ret < 0) { iconnection->npBasicGameInitialized = gsi_true; gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError, "gpiInitializeNpBasic: sceNpInit() failed, NP-functionality disabled. ret = 0x%x\n", ret); return GP_MISC_ERROR; } else iconnection->npBasicGameInitialized = gsi_false; //GP initialized, so destroy after complete return GP_NO_ERROR; }
// Used to check for any timed out peer operations // assumes peer is not NULL // makes no assumption of the operation queue void gpiCheckTimedOutPeerOperations(GPConnection * connection, GPIPeer *peer) { GPIPeerOp *anIterator = peer->peerOpQueue.first; GS_ASSERT(peer); if (!peer) return; while (anIterator && anIterator != peer->peerOpQueue.last) { if (anIterator->state != GPI_PEER_OP_STATE_FINISHED && current_time() > anIterator->timeout && anIterator->callback) { // currently only one type of peer operation exists // when it's found, we need to provide the application with // a result of no data if (anIterator->type == GPI_BM_KEYS_REQUEST) { GPICallback callback; GPGetBuddyStatusInfoKeysArg *arg = (GPGetBuddyStatusInfoKeysArg *)gsimalloc(sizeof(GPGetBuddyStatusInfoKeysArg)); callback.callback = anIterator->callback; callback.param = anIterator->userData; arg->keys = NULL; arg->numKeys = 0; arg->values = NULL; arg->profile = peer->profile; gpiAddCallback(connection, callback, arg, NULL, 0); } // The peer operation is removed regardless of type gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_Notice, "Peer operation timed out"); gpiPeerRemoveOp(peer, anIterator); } anIterator = anIterator->next; } }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // UDP Layer must be initialized // Used obtain the peer's state // theIp and thePort cannot be 0 (Zero) GSUdpErrorCode gsUdpEngineGetPeerState(unsigned int theIp, unsigned short thePort, GSUdpPeerState *thePeerState) { GSUdpEngineObject *aUdp = gsUdpEngineGetEngine(); GSUdpRemotePeer aPeer, *aPeerFound; int index; GS_ASSERT(aUdp->mInitialized); GS_ASSERT(theIp); GS_ASSERT(thePort); GS_ASSERT(thePeerState != NULL); if (!aUdp->mInitialized) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_State, GSIDebugLevel_Debug, "[Udp Engine] Engine not initialized\n"); *thePeerState = GS_UDP_PEER_CLOSED; return GS_UDP_NOT_INITIALIZED; } aPeer.mAddr = theIp; aPeer.mPort = thePort; index = ArraySearch(aUdp->mRemotePeers, &aPeer, gsUdpRemotePeerCompare, 0, 0); if (index == NOT_FOUND) { *thePeerState = GS_UDP_PEER_CLOSED; return GS_UDP_NO_ERROR; } aPeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index); *thePeerState = (GSUdpPeerState)gt2GetConnectionState(aPeerFound->mConnection); return GS_UDP_NO_ERROR; }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // UDP Layer must be initialized // theIp and thePort cannot be 0 (Zero) // Based on an IP and port, the function will return the amount of free space // of a peer's buffer. int gsUdpEngineGetPeerOutBufferFreeSpace(unsigned int theIp, unsigned short thePort) { GSUdpEngineObject *aUdp = gsUdpEngineGetEngine(); GSUdpRemotePeer aRemotePeer, *aRemotePeerFound; int index; GS_ASSERT(aUdp->mInitialized); GS_ASSERT(theIp); GS_ASSERT(thePort); if (!aUdp->mInitialized) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug, "[Udp Engine] Engine not initialized\n"); return 0; } aRemotePeer.mAddr = theIp; aRemotePeer.mPort = thePort; index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0); if (index != NOT_FOUND) { aRemotePeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index); return gt2GetOutgoingBufferFreeSpace(aRemotePeerFound->mConnection); } return 0; }
/************ ** WAITING ** ************/ void ghiDoWaiting ( GHIConnection * connection ) { int readFlag; int exceptFlag; int rcode; gsDebugFormat(GSIDebugCat_HTTP, GSIDebugType_State, GSIDebugLevel_Comment, "Waiting\n"); // We're waiting to receive something. ////////////////////////////////////// rcode = GSISocketSelect(connection->socket, &readFlag, NULL, &exceptFlag); if((gsiSocketIsError(rcode)) || ((rcode == 1) && exceptFlag)) { connection->completed = GHTTPTrue; connection->result = GHTTPSocketFailed; if(gsiSocketIsError(rcode)) connection->socketError = GOAGetLastError(connection->socket); else connection->socketError = 0; return; } // Check for waiting data. ////////////////////////// if((rcode == 1) && readFlag) { // Ready to receive. //////////////////// connection->state = GHTTPReceivingStatus; ghiCallProgressCallback(connection, NULL, 0); } }
// gpiPeerRemoveOp: // Assumes the list is NOT NULL otherwise it returns. // Assumes the operation being passed in is on the queue. // Assumes non-null inputs! // Completed or Timed out Operations are deleted from queue by finding // the operation passed in. Removal of operations don't necessarily // happen in order. void gpiPeerRemoveOp(GPIPeer *peer, GPIPeerOp *operation) { GS_ASSERT(peer); GS_ASSERT(operation); if (!peer || !operation) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_WarmError, "Peer operation not removed"); return; } GS_ASSERT(peer->peerOpQueue.opList != NULL); if (peer->peerOpQueue.opList == NULL) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_WarmError, "Peer operation not removed"); return; } if (peer->peerOpQueue.first == peer->peerOpQueue.last && peer->peerOpQueue.first == operation) { peer->peerOpQueue.opList = peer->peerOpQueue.first = peer->peerOpQueue.last = operation->next; } else if (peer->peerOpQueue.first == operation) { peer->peerOpQueue.first = peer->peerOpQueue.first->next; peer->peerOpQueue.opList = peer->peerOpQueue.first; } else { GPIPeerOp *aPrevOp = NULL; for(aPrevOp = peer->peerOpQueue.first ; aPrevOp->next != operation ; aPrevOp = aPrevOp->next) { if(aPrevOp->next == NULL) { // Can't find this peer in the list! //////////////////////////////////// gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError, "Tried to remove peer operation not in list."); return; } } aPrevOp->next = operation->next; } gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_Notice, "Peer operation removed"); freeclear(operation); }
GPResult gpiSyncNpBlockList( GPConnection * connection ) { int ret; SceNpId npId; //Buffer to store block list entry's NP ID gsi_u32 i, count = 0; GPIConnection * iconnection = (GPIConnection*)*connection; // Flag sync as complete so we don't do it more than once per login //////////////////////////////////////////////////////////////////// iconnection->npPerformBlockSync = gsi_false; // Get block list count /////////////////////// ret = sceNpBasicGetBlockListEntryCount(&count); if ( ret < 0 ) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError, "PS3BlockSync: Failed to get NP block list count\n"); } // Loop through each entry, check for existence of GSID account /////////////////////////////////////////////////////////////// for (i = 0; i < count; i++) { memset(&npId, 0x00, sizeof(npId)); ret = sceNpBasicGetBlockListEntry(i, &npId); if (ret < 0) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError, "PS3BlockSync: Failed to get NP block entry #%d\n", i); return GP_MISC_ERROR; } gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_Comment, "PS3BlockSync: NP block entry #%d, npid = %s. Queueing Search.\n", i, npId.handle.data); gpiProfileSearchUniquenick(connection, npId.handle.data, &iconnection->namespaceID, 1, GP_NON_BLOCKING, (GPCallback)gpiSyncNpBlockListCallback, NULL); } return GP_NO_ERROR; }
/****************** ** LOOKUP PENDING** ******************/ void ghiDoLookupPending ( GHIConnection * connection ) { #if !defined(GSI_NO_THREADS) //check if lookup is complete connection->serverIP = gsiGetResolvedIP(*connection->handle); //make sure there were no problems with the IP if (connection->serverIP == GSI_ERROR_RESOLVING_HOSTNAME) { gsDebugFormat(GSIDebugCat_HTTP, GSIDebugType_State, GSIDebugLevel_HotError, "Error resolving hostname\n"); //free handle memory and set to NULL gsifree(connection->handle); connection->handle = NULL; //notify that the lookup failed connection->completed = GHTTPTrue; connection->result = GHTTPHostLookupFailed; return; } if (connection->serverIP == GSI_STILL_RESOLVING_HOSTNAME) { //lookup incomplete - keep calling this function connection->state = GHTTPLookupPending; ghiCallProgressCallback(connection, NULL, 0); } else { //free handle memory and set to NULL gsifree(connection->handle); connection->handle = NULL; gsDebugFormat(GSIDebugCat_HTTP, GSIDebugType_State, GSIDebugLevel_Comment, "DNS lookup complete\n"); //looks like we got ourselves a server! proceed with connection phase connection->state = GHTTPConnecting; ghiCallProgressCallback(connection, NULL, 0); } #endif }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Lets the App and Message Handlers know a peer left void gsUdpClosedRoutingCB(GT2Connection theConnection, GT2CloseReason reason) { GSUdpEngineObject *aUdp = gsUdpEngineGetEngine(); GSUdpRemotePeer aRemotePeer; int index, len; GSUdpCloseReason aReason; char anAddr[GS_IP_ADDR_AND_PORT]; if (reason == GT2CommunicationError || reason == GT2SocketError) aReason = GS_UDP_CLOSED_BY_COMM_ERROR; else if (reason == GT2NotEnoughMemory) aReason = GS_UDP_CLOSED_BY_LOW_MEM; else aReason = (GSUdpCloseReason)reason; gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, "[Udp Engine] Connection closed to %s\n", gt2AddressToString(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), anAddr)); len = ArrayLength(aUdp->mMsgHandlers); for (index = 0; index < len; index++) { GSUdpMsgHandler *aHandler = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, index); if (aHandler->mClosed) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, "[Udp Engine] Connection closed: passed to message handler\n"); aHandler->mClosed(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), aReason, aHandler->mUserData); } } if (aUdp->mAppClosed) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, "[Udp Engine] Connection closed: passed to app\n"); aUdp->mAppClosed(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), aReason, aUdp->mAppUserData); } aRemotePeer.mConnection = theConnection; index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare2, 0, 0); if (index != NOT_FOUND) { ArrayDeleteAt(aUdp->mRemotePeers, index); } GSI_UNUSED(anAddr); }
void gsiLeaveCriticalSection(GSICriticalSection *theCrit) { int ret; ret = sys_mutex_unlock(*theCrit); if (ret != CELL_OK) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Misc, GSIDebugLevel_WarmError, "Failed to enter critical section: %d\r\n", ret); } }
GSISemaphoreID gsiCreateSemaphore(gsi_i32 theInitialCount, gsi_i32 theMaxCount, char* theName) { GSISemaphoreID aSemaphore = CreateSemaphoreA(NULL, theInitialCount, theMaxCount, theName); if (aSemaphore == NULL) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Misc, GSIDebugLevel_WarmError, "Failed to create semaphore\r\n"); } return aSemaphore; }
void gsiDeleteCriticalSection(GSICriticalSection *theCrit) { int ret; ret = sys_mutex_destroy(*theCrit); if (ret != CELL_OK) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Misc, GSIDebugLevel_WarmError, "Failed to delete critical section: %d\r\n", ret); } }
void SBServerAddKeyValue(SBServer server, const char *keyname, const char *value) { SBKeyValuePair kv; kv.key = SBRefStr(NULL, keyname); kv.value = SBRefStr(NULL, value); TableEnter(server->keyvals, &kv); gsDebugFormat(GSIDebugCat_SB, GSIDebugType_Misc, GSIDebugLevel_Comment, "SBServerAddKeyValue added %s\\%s\r\n", keyname, value); }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Any data received prompts the UDP layer to first find a higher level // message handler to handle the data. If there was no message handler // found, the data is passed to the higher level app. void gsUdpReceivedRoutingCB(GT2Connection theConnection, GT2Byte *theMessage, int theMessageLen, GT2Bool reliable) { GSUdpEngineObject *aUdp = gsUdpEngineGetEngine(); GSUdpMsgHandler aHandler; int index; char anAddr[GS_IP_ADDR_AND_PORT]; gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, "[Udp Engine] Received data from %s\n", gt2AddressToString(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), anAddr)); //If there is a handler, pass it to the handler //The header should not be stripped off if (theMessageLen >= GS_UDP_MSG_HEADER_LEN) { memcpy(aHandler.mHeader, theMessage, GS_UDP_MSG_HEADER_LEN); index = ArraySearch(aUdp->mMsgHandlers, &aHandler, gsUdpMsgHandlerCompare2, 0, 0); if (index != NOT_FOUND) { GSUdpMsgHandler *aHandlerFound = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, index); if (aHandlerFound->mReceived) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, "[Udp Engine] Passed to message handler\n"); aHandlerFound->mReceived(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), theMessage + GS_UDP_MSG_HEADER_LEN, (unsigned int)(theMessageLen - GS_UDP_MSG_HEADER_LEN), reliable, aHandlerFound->mUserData); return; } } } if (aUdp->mAppRecvData) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, "[Udp Engine] Passed to app\n"); aUdp->mAppRecvData(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), theMessage, (unsigned int)theMessageLen, reliable, aUdp->mAppUserData); } GSI_UNUSED(anAddr); }
void gpiSyncNpBlockListCallback( GPConnection * pconnection, GPProfileSearchResponseArg * arg, void * param ) { GPIProfile * pProfile; GPIConnection * iconnection = (GPIConnection*)*pconnection; if(arg->result == GP_NO_ERROR) { if(arg->numMatches == 1) { // Check if already blocked //////////////////////////// if(!gpiGetProfile(pconnection, arg->matches[0].profile, &pProfile) || !pProfile->blocked) { gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_Comment, "PS3BlockSync: NP Block Entry \"%s\" found in namespace %d. Adding to BlockedList.\n", arg->matches[0].uniquenick, arg->matches[0].namespaceID); // Add to GP Blocked List - set lock to make sure we dont try to add to NP list /////////////////////////////////////////////////////////////////////////////// iconnection->npSyncLock = gsi_true; gpiAddToBlockedList(pconnection, arg->matches[0].profile); iconnection->npSyncLock = gsi_false; } else gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_Comment, "PS3BlockSync: \"%s\" is already blocked\n", arg->matches[0].uniquenick); } else gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_Comment, "PS3BlockSync: No suitable match found\n"); } else gsDebugFormat(GSIDebugCat_GP, GSIDebugType_Misc, GSIDebugLevel_HotError, "PS3BlockSync: Block Entry Search FAILED!\n"); GSI_UNUSED(param); }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // UDP Layer must be initialized // theIp and thePort cannot be 0 (Zero) // Accepts a Peer's request for communication // Should only be used by App GSUdpErrorCode gsUdpEngineAcceptPeer(unsigned int theIp, unsigned short thePort) { GSUdpRemotePeer aRemotePeer; GSUdpEngineObject *aUdp = gsUdpEngineGetEngine(); int index; GS_ASSERT(aUdp->mInitialized); GS_ASSERT(theIp); GS_ASSERT(thePort); if (!aUdp->mInitialized) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug, "[Udp Engine] Engine not initialized\n"); return GS_UDP_NETWORK_ERROR; } if (theIp == 0 || thePort == 0) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug, "[Udp Engine] Invalid parameter(s), check ip, port\n"); return GS_UDP_PARAMETER_ERROR; } aRemotePeer.mAddr = theIp; aRemotePeer.mPort = thePort; index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0); if (index != NOT_FOUND) { GT2ConnectionCallbacks aCallbacks; GSUdpRemotePeer *aPeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index); aCallbacks.closed = gsUdpClosedRoutingCB; aCallbacks.connected = gsUdpConnectedRoutingCB; aCallbacks.ping = gsUdpPingRoutingCB; aCallbacks.received = gsUdpReceivedRoutingCB; gt2Accept(aPeerFound->mConnection, &aCallbacks); } return GS_UDP_NO_ERROR; }
static void myLoginCallback(GHTTPResult httpResult, WSLoginResponse * theResponse, void * theUserData) { if (httpResult != GHTTPSuccess) { gsDebugFormat(GSIDebugCat_App, GSIDebugType_Misc, GSIDebugLevel_HotError, "Failed on player login, HTTP error: %d\r\n", httpResult); getc(stdin); exit(0); } else if (theResponse->mLoginResult != WSLogin_Success) { gsDebugFormat(GSIDebugCat_App, GSIDebugType_Misc, GSIDebugLevel_HotError, "Failed on player login, Login result: %d\r\n", theResponse->mLoginResult); getc(stdin); exit(0); } else { SamplePlayerData * newPlayer = NULL; int playerIndex = (int)theUserData; char playerNick[WS_LOGIN_NICK_LEN]; newPlayer = &gPlayerData[playerIndex]; // copy certificate and private key newPlayer->mProfileId = theResponse->mCertificate.mProfileId; memcpy(&newPlayer->mCertificate, &theResponse->mCertificate, sizeof(GSLoginCertificate)); memcpy(&newPlayer->mPrivateData, &theResponse->mPrivateData, sizeof(GSLoginPrivateData)); #ifdef GSI_UNICODE UCS2ToAsciiString(theResponse->mCertificate.mUniqueNick, playerNick); printf("Player '%s' logged in.\r\n", playerNick); #else printf("Player '%s' logged in.\r\n", theResponse->mCertificate.mUniqueNick); GSI_UNUSED(playerNick); #endif } gServerData.mWaitCount--; }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // UDP Layer must be initialized // One the UDP Layer is initialized, this function // should be called every 10-100 ms // Message handlers already call this which means // that the app may not have to call this function GSUdpErrorCode gsUdpEngineThink() { GSUdpEngineObject *aUdp = gsUdpEngineGetEngine(); GS_ASSERT(aUdp->mInitialized); if (!aUdp->mInitialized) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug, "[Udp Engine] Engine not initialized\n"); return GS_UDP_NETWORK_ERROR; } gt2Think(aUdp->mSocket); return GS_UDP_NO_ERROR; }
/////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // This will be triggered when scSetReportIntention() has completed. // Expected to occur once per reported game session. void setReportIntentionCallback(SCInterfacePtr theInterface, GHTTPResult theHttpResult, SCResult theResult, void * theUserData) { SamplePlayerData* thePlayer = (SamplePlayerData*)theUserData; gsDebugFormat(GSIDebugCat_App, GSIDebugType_Misc, GSIDebugLevel_Notice, "SetReportIntentionCallback: theHttpResult = %d, theResult = %s\r\n", theHttpResult, SCResultStr[theResult]); if (theHttpResult == GHTTPSuccess && theResult == SCResult_NO_ERROR) { const char * connectionId = scGetConnectionId(theInterface); memcpy(thePlayer->mConnectionId, connectionId, SC_CONNECTION_GUID_SIZE); gsDebugFormat(GSIDebugCat_App, GSIDebugType_Misc, GSIDebugLevel_Debug, "Connection ID: %s\r\n", connectionId); } gServerData.mWaitCount--; // one less request to wait for GSI_UNUSED(theInterface); GSI_UNUSED(theUserData); }
int gsiStartThread(GSThreadFunc func, gsi_u32 theStackSize, void *arg, GSIThreadID * id) { int ret; ret = sys_ppu_thread_create(id, func, (uint32_t)arg, 1535, theStackSize, 0, NULL); if (ret != CELL_OK) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Misc, GSIDebugLevel_WarmError, "Failed to create thread: %d\r\n", ret); return -1; } return 0; }
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // UDP Layer must be initialized // Gets the local port the UDP layer is bound to. unsigned short gsUdpEngineGetLocalPort() { GSUdpEngineObject *aUdp = gsUdpEngineGetEngine(); GS_ASSERT(aUdp->mInitialized); if (!aUdp->mInitialized) { gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_HotError, "[Udp Engine] Engine not initialized\n"); return 0; } return aUdp->mLocalPort; }