int friendFinder(){ // Receive Buffer int rxpos = 0; uint8_t rx[1024]; // Chat Packet SceNetAdhocctlChatPacketC2S chat; chat.base.opcode = OPCODE_CHAT; // Last Ping Time uint64_t lastping = 0; // Last Time Reception got updated uint64_t lastreceptionupdate = 0; uint64_t now; // Finder Loop while(friendFinderRunning) { // Acquire Network Lock //_acquireNetworkLock(); // Ping Server now = real_time_now()*1000.0; if(now - lastping >= 100) { // Update Ping Time lastping = now; // Prepare Packet uint8_t opcode = OPCODE_PING; // Send Ping to Server send(metasocket, (const char *)&opcode, 1,0); } // Send Chat Messages //while(popFromOutbox(chat.message)) //{ // // Send Chat to Server // sceNetInetSend(metasocket, (const char *)&chat, sizeof(chat), 0); //} // Wait for Incoming Data int received = recv(metasocket, (char *)(rx + rxpos), sizeof(rx) - rxpos,0); // Free Network Lock //_freeNetworkLock(); // Received Data if(received > 0) { // Fix Position rxpos += received; // Log Incoming Traffic //printf("Received %d Bytes of Data from Server\n", received); INFO_LOG(SCENET, "Received %d Bytes of Data from Adhoc Server", received); } // Handle Packets if(rxpos > 0) { // BSSID Packet if(rx[0] == OPCODE_CONNECT_BSSID) { // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)) { // Cast Packet SceNetAdhocctlConnectBSSIDPacketS2C * packet = (SceNetAdhocctlConnectBSSIDPacketS2C *)rx; // Update BSSID parameter.bssid.mac_addr = packet->mac; // Change State threadStatus = ADHOCCTL_STATE_CONNECTED; // Notify Event Handlers CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventHandlerUpdate, join32(ADHOCCTL_EVENT_CONNECT, 0)); // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlConnectBSSIDPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlConnectBSSIDPacketS2C); } } // Chat Packet else if(rx[0] == OPCODE_CHAT) { // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlChatPacketS2C)) { // Cast Packet SceNetAdhocctlChatPacketS2C * packet = (SceNetAdhocctlChatPacketS2C *)rx; // Fix for Idiots that try to troll the "ME" Nametag if(strcasecmp((char *)packet->name.data, "ME") == 0) strcpy((char *)packet->name.data, "NOT ME"); // Add Incoming Chat to HUD //printf("Receive chat message %s", packet->base.message); // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlChatPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlChatPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlChatPacketS2C); } } // Connect Packet else if(rx[0] == OPCODE_CONNECT) { // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlConnectPacketS2C)) { // Log Incoming Peer INFO_LOG(SCENET,"Incoming Peer Data..."); // Cast Packet SceNetAdhocctlConnectPacketS2C * packet = (SceNetAdhocctlConnectPacketS2C *)rx; // Add User addFriend(packet); // Update HUD User Count #ifdef LOCALHOST_AS_PEER setUserCount(getActivePeerCount()); #else // setUserCount(getActivePeerCount()+1); #endif // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlConnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlConnectPacketS2C); } } // Disconnect Packet else if(rx[0] == OPCODE_DISCONNECT) { // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlDisconnectPacketS2C)) { // Log Incoming Peer Delete Request INFO_LOG(SCENET,"FriendFinder: Incoming Peer Data Delete Request..."); // Cast Packet SceNetAdhocctlDisconnectPacketS2C * packet = (SceNetAdhocctlDisconnectPacketS2C *)rx; // Delete User by IP deleteFriendByIP(packet->ip); // Update HUD User Count #ifdef LOCALHOST_AS_PEER setUserCount(_getActivePeerCount()); #else //setUserCount(_getActivePeerCount()+1); #endif // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlDisconnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlDisconnectPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlDisconnectPacketS2C); } } // Scan Packet else if(rx[0] == OPCODE_SCAN) { // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlScanPacketS2C)) { // Log Incoming Network Information INFO_LOG(SCENET,"Incoming Group Information..."); // Cast Packet SceNetAdhocctlScanPacketS2C * packet = (SceNetAdhocctlScanPacketS2C *)rx; // Allocate Structure Data SceNetAdhocctlScanInfo * group = (SceNetAdhocctlScanInfo *)malloc(sizeof(SceNetAdhocctlScanInfo)); // Allocated Structure Data if(group != NULL) { // Clear Memory memset(group, 0, sizeof(SceNetAdhocctlScanInfo)); // Link to existing Groups group->next = networks; // Copy Group Name group->group_name = packet->group; // Set Group Host group->bssid.mac_addr = packet->mac; // Link into Group List networks = group; } // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlScanPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlScanPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlScanPacketS2C); } } // Scan Complete Packet else if(rx[0] == OPCODE_SCAN_COMPLETE) { // Log Scan Completion INFO_LOG(SCENET,"FriendFinder: Incoming Scan complete response..."); // Change State threadStatus = ADHOCCTL_STATE_DISCONNECTED; // Notify Event Handlers CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventHandlerUpdate,join32(ADHOCCTL_EVENT_SCAN, 0)); //int i = 0; for(; i < ADHOCCTL_MAX_HANDLER; i++) //{ // // Active Handler // if(_event_handler[i] != NULL) _event_handler[i](ADHOCCTL_EVENT_SCAN, 0, _event_args[i]); //} // Move RX Buffer memmove(rx, rx + 1, sizeof(rx) - 1); // Fix RX Buffer Length rxpos -= 1; } } // Original value was 10 ms, I think 100 is just fine sleep_ms(100); } // Log Shutdown INFO_LOG(SCENET, "FriendFinder: End of Friend Finder Thread"); // Return Success return 0; }
int friendFinder(){ // Receive Buffer int rxpos = 0; uint8_t rx[1024]; // Chat Packet SceNetAdhocctlChatPacketC2S chat; chat.base.opcode = OPCODE_CHAT; // Last Ping Time uint64_t lastping = 0; // Last Time Reception got updated uint64_t lastreceptionupdate = 0; uint64_t now; // Log Startup INFO_LOG(SCENET, "FriendFinder: Begin of Friend Finder Thread"); // Finder Loop while(friendFinderRunning) { // Acquire Network Lock //_acquireNetworkLock(); // Ping Server now = real_time_now()*1000.0; if(now - lastping >= 100) { // Update Ping Time lastping = now; // Prepare Packet uint8_t opcode = OPCODE_PING; // Send Ping to Server, may failed with socket error 10054/10053 if someone else with the same IP already connected to AdHoc Server (the server might need to be modified to differentiate MAC instead of IP) int iResult = send(metasocket, (const char *)&opcode, 1,0); /*if (iResult == SOCKET_ERROR) { ERROR_LOG(SCENET, "FriendFinder: Socket Error (%i) when sending OPCODE_PING", errno); //friendFinderRunning = false; }*/ } // Send Chat Messages //while(popFromOutbox(chat.message)) //{ // // Send Chat to Server // sceNetInetSend(metasocket, (const char *)&chat, sizeof(chat), 0); //} // Wait for Incoming Data int received = recv(metasocket, (char *)(rx + rxpos), sizeof(rx) - rxpos,0); // Free Network Lock //_freeNetworkLock(); // Received Data if(received > 0) { // Fix Position rxpos += received; // Log Incoming Traffic //printf("Received %d Bytes of Data from Server\n", received); INFO_LOG(SCENET, "Received %d Bytes of Data from Adhoc Server", received); } // Handle Packets if(rxpos > 0) { // BSSID Packet if(rx[0] == OPCODE_CONNECT_BSSID) { INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT_BSSID"); // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)) { // Cast Packet SceNetAdhocctlConnectBSSIDPacketS2C * packet = (SceNetAdhocctlConnectBSSIDPacketS2C *)rx; // Update BSSID parameter.bssid.mac_addr = packet->mac; // Change State threadStatus = ADHOCCTL_STATE_CONNECTED; // Notify Event Handlers CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventHandlerUpdate, join32(ADHOCCTL_EVENT_CONNECT, 0)); // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlConnectBSSIDPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlConnectBSSIDPacketS2C); } } // Chat Packet else if(rx[0] == OPCODE_CHAT) { INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CHAT"); // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlChatPacketS2C)) { // Cast Packet SceNetAdhocctlChatPacketS2C * packet = (SceNetAdhocctlChatPacketS2C *)rx; // Fix for Idiots that try to troll the "ME" Nametag if(strcasecmp((char *)packet->name.data, "ME") == 0) strcpy((char *)packet->name.data, "NOT ME"); // Add Incoming Chat to HUD //printf("Receive chat message %s", packet->base.message); DEBUG_LOG(SCENET, "Received chat message %s", packet->base.message); // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlChatPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlChatPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlChatPacketS2C); } } // Connect Packet else if(rx[0] == OPCODE_CONNECT) { DEBUG_LOG(SCENET, "FriendFinder: OPCODE_CONNECT"); // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlConnectPacketS2C)) { // Log Incoming Peer INFO_LOG(SCENET,"Incoming Peer Data..."); // Cast Packet SceNetAdhocctlConnectPacketS2C * packet = (SceNetAdhocctlConnectPacketS2C *)rx; // Add User addFriend(packet); // Update HUD User Count #ifdef LOCALHOST_AS_PEER setUserCount(getActivePeerCount()); #else // setUserCount(getActivePeerCount()+1); #endif // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlConnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlConnectPacketS2C); } } // Disconnect Packet else if(rx[0] == OPCODE_DISCONNECT) { DEBUG_LOG(SCENET, "FriendFinder: OPCODE_DISCONNECT"); // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlDisconnectPacketS2C)) { // Log Incoming Peer Delete Request INFO_LOG(SCENET,"FriendFinder: Incoming Peer Data Delete Request..."); // Cast Packet SceNetAdhocctlDisconnectPacketS2C * packet = (SceNetAdhocctlDisconnectPacketS2C *)rx; // Delete User by IP, should delete by MAC since IP can be shared (behind NAT) isn't? deleteFriendByIP(packet->ip); // Update HUD User Count #ifdef LOCALHOST_AS_PEER setUserCount(_getActivePeerCount()); #else //setUserCount(_getActivePeerCount()+1); #endif // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlDisconnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlDisconnectPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlDisconnectPacketS2C); } } // Scan Packet else if(rx[0] == OPCODE_SCAN) { DEBUG_LOG(SCENET, "FriendFinder: OPCODE_SCAN"); // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlScanPacketS2C)) { // Log Incoming Network Information INFO_LOG(SCENET,"Incoming Group Information..."); // Cast Packet SceNetAdhocctlScanPacketS2C * packet = (SceNetAdhocctlScanPacketS2C *)rx; // Multithreading Lock peerlock.lock(); // It seems AdHoc Server always sent the full group list, so we should reset group list during Scan initialization // Should only add non-existing group (or replace an existing group) to prevent Ford Street Racing from showing a strange game session list /*SceNetAdhocctlScanInfo * group = findGroup(&packet->mac); if (group != NULL) { // Copy Group Name group->group_name = packet->group; // Set Group Host group->bssid.mac_addr = packet->mac; } else*/ { // Allocate Structure Data SceNetAdhocctlScanInfo * group = (SceNetAdhocctlScanInfo *)malloc(sizeof(SceNetAdhocctlScanInfo)); // Allocated Structure Data if (group != NULL) { // Clear Memory, should this be done only when allocating new group? memset(group, 0, sizeof(SceNetAdhocctlScanInfo)); // Link to existing Groups group->next = networks; // Copy Group Name group->group_name = packet->group; // Set Group Host group->bssid.mac_addr = packet->mac; // Link into Group List networks = group; } } // Multithreading Unlock peerlock.unlock(); // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlScanPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlScanPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlScanPacketS2C); } } // Scan Complete Packet else if(rx[0] == OPCODE_SCAN_COMPLETE) { DEBUG_LOG(SCENET, "FriendFinder: OPCODE_SCAN_COMPLETE"); // Log Scan Completion INFO_LOG(SCENET,"FriendFinder: Incoming Scan complete response..."); // Change State threadStatus = ADHOCCTL_STATE_DISCONNECTED; // Notify Event Handlers CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventHandlerUpdate,join32(ADHOCCTL_EVENT_SCAN, 0)); //int i = 0; for(; i < ADHOCCTL_MAX_HANDLER; i++) //{ // // Active Handler // if(_event_handler[i] != NULL) _event_handler[i](ADHOCCTL_EVENT_SCAN, 0, _event_args[i]); //} // Move RX Buffer memmove(rx, rx + 1, sizeof(rx) - 1); // Fix RX Buffer Length rxpos -= 1; } } // Original value was 10 ms, I think 100 is just fine sleep_ms(100); } // Groups/Networks should be deallocated isn't? // Prevent the games from having trouble to reInitiate Adhoc (the next NetInit -> PdpCreate after NetTerm) threadStatus = ADHOCCTL_STATE_DISCONNECTED; // Log Shutdown INFO_LOG(SCENET, "FriendFinder: End of Friend Finder Thread"); // Return Success return 0; }