mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Improved multiplayer compatibility on some games (ie. GTA VCS, Naruto Ultimate Ninja Heroes 3, DBZ Shin Budokai 2, Power Stone Collection, .hack//Link, etc)
This commit is contained in:
parent
af2ed00232
commit
fb7d50e5c2
8 changed files with 1428 additions and 657 deletions
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <cstring>
|
||||
#include "util/text/parsers.h"
|
||||
#include "thread/threadutil.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/HLE/sceKernelInterrupt.h"
|
||||
|
@ -46,7 +47,7 @@ SceNetAdhocctlScanInfo * networks = NULL;
|
|||
SceNetAdhocctlScanInfo * newnetworks = NULL;
|
||||
int threadStatus = ADHOCCTL_STATE_DISCONNECTED;
|
||||
|
||||
bool IsAdhocctlInCB = false;
|
||||
int actionAfterAdhocMipsCall;
|
||||
int actionAfterMatchingMipsCall;
|
||||
|
||||
// Broadcast MAC
|
||||
|
@ -59,7 +60,6 @@ std::thread friendFinderThread;
|
|||
std::recursive_mutex peerlock;
|
||||
SceNetAdhocPdpStat * pdp[255];
|
||||
SceNetAdhocPtpStat * ptp[255];
|
||||
uint32_t localip;
|
||||
std::vector<std::string> chatLog;
|
||||
std::string name = "";
|
||||
std::string incoming = "";
|
||||
|
@ -67,11 +67,10 @@ std::string message = "";
|
|||
bool chatScreenVisible = false;
|
||||
bool updateChatScreen = false;
|
||||
int newChat = 0;
|
||||
|
||||
bool isLocalServer = false;
|
||||
sockaddr localIP; // This might serves the same purpose with existing "localip" above, but since this is copied from my old code so here it is (too lazy to rewrite the code)
|
||||
|
||||
int isLocalMAC(const SceNetEtherAddr * addr) {
|
||||
bool isLocalMAC(const SceNetEtherAddr * addr) {
|
||||
SceNetEtherAddr saddr;
|
||||
getLocalMac(&saddr);
|
||||
|
||||
|
@ -82,32 +81,59 @@ int isLocalMAC(const SceNetEtherAddr * addr) {
|
|||
return (match == 0);
|
||||
}
|
||||
|
||||
int isPDPPortInUse(uint16_t port) {
|
||||
bool isPDPPortInUse(uint16_t port) {
|
||||
// Iterate Elements
|
||||
int i = 0; for (; i < 255; i++) if (pdp[i] != NULL && pdp[i]->lport == port) return 1;
|
||||
for (int i = 0; i < 255; i++) if (pdp[i] != NULL && pdp[i]->lport == port) return true;
|
||||
|
||||
// Unused Port
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int isPTPPortInUse(uint16_t port) {
|
||||
bool isPTPPortInUse(uint16_t port) {
|
||||
// Iterate Sockets
|
||||
int i = 0; for(; i < 255; i++) if(ptp[i] != NULL && ptp[i]->lport == port) return 1;
|
||||
for(int i = 0; i < 255; i++) if(ptp[i] != NULL && ptp[i]->lport == port) return true;
|
||||
|
||||
// Unused Port
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
char* mac2str(SceNetEtherAddr* mac) {
|
||||
if (mac == NULL) return ":::::";
|
||||
#if defined(_WIN32)
|
||||
static __declspec(thread) char str[18];
|
||||
#else
|
||||
static __thread char str[18];
|
||||
#endif
|
||||
snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
char* mac2str(SceNetEtherAddr* mac, char* str, size_t size) {
|
||||
if (mac == NULL || str == NULL || size < 18) return NULL;
|
||||
|
||||
snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
SceNetAdhocMatchingMemberInternal* addMember(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac) {
|
||||
if (context == NULL || mac == NULL) return NULL;
|
||||
|
||||
SceNetAdhocMatchingMemberInternal * peer = findPeer(context, mac);
|
||||
// Already existed
|
||||
if (peer != NULL) {
|
||||
char tmpmac[18];
|
||||
WARN_LOG(SCENET, "Member Peer Already Existed! Updating [%s]", mac2str(mac, tmpmac));
|
||||
peer->lastping = CoreTiming::GetGlobalTimeUsScaled();
|
||||
}
|
||||
// Member is not added yet
|
||||
if (peer == NULL) {
|
||||
else {
|
||||
peer = (SceNetAdhocMatchingMemberInternal *)malloc(sizeof(SceNetAdhocMatchingMemberInternal));
|
||||
if (peer != NULL) {
|
||||
memset(peer, 0, sizeof(SceNetAdhocMatchingMemberInternal));
|
||||
peer->mac = *mac;
|
||||
peer->lastping = CoreTiming::GetGlobalTimeUsScaled();
|
||||
peer->next = context->peerlist;
|
||||
context->peerlist = peer;
|
||||
}
|
||||
|
@ -124,14 +150,15 @@ void addFriend(SceNetAdhocctlConnectPacketS2C * packet) {
|
|||
SceNetAdhocctlPeerInfo * peer = findFriend(&packet->mac);
|
||||
// Already existed
|
||||
if (peer != NULL) {
|
||||
char tmpmac[18];
|
||||
WARN_LOG(SCENET, "Friend Peer Already Existed! Updating [%s][%s][%s]", packet->name.data, mac2str(&packet->mac, tmpmac), inet_ntoa(*(in_addr*)&packet->ip));
|
||||
peer->nickname = packet->name;
|
||||
peer->mac_addr = packet->mac;
|
||||
peer->ip_addr = packet->ip;
|
||||
// Update TimeStamp
|
||||
peer->last_recv = CoreTiming::GetGlobalTimeUsScaled();
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
// Allocate Structure
|
||||
peer = (SceNetAdhocctlPeerInfo *)malloc(sizeof(SceNetAdhocctlPeerInfo));
|
||||
// Allocated Structure
|
||||
|
@ -198,7 +225,7 @@ void changeBlockingMode(int fd, int nonblocking) {
|
|||
#endif
|
||||
}
|
||||
|
||||
int countAvailableNetworks(void) {
|
||||
int countAvailableNetworks() {
|
||||
// Network Count
|
||||
int count = 0;
|
||||
|
||||
|
@ -236,11 +263,12 @@ void freeGroupsRecursive(SceNetAdhocctlScanInfo * node) {
|
|||
|
||||
// Free Memory
|
||||
free(node);
|
||||
node = NULL;
|
||||
}
|
||||
|
||||
void deleteAllPDP(void) {
|
||||
void deleteAllPDP() {
|
||||
// Iterate Element
|
||||
int i = 0; for (; i < 255; i++) {
|
||||
for (int i = 0; i < 255; i++) {
|
||||
// Active Socket
|
||||
if (pdp[i] != NULL) {
|
||||
// Close Socket
|
||||
|
@ -255,9 +283,9 @@ void deleteAllPDP(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void deleteAllPTP(void) {
|
||||
void deleteAllPTP() {
|
||||
// Iterate Element
|
||||
int i = 0; for (; i < 255; i++) {
|
||||
for (int i = 0; i < 255; i++) {
|
||||
// Active Socket
|
||||
if (ptp[i] != NULL) {
|
||||
// Close Socket
|
||||
|
@ -283,36 +311,39 @@ void deleteFriendByIP(uint32_t ip) {
|
|||
for (; peer != NULL; peer = peer->next) {
|
||||
// Found Peer
|
||||
if (peer->ip_addr == ip) {
|
||||
// Instead of removing it from the list we'll make it timeout since most Matching games are moving group and may still need the peer data
|
||||
peer->last_recv = 0;
|
||||
|
||||
|
||||
// Multithreading Lock
|
||||
peerlock.lock();
|
||||
|
||||
// Unlink Left (Beginning)
|
||||
if(prev == NULL)friends = peer->next;
|
||||
/*if (prev == NULL) friends = peer->next;
|
||||
|
||||
// Unlink Left (Other)
|
||||
else prev->next = peer->next;
|
||||
*/
|
||||
|
||||
char tmpmac[18];
|
||||
INFO_LOG(SCENET, "Removing Friend Peer %s [%s]", mac2str(&peer->mac_addr, tmpmac), inet_ntoa(*(in_addr*)&peer->ip_addr));
|
||||
|
||||
// Free Memory
|
||||
//free(peer);
|
||||
//peer = NULL;
|
||||
// Instead of removing it from the list we'll make it timed out since most Matching games are moving group and may still need the peer data thus not recognizing it as Unknown peer
|
||||
peer->last_recv = 0; //CoreTiming::GetGlobalTimeUsScaled();
|
||||
|
||||
// Multithreading Unlock
|
||||
peerlock.unlock();
|
||||
|
||||
// Free Memory
|
||||
free(peer);
|
||||
peer = NULL;
|
||||
|
||||
// Stop Search
|
||||
break;
|
||||
}
|
||||
|
||||
// Set Previous Reference
|
||||
// TODO: Should this be used by something?
|
||||
prev = peer;
|
||||
}
|
||||
}
|
||||
|
||||
int findFreeMatchingID(void) {
|
||||
int findFreeMatchingID() {
|
||||
// Minimum Matching ID
|
||||
int min = 1;
|
||||
|
||||
|
@ -320,13 +351,15 @@ int findFreeMatchingID(void) {
|
|||
int max = 0;
|
||||
|
||||
// Find highest Matching ID
|
||||
SceNetAdhocMatchingContext * item = contexts; for (; item != NULL; item = item->next) {
|
||||
SceNetAdhocMatchingContext * item = contexts;
|
||||
for (; item != NULL; item = item->next) {
|
||||
// New Maximum
|
||||
if (max < item->id) max = item->id;
|
||||
}
|
||||
|
||||
// Find unoccupied ID
|
||||
int i = min; for (; i < max; i++) {
|
||||
int i = min;
|
||||
for (; i < max; i++) {
|
||||
// Found unoccupied ID
|
||||
if (findMatchingContext(i) == NULL) return i;
|
||||
}
|
||||
|
@ -337,7 +370,8 @@ int findFreeMatchingID(void) {
|
|||
|
||||
SceNetAdhocMatchingContext * findMatchingContext(int id) {
|
||||
// Iterate Matching Context List
|
||||
SceNetAdhocMatchingContext * item = contexts; for (; item != NULL; item = item->next) { // Found Matching ID
|
||||
SceNetAdhocMatchingContext * item = contexts;
|
||||
for (; item != NULL; item = item->next) { // Found Matching ID
|
||||
if (item->id == id) return item;
|
||||
}
|
||||
|
||||
|
@ -353,7 +387,8 @@ SceNetAdhocMatchingContext * findMatchingContext(int id) {
|
|||
SceNetAdhocMatchingMemberInternal * findOutgoingRequest(SceNetAdhocMatchingContext * context)
|
||||
{
|
||||
// Iterate Peer List for Matching Target
|
||||
SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next)
|
||||
SceNetAdhocMatchingMemberInternal * peer = context->peerlist;
|
||||
for (; peer != NULL; peer = peer->next)
|
||||
{
|
||||
// Found Peer in List
|
||||
if (peer->state == PSP_ADHOC_MATCHING_PEER_OUTGOING_REQUEST) return peer;
|
||||
|
@ -369,6 +404,8 @@ SceNetAdhocMatchingMemberInternal * findOutgoingRequest(SceNetAdhocMatchingConte
|
|||
*/
|
||||
void postAcceptCleanPeerList(SceNetAdhocMatchingContext * context)
|
||||
{
|
||||
int delcount = 0;
|
||||
int peercount = 0;
|
||||
// Acquire Peer Lock
|
||||
peerlock.lock();
|
||||
|
||||
|
@ -380,14 +417,20 @@ void postAcceptCleanPeerList(SceNetAdhocMatchingContext * context)
|
|||
SceNetAdhocMatchingMemberInternal * next = peer->next;
|
||||
|
||||
// Unneeded Peer
|
||||
if (peer->state != PSP_ADHOC_MATCHING_PEER_CHILD && peer->state != PSP_ADHOC_MATCHING_PEER_P2P && peer->state != PSP_ADHOC_MATCHING_PEER_PARENT) deletePeer(context, peer);
|
||||
if (peer->state != PSP_ADHOC_MATCHING_PEER_CHILD && peer->state != PSP_ADHOC_MATCHING_PEER_P2P && peer->state != PSP_ADHOC_MATCHING_PEER_PARENT) {
|
||||
deletePeer(context, peer);
|
||||
delcount++;
|
||||
}
|
||||
|
||||
// Move to Next Peer
|
||||
peer = next;
|
||||
peercount++;
|
||||
}
|
||||
|
||||
// Free Peer Lock
|
||||
peerlock.unlock();
|
||||
|
||||
INFO_LOG(SCENET, "Removing Unneeded Peer (%i/%i)", delcount, peercount);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -404,7 +447,7 @@ void postAcceptAddSiblings(SceNetAdhocMatchingContext * context, int siblingcoun
|
|||
uint8_t * siblings_u8 = (uint8_t *)siblings;
|
||||
|
||||
// Iterate Siblings
|
||||
int i = 0; for (; i < siblingcount; i++)
|
||||
for (int i = 0; i < siblingcount; i++)
|
||||
{
|
||||
// Allocate Memory
|
||||
SceNetAdhocMatchingMemberInternal * sibling = (SceNetAdhocMatchingMemberInternal *)malloc(sizeof(SceNetAdhocMatchingMemberInternal));
|
||||
|
@ -431,7 +474,8 @@ void postAcceptAddSiblings(SceNetAdhocMatchingContext * context, int siblingcoun
|
|||
// Spawn Established Event
|
||||
spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_ESTABLISHED, &sibling->mac, 0, NULL);
|
||||
|
||||
INFO_LOG(SCENET, "Accepting Peer %02X:%02X:%02X:%02X:%02X:%02X", sibling->mac.data[0], sibling->mac.data[1], sibling->mac.data[2], sibling->mac.data[3], sibling->mac.data[4], sibling->mac.data[5]);
|
||||
char tmpmac[18];
|
||||
INFO_LOG(SCENET, "Accepting Peer %s", mac2str(&sibling->mac, tmpmac));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -441,14 +485,17 @@ void postAcceptAddSiblings(SceNetAdhocMatchingContext * context, int siblingcoun
|
|||
* @param context Matching Context Pointer
|
||||
* @return Number of Children
|
||||
*/
|
||||
s32_le countChildren(SceNetAdhocMatchingContext * context)
|
||||
s32_le countChildren(SceNetAdhocMatchingContext * context, const bool excludeTimedout)
|
||||
{
|
||||
// Children Counter
|
||||
s32_le count = 0;
|
||||
|
||||
// Iterate Peer List for Matching Target
|
||||
SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next)
|
||||
SceNetAdhocMatchingMemberInternal * peer = context->peerlist;
|
||||
for (; peer != NULL; peer = peer->next)
|
||||
{
|
||||
// Exclude timedout members?
|
||||
if (!excludeTimedout || peer->lastping != 0)
|
||||
// Increase Children Counter
|
||||
if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) count++;
|
||||
}
|
||||
|
@ -466,7 +513,8 @@ s32_le countChildren(SceNetAdhocMatchingContext * context)
|
|||
SceNetAdhocMatchingMemberInternal * findPeer(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac)
|
||||
{
|
||||
// Iterate Peer List for Matching Target
|
||||
SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next)
|
||||
SceNetAdhocMatchingMemberInternal * peer = context->peerlist;
|
||||
for (; peer != NULL; peer = peer->next)
|
||||
{
|
||||
// Found Peer in List
|
||||
if (memcmp(&peer->mac, mac, sizeof(SceNetEtherAddr)) == 0)
|
||||
|
@ -488,7 +536,8 @@ SceNetAdhocMatchingMemberInternal * findPeer(SceNetAdhocMatchingContext * contex
|
|||
SceNetAdhocMatchingMemberInternal * findParent(SceNetAdhocMatchingContext * context)
|
||||
{
|
||||
// Iterate Peer List for Matching Target
|
||||
SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next)
|
||||
SceNetAdhocMatchingMemberInternal * peer = context->peerlist;
|
||||
for (; peer != NULL; peer = peer->next)
|
||||
{
|
||||
// Found Peer in List
|
||||
if (peer->state == PSP_ADHOC_MATCHING_PEER_PARENT) return peer;
|
||||
|
@ -503,12 +552,14 @@ SceNetAdhocMatchingMemberInternal * findParent(SceNetAdhocMatchingContext * cont
|
|||
* @param context Matching Context Pointer
|
||||
* @return Internal Peer Reference or... NULL
|
||||
*/
|
||||
SceNetAdhocMatchingMemberInternal * findP2P(SceNetAdhocMatchingContext * context)
|
||||
SceNetAdhocMatchingMemberInternal * findP2P(SceNetAdhocMatchingContext * context, const bool excludeTimedout)
|
||||
{
|
||||
// Iterate Peer List for Matching Target
|
||||
SceNetAdhocMatchingMemberInternal * peer = context->peerlist;
|
||||
for (; peer != NULL; peer = peer->next)
|
||||
{
|
||||
// Exclude timedout members?
|
||||
if (!excludeTimedout || peer->lastping != 0)
|
||||
// Found Peer in List
|
||||
if (peer->state == PSP_ADHOC_MATCHING_PEER_P2P) return peer;
|
||||
}
|
||||
|
@ -550,7 +601,8 @@ void deletePeer(SceNetAdhocMatchingContext * context, SceNetAdhocMatchingMemberI
|
|||
// Beginning Item
|
||||
else context->peerlist = item->next;
|
||||
|
||||
INFO_LOG(SCENET, "Removing Peer %02X:%02X:%02X:%02X:%02X:%02X", peer->mac.data[0], peer->mac.data[1], peer->mac.data[2], peer->mac.data[3], peer->mac.data[4], peer->mac.data[5]);
|
||||
char tmpmac[18];
|
||||
INFO_LOG(SCENET, "Removing Member Peer %s", mac2str(&peer->mac, tmpmac));
|
||||
}
|
||||
|
||||
// Free Peer Memory
|
||||
|
@ -741,7 +793,7 @@ void sendDeathMessage(SceNetAdhocMatchingContext * context, SceNetAdhocMatchingM
|
|||
* @param context Matching Context Pointer
|
||||
* @return Number of Connected Peers
|
||||
*/
|
||||
uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context)
|
||||
uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context, const bool excludeTimedout)
|
||||
{
|
||||
// Peer Count
|
||||
uint32_t count = 0;
|
||||
|
@ -750,7 +802,7 @@ uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context)
|
|||
if (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT)
|
||||
{
|
||||
// Number of Children + 1 Parent (Self)
|
||||
count = countChildren(context) + 1;
|
||||
count = countChildren(context, excludeTimedout) + 1;
|
||||
}
|
||||
|
||||
// Child Mode
|
||||
|
@ -763,7 +815,7 @@ uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context)
|
|||
if (findParent(context) != NULL)
|
||||
{
|
||||
// Add Number of Siblings + 1 Parents
|
||||
count += countChildren(context) + 1;
|
||||
count += countChildren(context, excludeTimedout) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -774,7 +826,7 @@ uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context)
|
|||
count = 1;
|
||||
|
||||
// Connected to another P2P Client
|
||||
if (findP2P(context) != NULL)
|
||||
if (findP2P(context, excludeTimedout) != NULL)
|
||||
{
|
||||
// Add P2P Brother
|
||||
count++;
|
||||
|
@ -801,31 +853,35 @@ void spawnLocalEvent(SceNetAdhocMatchingContext * context, int event, SceNetEthe
|
|||
|
||||
/**
|
||||
* Handle Timeouts in Matching Context
|
||||
* @param context Matchi]ng Context Pointer
|
||||
* @param context Matching Context Pointer
|
||||
*/
|
||||
void handleTimeout(SceNetAdhocMatchingContext * context)
|
||||
{
|
||||
peerlock.lock();
|
||||
// Iterate Peer List
|
||||
SceNetAdhocMatchingMemberInternal * peer = context->peerlist; while (peer != NULL)
|
||||
SceNetAdhocMatchingMemberInternal * peer = context->peerlist;
|
||||
while (peer != NULL && contexts != NULL && coreState != CORE_POWERDOWN)
|
||||
{
|
||||
// Get Next Pointer (to avoid crash on memory freeing)
|
||||
SceNetAdhocMatchingMemberInternal * next = peer->next;
|
||||
|
||||
u64_le now = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0
|
||||
// Timeout!
|
||||
// Timeout!, may be we shouldn't kick timedout members ourself and let the game do it
|
||||
if ((now - peer->lastping) >= context->timeout)
|
||||
{
|
||||
// Spawn Timeout Event
|
||||
if ((context->mode == PSP_ADHOC_MATCHING_MODE_CHILD && (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD || peer->state == PSP_ADHOC_MATCHING_PEER_PARENT)) ||
|
||||
(context->mode == PSP_ADHOC_MATCHING_MODE_PARENT && peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) ||
|
||||
(context->mode == PSP_ADHOC_MATCHING_MODE_P2P && peer->state == PSP_ADHOC_MATCHING_PEER_P2P))
|
||||
spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_TIMEOUT, &peer->mac, 0, NULL);
|
||||
(context->mode == PSP_ADHOC_MATCHING_MODE_P2P && peer->state == PSP_ADHOC_MATCHING_PEER_P2P)) {
|
||||
spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_TIMEOUT, &peer->mac, 0, NULL); // This is the only code that use PSP_ADHOC_MATCHING_EVENT_TIMEOUT, should we let it timedout?
|
||||
}
|
||||
|
||||
INFO_LOG(SCENET, "TimedOut Peer %02X:%02X:%02X:%02X:%02X:%02X (%lldms)", peer->mac.data[0], peer->mac.data[1], peer->mac.data[2], peer->mac.data[3], peer->mac.data[4], peer->mac.data[5], (context->timeout/1000));
|
||||
char tmpmac[18];
|
||||
INFO_LOG(SCENET, "TimedOut Member Peer %s (%lldms)", mac2str(&peer->mac, tmpmac), (context->timeout/1000));
|
||||
|
||||
// Delete Peer from List
|
||||
deletePeer(context, peer);
|
||||
//peer->lastping = 0; //Let's just make the game kick timedout members during sceNetAdhocMatchingGetMembers
|
||||
}
|
||||
|
||||
// Move Pointer
|
||||
|
@ -845,6 +901,7 @@ void clearStackRecursive(ThreadMessage * node)
|
|||
|
||||
// Free Last Existing Node of List (NULL is handled in _free)
|
||||
free(node);
|
||||
node = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -901,6 +958,8 @@ void clearPeerList(SceNetAdhocMatchingContext * context)
|
|||
|
||||
// Delete Peer
|
||||
free(peer); //deletePeer(context, peer);
|
||||
// Instead of removing peer immediately, We should give a little time before removing the peer and let it timed out? just in case the game is in the middle of communicating with the peer on another thread so it won't recognize it as Unknown peer
|
||||
//peer->lastping = CoreTiming::GetGlobalTimeUsScaled();
|
||||
|
||||
// Move Pointer
|
||||
peer = context->peerlist; //peer = next;
|
||||
|
@ -910,36 +969,23 @@ void clearPeerList(SceNetAdhocMatchingContext * context)
|
|||
peerlock.unlock();
|
||||
}
|
||||
|
||||
bool IsMatchingInCallback(SceNetAdhocMatchingContext * context) {
|
||||
bool inCB = false;
|
||||
if (context == NULL) return inCB;
|
||||
context->eventlock->lock(); //peerlock.lock();
|
||||
inCB = (/*context != NULL &&*/ context->IsMatchingInCB);
|
||||
context->eventlock->unlock(); //peerlock.unlock();
|
||||
return inCB;
|
||||
}
|
||||
|
||||
// It seems After Actions being called in reverse order of Mipscall order (ie. MipsCall order of ACCEPT(6)->ESTABLISH(7) getting AfterAction order of ESTABLISH(7)->ACCEPT(6)
|
||||
void AfterMatchingMipsCall::run(MipsCall &call) {
|
||||
if (!context || !context->eventlock)
|
||||
return;
|
||||
|
||||
DEBUG_LOG(SCENET, "Entering AfterMatchingMipsCall::run [ID=%i][Event=%d] [cbId: %u]", context->id, EventID, call.cbId);
|
||||
//u32 v0 = currentMIPS->r[MIPS_REG_V0];
|
||||
if (__IsInInterrupt()) ERROR_LOG(SCENET, "AfterMatchingMipsCall::run [ID=%i][Event=%d] is Returning Inside an Interrupt!", context->id, EventID);
|
||||
//while (__IsInInterrupt()) sleep_ms(1); // Must not sleep inside callback handler
|
||||
context->eventlock->lock(); //peerlock.lock();
|
||||
//SceNetAdhocMatchingContext * context = findMatchingContext(ID);
|
||||
//if (context != NULL)
|
||||
{
|
||||
context->IsMatchingInCB = false;
|
||||
if (context == NULL) {
|
||||
peerlock.lock();
|
||||
context = findMatchingContext(contextID);
|
||||
peerlock.unlock();
|
||||
}
|
||||
context->eventlock->unlock(); //peerlock.unlock();
|
||||
//call.setReturnValue(v0);
|
||||
u32 v0 = currentMIPS->r[MIPS_REG_V0];
|
||||
if (__IsInInterrupt()) ERROR_LOG(SCENET, "AfterMatchingMipsCall::run [ID=%i][Event=%d] is Returning Inside an Interrupt!", contextID, EventID);
|
||||
if (Memory::IsValidAddress(bufAddr)) userMemory.Free(bufAddr);
|
||||
DEBUG_LOG(SCENET, "Leaving AfterMatchingMipsCall::run [ID=%i][Event=%d] [retV0: %08x]", context->id, EventID, currentMIPS->r[MIPS_REG_V0]);
|
||||
SetMatchingInCallback(context, false);
|
||||
DEBUG_LOG(SCENET, "AfterMatchingMipsCall::run [ID=%i][Event=%d] [cbId: %u][retV0: %08x]", contextID, EventID, call.cbId, v0);
|
||||
//call.setReturnValue(v0);
|
||||
}
|
||||
|
||||
void AfterMatchingMipsCall::SetContextID(u32 ContextID, u32 eventId, u32_le BufAddr) {
|
||||
void AfterMatchingMipsCall::SetData(int ContextID, int eventId, u32_le BufAddr) {
|
||||
contextID = ContextID;
|
||||
EventID = eventId;
|
||||
bufAddr = BufAddr;
|
||||
peerlock.lock();
|
||||
|
@ -947,61 +993,100 @@ void AfterMatchingMipsCall::SetContextID(u32 ContextID, u32 eventId, u32_le BufA
|
|||
peerlock.unlock();
|
||||
}
|
||||
|
||||
bool SetMatchingInCallback(SceNetAdhocMatchingContext* context, bool IsInCB) {
|
||||
if (context == NULL) return false;
|
||||
context->eventlock->lock(); //peerlock.lock();
|
||||
context->IsMatchingInCB = IsInCB;
|
||||
context->eventlock->unlock(); //peerlock.unlock();
|
||||
return IsInCB;
|
||||
}
|
||||
|
||||
bool IsMatchingInCallback(SceNetAdhocMatchingContext* context) {
|
||||
bool inCB = false;
|
||||
if (context == NULL) return inCB;
|
||||
context->eventlock->lock(); //peerlock.lock();
|
||||
inCB = (context->IsMatchingInCB);
|
||||
context->eventlock->unlock(); //peerlock.unlock();
|
||||
return inCB;
|
||||
}
|
||||
|
||||
void AfterAdhocMipsCall::run(MipsCall& call) {
|
||||
u32 v0 = currentMIPS->r[MIPS_REG_V0];
|
||||
if (__IsInInterrupt()) ERROR_LOG(SCENET, "AfterAdhocMipsCall::run [ID=%i][Event=%d] is Returning Inside an Interrupt!", HandlerID, EventID);
|
||||
SetAdhocctlInCallback(false);
|
||||
DEBUG_LOG(SCENET, "AfterAdhocMipsCall::run [ID=%i][Event=%d] [cbId: %u][retV0: %08x]", HandlerID, EventID, call.cbId, v0);
|
||||
//call.setReturnValue(v0);
|
||||
}
|
||||
|
||||
void AfterAdhocMipsCall::SetData(int handlerID, int eventId, u32_le ArgsAddr) {
|
||||
HandlerID = handlerID;
|
||||
EventID = eventId;
|
||||
argsAddr = ArgsAddr;
|
||||
}
|
||||
|
||||
int SetAdhocctlInCallback(bool IsInCB) {
|
||||
std::lock_guard<std::recursive_mutex> adhocGuard(adhocEvtMtx);
|
||||
IsAdhocctlInCB += (IsInCB?1:-1);
|
||||
return IsAdhocctlInCB;
|
||||
}
|
||||
|
||||
int IsAdhocctlInCallback() {
|
||||
std::lock_guard<std::recursive_mutex> adhocGuard(adhocEvtMtx);
|
||||
int inCB = IsAdhocctlInCB;
|
||||
return inCB;
|
||||
}
|
||||
|
||||
// Make sure MIPS calls have been fully executed before the next notifyAdhocctlHandlers
|
||||
void notifyAdhocctlHandlers(u32 flag, u32 error) {
|
||||
__UpdateAdhocctlHandlers(flag, error);
|
||||
// TODO: We should use after action instead of guessing the time like this
|
||||
//sleep_ms(20); // Ugly workaround to give time for the mips callback to fully executed, usually only need <16ms
|
||||
}
|
||||
|
||||
// Matching callback is void function: typedef void(*SceNetAdhocMatchingHandler)(int id, int event, SceNetEtherAddr * peer, int optlen, void * opt);
|
||||
// Important! The MIPS call need to be fully executed before the next MIPS call invoked, as the game (ie. DBZ Tag Team) may need to prepare something for the next callback event to use
|
||||
// Note: Must not lock peerlock within this function to prevent race-condition with other thread whos owning peerlock and trying to lock context->eventlock owned by this thread
|
||||
void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * msg, void * opt, u32 &bufAddr, u32 &bufLen, u32_le * args) {
|
||||
//u32_le args[5] = { 0, 0, 0, 0, 0 };
|
||||
/*if ((s32)bufLen < (msg->optlen + 8)) {
|
||||
bufLen = msg->optlen + 8;
|
||||
if (Memory::IsValidAddress(bufAddr)) userMemory.Free(bufAddr);
|
||||
bufAddr = userMemory.Alloc(bufLen); // Max bufLen should be context->rxbuflen
|
||||
INFO_LOG(SCENET, "MatchingHandler: Alloc(%i -> %i) = %08x", msg->optlen + 8, bufLen, bufAddr);
|
||||
}*/
|
||||
void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * msg, void * opt, u32_le &bufAddr, u32_le &bufLen, u32_le * args) {
|
||||
// Don't share buffer address space with other mipscall in the queue since mipscalls aren't immediately executed
|
||||
MatchingArgs argsNew;
|
||||
bufAddr = userMemory.Alloc(bufLen); // We will free this after returning from mipscall
|
||||
u8 * optPtr = Memory::GetPointer(bufAddr);
|
||||
memcpy(optPtr, &msg->mac, sizeof(msg->mac));
|
||||
if (msg->optlen > 0) memcpy(optPtr + 8, opt, msg->optlen);
|
||||
u32_le dataBufLen = msg->optlen + 8; //max(bufLen, msg->optlen + 8);
|
||||
u32_le dataBufAddr = userMemory.Alloc(dataBufLen); // We will free this memory after returning from mipscall
|
||||
uint8_t * dataPtr = Memory::GetPointer(dataBufAddr);
|
||||
memcpy(dataPtr, &msg->mac, sizeof(msg->mac));
|
||||
if (msg->optlen > 0)
|
||||
memcpy(dataPtr + 8, opt, msg->optlen);
|
||||
argsNew.data[0] = context->id;
|
||||
argsNew.data[1] = msg->opcode;
|
||||
argsNew.data[2] = bufAddr; // PSP_GetScratchpadMemoryBase() + 0x6000;
|
||||
argsNew.data[2] = dataBufAddr;
|
||||
argsNew.data[3] = msg->optlen;
|
||||
argsNew.data[4] = argsNew.data[2] + 8; // OptData Addr
|
||||
argsNew.data[4] = dataBufAddr + 8; // OptData Addr
|
||||
argsNew.data[5] = context->handler.entryPoint; //not part of callback argument, just borrowing a space to store callback address so i don't need to search the context first later
|
||||
|
||||
context->eventlock->lock();
|
||||
context->IsMatchingInCB = true;
|
||||
context->eventlock->unlock();
|
||||
// ScheduleEvent_Threadsafe_Immediate seems to get mixed up with interrupt (returning from mipscall inside an interrupt) and getting invalid address before returning from interrupt
|
||||
__UpdateMatchingHandler(argsNew);
|
||||
|
||||
// Make sure MIPS call have been fully executed before the next notifyMatchingHandler
|
||||
/*int count = 0;
|
||||
while ( IsMatchingInCallback(context) && (count < 250)) {
|
||||
sleep_ms(1);
|
||||
count++;
|
||||
}
|
||||
if (count >= 250) ERROR_LOG(SCENET, "MatchingHandler: Callback Failed to Return within %dms! [ID=%i][Opcode=%d][OptSize=%d][MAC=%012X]", count, context->id, msg->opcode, msg->optlen, htonl(*(u_long*)&msg->mac));*/
|
||||
//sleep_ms(20); // Wait a little more (for context switching may be?) to prevent DBZ Tag Team from getting connection lost, but this will cause lags on Lord of Arcana
|
||||
}
|
||||
|
||||
void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node) {
|
||||
void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count) {
|
||||
// End of List
|
||||
if (node == NULL) return;
|
||||
|
||||
// Increase Recursion Depth
|
||||
freeFriendsRecursive(node->next);
|
||||
freeFriendsRecursive(node->next, count);
|
||||
|
||||
// Free Memory
|
||||
free(node);
|
||||
node = NULL;
|
||||
if (count != NULL) (*count)++;
|
||||
}
|
||||
|
||||
void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo* node, int32_t* count) {
|
||||
// End of List
|
||||
if (node == NULL) return;
|
||||
|
||||
// Increase Recursion Depth
|
||||
timeoutFriendsRecursive(node->next, count);
|
||||
|
||||
// Set last timestamp
|
||||
node->last_recv = 0;
|
||||
if (count != NULL) (*count)++;
|
||||
}
|
||||
|
||||
void sendChat(std::string chatString) {
|
||||
|
@ -1044,6 +1129,7 @@ std::vector<std::string> getChatLog() {
|
|||
}
|
||||
|
||||
int friendFinder(){
|
||||
setCurrentThreadName("FriendFinder");
|
||||
// Receive Buffer
|
||||
int rxpos = 0;
|
||||
uint8_t rx[1024];
|
||||
|
@ -1069,7 +1155,7 @@ int friendFinder(){
|
|||
//_acquireNetworkLock();
|
||||
|
||||
// Ping Server
|
||||
now = real_time_now()*1000000.0; // should be in microseconds, but it seems real_time_now() returns in seconds
|
||||
now = real_time_now() * 1000000.0; // CoreTiming::GetGlobalTimeUsScaled(); // Use real_time_now()*1000000.0 if the game gets disconnected from AdhocServer too fast when FPS wasn't stable
|
||||
if (now - lastping >= PSP_ADHOCCTL_PING_TIMEOUT) { //100 // We need to use lower interval to prevent getting timeout at Pro Adhoc Server through internet
|
||||
// original code : ((sceKernelGetSystemTimeWide() - lastping) >= ADHOCCTL_PING_TIMEOUT)
|
||||
// Update Ping Time
|
||||
|
@ -1106,18 +1192,33 @@ int friendFinder(){
|
|||
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;
|
||||
|
||||
char tmpmac[18];
|
||||
INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT_BSSID [%s]", mac2str(&packet->mac, tmpmac));
|
||||
// from JPCSP: Some games have problems when the PSP_ADHOCCTL_EVENT_CONNECTED is sent too quickly after connecting to a network. The connection will be set CONNECTED with a small delay (200ms or 200us?)
|
||||
/*if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) {
|
||||
setState(ADHOCCTL_STATE_GAMEMODE);
|
||||
notifyAdhocctlHandlers(ADHOCCTL_EVENT_GAME, 0);
|
||||
}
|
||||
else {
|
||||
setState(ADHOCCTL_STATE_CONNECTED);
|
||||
notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0);
|
||||
}*/
|
||||
|
||||
// Update User BSSID
|
||||
//parameter.bssid.mac_addr = packet->mac; // The MAC address in this packet seems to Always be the First player joining the Group (group Creator?), Shouldn't it be it self?
|
||||
// Notify Event Handlers
|
||||
//notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0);
|
||||
// Change State
|
||||
threadStatus = ADHOCCTL_STATE_CONNECTED;
|
||||
// Notify Event Handlers
|
||||
notifyAdhocctlHandlers(ADHOCCTL_EVENT_CONNECT, 0);
|
||||
|
||||
// Give time a little time
|
||||
//sceKernelDelayThread(adhocEventDelayMS * 1000);
|
||||
//sleep_ms(adhocEventDelayMS);
|
||||
|
||||
// Move RX Buffer
|
||||
memmove(rx, rx + sizeof(SceNetAdhocctlConnectBSSIDPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectBSSIDPacketS2C));
|
||||
|
||||
|
@ -1128,11 +1229,16 @@ int friendFinder(){
|
|||
|
||||
// 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;
|
||||
INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CHAT");
|
||||
|
||||
// Fix strings with null-terminated
|
||||
packet->name.data[ADHOCCTL_NICKNAME_LEN - 1] = 0;
|
||||
packet->base.message[ADHOCCTL_MESSAGE_LEN - 1] = 0;
|
||||
|
||||
// Add Incoming Chat to HUD
|
||||
NOTICE_LOG(SCENET, "Received chat message %s", packet->base.message);
|
||||
incoming = "";
|
||||
|
@ -1150,6 +1256,7 @@ int friendFinder(){
|
|||
newChat += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Move RX Buffer
|
||||
memmove(rx, rx + sizeof(SceNetAdhocctlChatPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlChatPacketS2C));
|
||||
|
||||
|
@ -1160,17 +1267,28 @@ int friendFinder(){
|
|||
|
||||
// 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;
|
||||
|
||||
DEBUG_LOG(SCENET, "FriendFinder: OPCODE_CONNECT");
|
||||
|
||||
// Fix strings with null-terminated
|
||||
packet->name.data[ADHOCCTL_NICKNAME_LEN - 1] = 0;
|
||||
|
||||
// Log Incoming Peer
|
||||
INFO_LOG(SCENET, "Incoming Peer Data...");
|
||||
|
||||
// Add User
|
||||
addFriend(packet);
|
||||
|
||||
/* // Make sure GameMode participants are all joined (including self MAC)
|
||||
if (adhocctlCurrentMode == PSP_ADHOCCTL_MODE_GAMEMODE) {
|
||||
// From JPCSP: Join complete when all the required MACs have joined
|
||||
}*/
|
||||
|
||||
// Update HUD User Count
|
||||
incoming = "";
|
||||
incoming.append((char *)packet->name.data);
|
||||
incoming.append(" Joined ");
|
||||
|
@ -1181,7 +1299,7 @@ int friendFinder(){
|
|||
if (chatScreenVisible) {
|
||||
updateChatScreen = true;
|
||||
}
|
||||
// Update HUD User Count
|
||||
|
||||
#ifdef LOCALHOST_AS_PEER
|
||||
setUserCount(getActivePeerCount());
|
||||
#else
|
||||
|
@ -1198,15 +1316,16 @@ int friendFinder(){
|
|||
|
||||
// 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;
|
||||
|
||||
DEBUG_LOG(SCENET, "FriendFinder: OPCODE_DISCONNECT");
|
||||
|
||||
// Log Incoming Peer Delete Request
|
||||
INFO_LOG(SCENET, "FriendFinder: Incoming Peer Data Delete Request...");
|
||||
|
||||
// Delete User by IP, should delete by MAC since IP can be shared (behind NAT) isn't?
|
||||
deleteFriendByIP(packet->ip);
|
||||
|
||||
|
@ -1227,14 +1346,16 @@ int friendFinder(){
|
|||
|
||||
// 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;
|
||||
|
||||
DEBUG_LOG(SCENET, "FriendFinder: OPCODE_SCAN");
|
||||
|
||||
// Log Incoming Network Information
|
||||
INFO_LOG(SCENET, "Incoming Group Information...");
|
||||
|
||||
// Multithreading Lock
|
||||
peerlock.lock();
|
||||
|
||||
|
@ -1242,20 +1363,17 @@ int friendFinder(){
|
|||
SceNetAdhocctlScanInfo * group = findGroup(&packet->mac);
|
||||
|
||||
if (group != NULL) {
|
||||
// Copy Group Name
|
||||
group->group_name = packet->group;
|
||||
// Copy Group Name
|
||||
group->group_name = packet->group;
|
||||
|
||||
// Set Group Host
|
||||
group->bssid.mac_addr = packet->mac;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
if (group != NULL) {
|
||||
// Clear Memory, should this be done only when allocating new group?
|
||||
memset(group, 0, sizeof(SceNetAdhocctlScanInfo));
|
||||
|
||||
|
@ -1268,6 +1386,10 @@ int friendFinder(){
|
|||
// Set Group Host
|
||||
group->bssid.mac_addr = packet->mac;
|
||||
|
||||
// Set group parameters
|
||||
group->channel = parameter.channel;
|
||||
group->mode = ADHOCCTL_MODE_ADHOC; //adhocctlCurrentMode;
|
||||
|
||||
// Link into Group List
|
||||
newnetworks = group;
|
||||
}
|
||||
|
@ -1297,16 +1419,18 @@ int friendFinder(){
|
|||
newnetworks = NULL;
|
||||
peerlock.unlock();
|
||||
|
||||
// Change State
|
||||
threadStatus = ADHOCCTL_STATE_DISCONNECTED;
|
||||
|
||||
// Notify Event Handlers
|
||||
notifyAdhocctlHandlers(ADHOCCTL_EVENT_SCAN, 0);
|
||||
//notifyAdhocctlHandlers(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]);
|
||||
//}
|
||||
// Change State
|
||||
threadStatus = ADHOCCTL_STATE_DISCONNECTED;
|
||||
// Give time a little time
|
||||
//sceKernelDelayThread(adhocEventDelayMS * 1000);
|
||||
//sleep_ms(adhocEventDelayMS);
|
||||
|
||||
// Move RX Buffer
|
||||
memmove(rx, rx + 1, sizeof(rx) - 1);
|
||||
|
@ -1315,11 +1439,11 @@ int friendFinder(){
|
|||
rxpos -= 1;
|
||||
}
|
||||
}
|
||||
// Original value was 10 ms, I think 100 is just fine
|
||||
sleep_ms(1); // Using 1ms for faster response just like AdhocServer
|
||||
// This delay time should be 100ms when there is an event otherwise 500ms ?
|
||||
sleep_ms(1); // Using 1ms for faster response just like AdhocServer?
|
||||
|
||||
// Don't do anything if it's paused, otherwise the log will be flooded
|
||||
while (Core_IsStepping() && friendFinderRunning) sleep_ms(1);
|
||||
while (Core_IsStepping() && coreState != CORE_POWERDOWN && friendFinderRunning) sleep_ms(1);
|
||||
}
|
||||
|
||||
// Groups/Networks should be deallocated isn't?
|
||||
|
@ -1334,7 +1458,7 @@ int friendFinder(){
|
|||
return 0;
|
||||
}
|
||||
|
||||
int getActivePeerCount(void) {
|
||||
int getActivePeerCount(const bool excludeTimedout) {
|
||||
// Counter
|
||||
int count = 0;
|
||||
|
||||
|
@ -1348,8 +1472,9 @@ int getActivePeerCount(void) {
|
|||
|
||||
// Iterate Peers
|
||||
for (; peer != NULL; peer = peer->next) {
|
||||
// Increase Counter
|
||||
count++;
|
||||
// Increase Counter, Should we exclude peers pending for timed out?
|
||||
if (!excludeTimedout || peer->last_recv != 0)
|
||||
count++;
|
||||
}
|
||||
|
||||
// Return Result
|
||||
|
@ -1365,7 +1490,7 @@ int getLocalIp(sockaddr_in * SocketAddress){
|
|||
// Error handling
|
||||
}
|
||||
// Get local IP addresses
|
||||
struct hostent *pHost = 0;
|
||||
struct hostent *pHost = 0;
|
||||
pHost = ::gethostbyname(szHostName);
|
||||
if(pHost) {
|
||||
memcpy(&SocketAddress->sin_addr, pHost->h_addr_list[0], pHost->h_length);
|
||||
|
@ -1376,7 +1501,6 @@ int getLocalIp(sockaddr_in * SocketAddress){
|
|||
}
|
||||
return -1;
|
||||
#else
|
||||
memcpy(&SocketAddress->sin_addr, &localip, sizeof(uint32_t));
|
||||
char szHostName[256] = "";
|
||||
gethostname(szHostName, sizeof(szHostName));
|
||||
struct hostent* pHost = 0;
|
||||
|
@ -1388,8 +1512,7 @@ int getLocalIp(sockaddr_in * SocketAddress){
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
//return -1;
|
||||
return 0;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1468,36 +1591,37 @@ int getNicknameCount(const char * nickname)
|
|||
* PDP Socket Counter
|
||||
* @return Number of internal PDP Sockets
|
||||
*/
|
||||
int getPDPSocketCount(void)
|
||||
int getPDPSocketCount()
|
||||
{
|
||||
// Socket Counter
|
||||
int counter = 0;
|
||||
|
||||
// Count Sockets
|
||||
int i = 0; for (; i < 255; i++) if (pdp[i] != NULL) counter++;
|
||||
for (int i = 0; i < 255; i++) if (pdp[i] != NULL) counter++;
|
||||
|
||||
// Return Socket Count
|
||||
return counter;
|
||||
}
|
||||
|
||||
int getPTPSocketCount(void) {
|
||||
int getPTPSocketCount() {
|
||||
// Socket Counter
|
||||
int counter = 0;
|
||||
|
||||
// Count Sockets
|
||||
int i = 0; for (; i < 255; i++) if (ptp[i] != NULL) counter++;
|
||||
for (int i = 0; i < 255; i++) if (ptp[i] != NULL) counter++;
|
||||
|
||||
// Return Socket Count
|
||||
return counter;
|
||||
}
|
||||
|
||||
int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){
|
||||
auto n = GetI18NCategory("Networking");
|
||||
int iResult = 0;
|
||||
metasocket = (int)INVALID_SOCKET;
|
||||
metasocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (metasocket == INVALID_SOCKET){
|
||||
ERROR_LOG(SCENET, "Invalid socket");
|
||||
return -1;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
struct sockaddr_in server_addr;
|
||||
server_addr.sin_family = AF_INET;
|
||||
|
@ -1512,7 +1636,7 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){
|
|||
iResult = getaddrinfo(g_Config.proAdhocServer.c_str(),0,NULL,&resultAddr);
|
||||
if (iResult != 0) {
|
||||
ERROR_LOG(SCENET, "DNS Error (%s)\n", g_Config.proAdhocServer.c_str());
|
||||
host->NotifyUserMessage("DNS Error connecting to " + g_Config.proAdhocServer, 8.0f);
|
||||
host->NotifyUserMessage(n->T("DNS Error connecting to ") + g_Config.proAdhocServer, 5.0f, 0x0000ff);
|
||||
return iResult;
|
||||
}
|
||||
for (ptr = resultAddr; ptr != NULL; ptr = ptr->ai_next) {
|
||||
|
@ -1537,26 +1661,31 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){
|
|||
iResult = bind(metasocket, (struct sockaddr*) & localIP, sizeof(sockaddr));
|
||||
if (iResult == SOCKET_ERROR) {
|
||||
ERROR_LOG(SCENET, "Bind to alternate localhost[%s] failed(%i).", inet_ntoa(((struct sockaddr_in*) & localIP)->sin_addr), iResult);
|
||||
host->NotifyUserMessage(std::string(n->T("Failed to Bind Localhost IP")) + " " + inet_ntoa(((struct sockaddr_in*) & localIP)->sin_addr), 3.0, 0x0000ff);
|
||||
}
|
||||
}
|
||||
|
||||
// Default/Initial Network
|
||||
memset(¶meter, 0, sizeof(parameter));
|
||||
strcpy((char *)¶meter.nickname.data, g_Config.sNickName.c_str());
|
||||
parameter.channel = 1; // Fake Channel 1
|
||||
parameter.channel = g_Config.iWlanAdhocChannel; // Fake Channel, 0 = Auto where JPCSP use 11 as default for Auto (Commonly for Auto: 1, 6, 11)
|
||||
if (parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) parameter.channel = 1;
|
||||
getLocalMac(¶meter.bssid.mac_addr);
|
||||
|
||||
// Default ProductId
|
||||
product_code.type = adhoc_id->type;
|
||||
memcpy(product_code.data, adhoc_id->data, ADHOCCTL_ADHOCID_LEN);
|
||||
|
||||
// Connect to Adhoc Server
|
||||
server_addr.sin_addr = serverIp;
|
||||
iResult = connect(metasocket,(sockaddr *)&server_addr,sizeof(server_addr));
|
||||
if (iResult == SOCKET_ERROR) {
|
||||
uint8_t * sip = (uint8_t *)&server_addr.sin_addr.s_addr;
|
||||
char buffer[512];
|
||||
snprintf(buffer, sizeof(buffer), "Socket error (%i) when connecting to %s/%u.%u.%u.%u:%u", errno, g_Config.proAdhocServer.c_str(), sip[0], sip[1], sip[2], sip[3], ntohs(server_addr.sin_port));
|
||||
snprintf(buffer, sizeof(buffer), "Socket error (%i) when connecting to AdhocServer [%s/%s:%u]", errno, g_Config.proAdhocServer.c_str(), inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port));
|
||||
ERROR_LOG(SCENET, "%s", buffer);
|
||||
host->NotifyUserMessage(buffer, 8.0f);
|
||||
host->NotifyUserMessage(buffer, 5.0f, 0x0000ff);
|
||||
return iResult;
|
||||
}
|
||||
//grab local ip for later use better than constant ip on non windows platform
|
||||
localip = getLocalIp(metasocket);
|
||||
|
||||
// Prepare Login Packet
|
||||
SceNetAdhocctlLoginPacketC2S packet;
|
||||
|
@ -1569,12 +1698,11 @@ int initNetwork(SceNetAdhocctlAdhocId *adhoc_id){
|
|||
int sent = send(metasocket, (char*)&packet, sizeof(packet), 0);
|
||||
changeBlockingMode(metasocket, 1); // Change to non-blocking
|
||||
if (sent > 0) {
|
||||
auto n = GetI18NCategory("Networking");
|
||||
host->NotifyUserMessage(n->T("Network Initialized"), 1.0);
|
||||
return 0;
|
||||
}
|
||||
else{
|
||||
return -1;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1665,7 +1793,7 @@ bool validNetworkName(const SceNetAdhocctlGroupName * group_name) {
|
|||
// Name given
|
||||
if (group_name != NULL) {
|
||||
// Iterate Name Characters
|
||||
int i = 0; for (; i < ADHOCCTL_GROUPNAME_LEN && valid; i++) {
|
||||
for (int i = 0; i < ADHOCCTL_GROUPNAME_LEN && valid; i++) {
|
||||
// End of Name
|
||||
if (group_name->data[i] == 0) break;
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "Core/CoreTiming.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/HLE/HLEHelperThread.h"
|
||||
#include "Core/HLE/sceNetAdhoc.h"
|
||||
#include "Core/HLE/sceKernelThread.h"
|
||||
#include "Core/HLE/sceKernel.h"
|
||||
|
@ -73,7 +74,7 @@ class PointerWrap;
|
|||
#define EINPROGRESS WSAEWOULDBLOCK
|
||||
#define EISCONN WSAEISCONN
|
||||
#define EALREADY WSAEALREADY
|
||||
inline bool connectInProgress(int errcode){ return (errcode == WSAEWOULDBLOCK || errcode == WSAEINVAL || errcode == WSAEALREADY); }
|
||||
inline bool connectInProgress(int errcode){ return (errcode == WSAEWOULDBLOCK || errcode == WSAEINPROGRESS || errcode == WSAEALREADY); }
|
||||
#else
|
||||
#define INVALID_SOCKET -1
|
||||
#define SOCKET_ERROR -1
|
||||
|
@ -101,19 +102,32 @@ inline bool connectInProgress(int errcode){ return (errcode == EINPROGRESS || er
|
|||
#define SERVER_PORT 27312
|
||||
|
||||
// psp strutcs and definitions
|
||||
#define ADHOCCTL_MODE_ADHOC 0
|
||||
#define ADHOCCTL_MODE_NONE -1
|
||||
#define ADHOCCTL_MODE_ADHOC 0 //ADHOCCTL_MODE_NORMAL
|
||||
#define ADHOCCTL_MODE_GAMEMODE 1
|
||||
|
||||
// Event Types for Event Handler
|
||||
#define ADHOCCTL_EVENT_ERROR 0
|
||||
#define ADHOCCTL_EVENT_CONNECT 1
|
||||
#define ADHOCCTL_EVENT_DISCONNECT 2
|
||||
#define ADHOCCTL_EVENT_SCAN 3
|
||||
#define ADHOCCTL_EVENT_GAME 4
|
||||
#define ADHOCCTL_EVENT_DISCOVER 5
|
||||
#define ADHOCCTL_EVENT_WOL 6
|
||||
#define ADHOCCTL_EVENT_WOL_INTERRUPT 7
|
||||
|
||||
// Internal Thread States
|
||||
#define ADHOCCTL_STATE_DISCONNECTED 0
|
||||
#define ADHOCCTL_STATE_CONNECTED 1
|
||||
#define ADHOCCTL_STATE_SCANNING 2
|
||||
#define ADHOCCTL_STATE_GAMEMODE 3
|
||||
#define ADHOCCTL_STATE_DISCOVER 4
|
||||
#define ADHOCCTL_STATE_WOL 5
|
||||
|
||||
// ProductType ( extracted from SSID along with ProductId & GroupName, Pattern = "PSP_([AXS])(.........)_([LG])_(.*)" )
|
||||
#define PSP_ADHOCCTL_TYPE_COMMERCIAL 0
|
||||
#define PSP_ADHOCCTL_TYPE_DEBUG 1
|
||||
#define PSP_ADHOCCTL_TYPE_SYSTEM 2
|
||||
|
||||
// Kernel Utility Netconf Adhoc Types
|
||||
#define UTILITY_NETCONF_TYPE_CONNECT_ADHOC 2
|
||||
|
@ -186,8 +200,8 @@ extern uint8_t broadcastMAC[ETHER_ADDR_LEN];
|
|||
|
||||
// Malloc Pool Information
|
||||
typedef struct SceNetMallocStat {
|
||||
s32_le pool; // Pointer to the pool?
|
||||
s32_le maximum; // Maximum size of the pool?
|
||||
s32_le pool; // Pointer to the pool? // This should be the poolSize isn't?
|
||||
s32_le maximum; // Maximum size of the pool? Maximum usage (ie. pool- free) ?
|
||||
s32_le free; // How much memory is free
|
||||
} PACK SceNetMallocStat;
|
||||
|
||||
|
@ -321,9 +335,6 @@ typedef struct SceNetAdhocGameModeBufferStat {
|
|||
u32_le master;
|
||||
SceNetAdhocGameModeOptData opt;
|
||||
} PACK SceNetAdhocGameModeBufferStat;
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
// Adhoc ID (Game Product Key)
|
||||
#define ADHOCCTL_ADHOCID_LEN 9
|
||||
|
@ -331,7 +342,11 @@ typedef struct SceNetAdhocctlAdhocId {
|
|||
s32_le type;
|
||||
uint8_t data[ADHOCCTL_ADHOCID_LEN];
|
||||
uint8_t padding[3];
|
||||
} SceNetAdhocctlAdhocId; // should this be packed?
|
||||
} PACK SceNetAdhocctlAdhocId; // should this be packed?
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
|
||||
// Internal Matching Peer Information
|
||||
typedef struct SceNetAdhocMatchingMemberInternal {
|
||||
|
@ -459,8 +474,8 @@ typedef struct SceNetAdhocMatchingContext {
|
|||
u64_le timeout;
|
||||
|
||||
// Helper Thread (fake PSP Thread) needed to execute callback
|
||||
//HLEHelperThread *matchingThread;
|
||||
//SceUID matching_thid;
|
||||
HLEHelperThread *matchingThread;
|
||||
SceUID matching_thid;
|
||||
|
||||
// Event Caller Thread
|
||||
std::thread eventThread; // s32_le event_thid;
|
||||
|
@ -704,10 +719,11 @@ typedef struct {
|
|||
SceNetAdhocctlGroupName group;
|
||||
} PACK SceNetAdhocctlConnectPacketC2S;
|
||||
|
||||
#define ADHOCCTL_MESSAGE_LEN 64
|
||||
// C2S Chat Packet
|
||||
typedef struct {
|
||||
SceNetAdhocctlPacketBase base;
|
||||
char message[64];
|
||||
char message[ADHOCCTL_MESSAGE_LEN];
|
||||
} PACK SceNetAdhocctlChatPacketC2S;
|
||||
|
||||
// S2C Connect Packet
|
||||
|
@ -763,30 +779,56 @@ typedef struct {
|
|||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
class AfterAdhocMipsCall : public PSPAction {
|
||||
public:
|
||||
AfterAdhocMipsCall() {}
|
||||
static PSPAction* Create() { return new AfterAdhocMipsCall(); }
|
||||
void DoState(PointerWrap& p) override {
|
||||
auto s = p.Section("AfterAdhocMipsCall", 4, 4);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
p.Do(HandlerID);
|
||||
p.Do(EventID);
|
||||
p.Do(argsAddr);
|
||||
}
|
||||
void run(MipsCall& call) override;
|
||||
void SetData(int handlerID, int eventId, u32_le argsAddr);
|
||||
|
||||
private:
|
||||
int HandlerID = -1;
|
||||
int EventID = -1;
|
||||
u32_le argsAddr = 0;
|
||||
};
|
||||
|
||||
class AfterMatchingMipsCall : public PSPAction {
|
||||
public:
|
||||
AfterMatchingMipsCall() {}
|
||||
static PSPAction *Create() { return new AfterMatchingMipsCall(); }
|
||||
void DoState(PointerWrap &p) override {
|
||||
auto s = p.Section("AfterMatchingMipsCall", 1, 2);
|
||||
auto s = p.Section("AfterMatchingMipsCall", 1, 4);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
p.Do(EventID);
|
||||
if (s >= 4) {
|
||||
p.Do(contextID);
|
||||
p.Do(bufAddr);
|
||||
}
|
||||
//context = NULL;
|
||||
}
|
||||
void run(MipsCall &call) override;
|
||||
void SetContextID(u32 ContextID, u32 eventId, u32_le BufAddr);
|
||||
void SetContext(SceNetAdhocMatchingContext* Context, u32 eventId, u32_le BufAddr) { context = Context; EventID = eventId; bufAddr = BufAddr; }
|
||||
void SetData(int ContextID, int eventId, u32_le BufAddr);
|
||||
|
||||
private:
|
||||
u32 EventID = 0;
|
||||
SceNetAdhocMatchingContext *context = nullptr;
|
||||
int contextID = -1;
|
||||
int EventID = -1;
|
||||
u32_le bufAddr = 0;
|
||||
SceNetAdhocMatchingContext* context = nullptr;
|
||||
};
|
||||
|
||||
extern int actionAfterAdhocMipsCall;
|
||||
extern int actionAfterMatchingMipsCall;
|
||||
extern bool IsAdhocctlInCB;
|
||||
|
||||
// Aux vars
|
||||
extern int metasocket;
|
||||
|
@ -796,7 +838,6 @@ extern std::thread friendFinderThread;
|
|||
extern std::recursive_mutex peerlock;
|
||||
extern SceNetAdhocPdpStat * pdp[255];
|
||||
extern SceNetAdhocPtpStat * ptp[255];
|
||||
extern std::map<int, AdhocctlHandler> adhocctlHandlers;
|
||||
|
||||
extern uint16_t portOffset;
|
||||
extern bool isLocalServer;
|
||||
|
@ -812,27 +853,34 @@ extern int threadStatus;
|
|||
|
||||
// Check if Matching callback is running
|
||||
bool IsMatchingInCallback(SceNetAdhocMatchingContext * context);
|
||||
bool SetMatchingInCallback(SceNetAdhocMatchingContext* context, bool IsInCB);
|
||||
|
||||
int IsAdhocctlInCallback();
|
||||
int SetAdhocctlInCallback(bool IsInCB);
|
||||
|
||||
/**
|
||||
* Local MAC Check
|
||||
* @param saddr To-be-checked MAC Address
|
||||
* @return 1 if valid or... 0
|
||||
*/
|
||||
int isLocalMAC(const SceNetEtherAddr * addr);
|
||||
bool isLocalMAC(const SceNetEtherAddr * addr);
|
||||
|
||||
/**
|
||||
* PDP Port Check
|
||||
* @param port To-be-checked Port
|
||||
* @return 1 if in use or... 0
|
||||
*/
|
||||
int isPDPPortInUse(uint16_t port);
|
||||
bool isPDPPortInUse(uint16_t port);
|
||||
|
||||
/**
|
||||
* Check whether PTP Port is in use or not
|
||||
* @param port To-be-checked Port Number
|
||||
* @return 1 if in use or... 0
|
||||
*/
|
||||
int isPTPPortInUse(uint16_t port);
|
||||
bool isPTPPortInUse(uint16_t port);
|
||||
|
||||
char* mac2str(SceNetEtherAddr* mac);
|
||||
char* mac2str(SceNetEtherAddr* mac, char* str, size_t size = 18);
|
||||
|
||||
/*
|
||||
* Matching Members
|
||||
|
@ -890,12 +938,12 @@ void freeGroupsRecursive(SceNetAdhocctlScanInfo * node);
|
|||
/**
|
||||
* Closes & Deletes all PDP Sockets
|
||||
*/
|
||||
void deleteAllPDP(void);
|
||||
void deleteAllPDP();
|
||||
|
||||
/**
|
||||
* Closes & Deletes all PTP sockets
|
||||
*/
|
||||
void deleteAllPTP(void);
|
||||
void deleteAllPTP();
|
||||
|
||||
/**
|
||||
* Delete Friend from Local List
|
||||
|
@ -907,7 +955,9 @@ void deleteFriendByIP(uint32_t ip);
|
|||
* Recursive Memory Freeing-Helper for Friend-Structures
|
||||
* @param node Current Node in List
|
||||
*/
|
||||
void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node);
|
||||
void freeFriendsRecursive(SceNetAdhocctlPeerInfo * node, int32_t* count);
|
||||
|
||||
void timeoutFriendsRecursive(SceNetAdhocctlPeerInfo* node, int32_t* count);
|
||||
|
||||
/**
|
||||
* Friend Finder Thread (Receives Peer Information)
|
||||
|
@ -921,7 +971,7 @@ int friendFinder();
|
|||
* Find Free Matching ID
|
||||
* @return First unoccupied Matching ID
|
||||
*/
|
||||
int findFreeMatchingID(void);
|
||||
int findFreeMatchingID();
|
||||
|
||||
/**
|
||||
* Find Internal Matching Context for Matching ID
|
||||
|
@ -933,7 +983,7 @@ SceNetAdhocMatchingContext * findMatchingContext(int id);
|
|||
/*
|
||||
* Notify Matching Event Handler
|
||||
*/
|
||||
void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * msg, void * opt, u32 &bufAddr, u32 &bufLen, u32_le * args);
|
||||
void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * msg, void * opt, u32_le &bufAddr, u32_le &bufLen, u32_le * args);
|
||||
// Notifiy Adhocctl Handlers
|
||||
void notifyAdhocctlHandlers(u32 flag, u32 error);
|
||||
|
||||
|
@ -1030,7 +1080,7 @@ void sendDeathMessage(SceNetAdhocMatchingContext * context, SceNetAdhocMatchingM
|
|||
* @param context Matching Context Pointer
|
||||
* @return Number of Children
|
||||
*/
|
||||
s32_le countChildren(SceNetAdhocMatchingContext * context);
|
||||
s32_le countChildren(SceNetAdhocMatchingContext * context, const bool excludeTimedout = false);
|
||||
|
||||
/**
|
||||
* Delete Peer from List
|
||||
|
@ -1059,14 +1109,14 @@ SceNetAdhocMatchingMemberInternal * findParent(SceNetAdhocMatchingContext * cont
|
|||
* @param context Matching Context Pointer
|
||||
* @return Internal Peer Reference or... NULL
|
||||
*/
|
||||
SceNetAdhocMatchingMemberInternal * findP2P(SceNetAdhocMatchingContext * context);
|
||||
SceNetAdhocMatchingMemberInternal * findP2P(SceNetAdhocMatchingContext * context, const bool excludeTimedout = false);
|
||||
|
||||
/**
|
||||
* Return Number of Connected Peers
|
||||
* @param context Matching Context Pointer
|
||||
* @return Number of Connected Peers
|
||||
*/
|
||||
uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context);
|
||||
uint32_t countConnectedPeers(SceNetAdhocMatchingContext * context, const bool excludeTimedout = false);
|
||||
|
||||
/**
|
||||
* Spawn Local Event for Event Thread
|
||||
|
@ -1093,7 +1143,7 @@ void spawnLocalEvent(SceNetAdhocMatchingContext * context, int event, SceNetEthe
|
|||
* Return Number of active Peers in the same Network as the Local Player
|
||||
* @return Number of active Peers
|
||||
*/
|
||||
int getActivePeerCount(void);
|
||||
int getActivePeerCount(const bool excludeTimedout = true);
|
||||
|
||||
/**
|
||||
* Returns the locall Ip of this machine, TODO: Implement the linux version
|
||||
|
@ -1152,13 +1202,13 @@ uint16_t getLocalPort(int sock);
|
|||
* PDP Socket Counter
|
||||
* @return Number of internal PDP Sockets
|
||||
*/
|
||||
int getPDPSocketCount(void);
|
||||
int getPDPSocketCount();
|
||||
|
||||
/**
|
||||
* PTP Socket Counter
|
||||
* @return Number of internal PTP Sockets
|
||||
*/
|
||||
int getPTPSocketCount(void);
|
||||
int getPTPSocketCount();
|
||||
|
||||
/**
|
||||
* Initialize Networking Components for Adhocctl Emulator
|
||||
|
|
|
@ -42,9 +42,12 @@
|
|||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
//#include <sqlite3.h>
|
||||
#include "thread/threadutil.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/HLE/proAdhocServer.h"
|
||||
#include "i18n/i18n.h"
|
||||
|
||||
|
||||
// User Count
|
||||
|
@ -497,8 +500,7 @@ void login_user_stream(int fd, uint32_t ip)
|
|||
while(u != NULL && u->resolver.ip != ip) u = u->next;
|
||||
|
||||
if (u != NULL) { // IP Already existed
|
||||
uint8_t * ip4 = (uint8_t *)&u->resolver.ip;
|
||||
WARN_LOG(SCENET, "AdhocServer: Already Existing IP: %u.%u.%u.%u\n", ip4[0], ip4[1], ip4[2], ip4[3]);
|
||||
WARN_LOG(SCENET, "AdhocServer: Already Existing IP: %s\n", inet_ntoa(*(in_addr*)&u->resolver.ip));
|
||||
}
|
||||
|
||||
// Unique IP Address
|
||||
|
@ -528,8 +530,7 @@ void login_user_stream(int fd, uint32_t ip)
|
|||
user->last_recv = time(NULL);
|
||||
|
||||
// Notify User
|
||||
uint8_t * ipa = (uint8_t *)&user->resolver.ip;
|
||||
INFO_LOG(SCENET, "AdhocServer: New Connection from %u.%u.%u.%u", ipa[0], ipa[1], ipa[2], ipa[3]);
|
||||
INFO_LOG(SCENET, "AdhocServer: New Connection from %s", inet_ntoa(*(in_addr*)&user->resolver.ip));
|
||||
|
||||
// Fix User Counter
|
||||
_db_user_count++;
|
||||
|
@ -572,8 +573,7 @@ void login_user_data(SceNetAdhocctlUserNode * user, SceNetAdhocctlLoginPacketC2S
|
|||
while (u != NULL && !IsMatch(u->resolver.mac, data->mac)) u = u->next;
|
||||
|
||||
if (u != NULL) { // MAC Already existed
|
||||
uint8_t* ip4 = (uint8_t*)&u->resolver.ip;
|
||||
WARN_LOG(SCENET, "AdhocServer: Already Existing MAC: %02X:%02X:%02X:%02X:%02X:%02X [%u.%u.%u.%u]\n", data->mac.data[0], data->mac.data[1], data->mac.data[2], data->mac.data[3], data->mac.data[4], data->mac.data[5], ip4[0], ip4[1], ip4[2], ip4[3]);
|
||||
WARN_LOG(SCENET, "AdhocServer: Already Existing MAC: %02x:%02x:%02x:%02x:%02x:%02x [%s]\n", data->mac.data[0], data->mac.data[1], data->mac.data[2], data->mac.data[3], data->mac.data[4], data->mac.data[5], inet_ntoa(*(in_addr*)&u->resolver.ip));
|
||||
}
|
||||
|
||||
// Game Product Override
|
||||
|
@ -621,11 +621,10 @@ void login_user_data(SceNetAdhocctlUserNode * user, SceNetAdhocctlLoginPacketC2S
|
|||
user->game = game;
|
||||
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
char safegamestr[10];
|
||||
memset(safegamestr, 0, sizeof(safegamestr));
|
||||
strncpy(safegamestr, game->game.data, PRODUCT_CODE_LENGTH);
|
||||
INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) started playing %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr);
|
||||
INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) started playing %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr);
|
||||
|
||||
// Update Status Log
|
||||
update_status();
|
||||
|
@ -639,8 +638,7 @@ void login_user_data(SceNetAdhocctlUserNode * user, SceNetAdhocctlLoginPacketC2S
|
|||
else
|
||||
{
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
WARN_LOG(SCENET, "AdhocServer: Invalid Login Packet Contents from %u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
|
||||
WARN_LOG(SCENET, "AdhocServer: Invalid Login Packet Contents from %s", inet_ntoa(*(in_addr*)&user->resolver.ip));
|
||||
}
|
||||
|
||||
// Logout User - Out of Memory or Invalid Arguments
|
||||
|
@ -672,11 +670,10 @@ void logout_user(SceNetAdhocctlUserNode * user)
|
|||
if(user->game != NULL)
|
||||
{
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
char safegamestr[10];
|
||||
memset(safegamestr, 0, sizeof(safegamestr));
|
||||
strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH);
|
||||
INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) stopped playing %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr);
|
||||
INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) stopped playing %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr);
|
||||
|
||||
// Fix Game Player Count
|
||||
user->game->playercount--;
|
||||
|
@ -702,8 +699,7 @@ void logout_user(SceNetAdhocctlUserNode * user)
|
|||
else
|
||||
{
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
WARN_LOG(SCENET, "AdhocServer: Dropped Connection to %u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
|
||||
WARN_LOG(SCENET, "AdhocServer: Dropped Connection to %s", inet_ntoa(*(in_addr*)&user->resolver.ip));
|
||||
}
|
||||
|
||||
// Free Memory
|
||||
|
@ -719,7 +715,7 @@ void logout_user(SceNetAdhocctlUserNode * user)
|
|||
/**
|
||||
* Free Database Memory
|
||||
*/
|
||||
void free_database(void)
|
||||
void free_database()
|
||||
{
|
||||
// There are users playing
|
||||
if(_db_user_count > 0)
|
||||
|
@ -885,14 +881,13 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group
|
|||
if (iResult < 0) ERROR_LOG(SCENET, "AdhocServer: connect_user[send user bssid] (Socket error %d)", errno);
|
||||
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
char safegamestr[10];
|
||||
memset(safegamestr, 0, sizeof(safegamestr));
|
||||
strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH);
|
||||
char safegroupstr[9];
|
||||
memset(safegroupstr, 0, sizeof(safegroupstr));
|
||||
strncpy(safegroupstr, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN);
|
||||
INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) joined %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr);
|
||||
INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) joined %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr, safegroupstr);
|
||||
|
||||
// Update Status Log
|
||||
update_status();
|
||||
|
@ -906,7 +901,6 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group
|
|||
else
|
||||
{
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
char safegamestr[10];
|
||||
memset(safegamestr, 0, sizeof(safegamestr));
|
||||
strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH);
|
||||
|
@ -916,7 +910,7 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group
|
|||
char safegroupstr2[9];
|
||||
memset(safegroupstr2, 0, sizeof(safegroupstr2));
|
||||
strncpy(safegroupstr2, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN);
|
||||
WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to join %s group %s without disconnecting from %s first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr, safegroupstr2);
|
||||
WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) attempted to join %s group %s without disconnecting from %s first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr, safegroupstr, safegroupstr2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -924,14 +918,13 @@ void connect_user(SceNetAdhocctlUserNode * user, SceNetAdhocctlGroupName * group
|
|||
else
|
||||
{
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
char safegamestr[10];
|
||||
memset(safegamestr, 0, sizeof(safegamestr));
|
||||
strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH);
|
||||
char safegroupstr[9];
|
||||
memset(safegroupstr, 0, sizeof(safegroupstr));
|
||||
strncpy(safegroupstr, (char *)group->data, ADHOCCTL_GROUPNAME_LEN);
|
||||
WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to join invalid %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr);
|
||||
WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) attempted to join invalid %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr, safegroupstr);
|
||||
}
|
||||
|
||||
// Invalid State, Out of Memory or Invalid Group Name
|
||||
|
@ -984,14 +977,13 @@ void disconnect_user(SceNetAdhocctlUserNode * user)
|
|||
}
|
||||
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
char safegamestr[10];
|
||||
memset(safegamestr, 0, sizeof(safegamestr));
|
||||
strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH);
|
||||
char safegroupstr[9];
|
||||
memset(safegroupstr, 0, sizeof(safegroupstr));
|
||||
strncpy(safegroupstr, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN);
|
||||
INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) left %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr);
|
||||
INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) left %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr, safegroupstr);
|
||||
|
||||
// Empty Group
|
||||
if(user->group->playercount == 0)
|
||||
|
@ -1028,11 +1020,10 @@ void disconnect_user(SceNetAdhocctlUserNode * user)
|
|||
else
|
||||
{
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
char safegamestr[10];
|
||||
memset(safegamestr, 0, sizeof(safegamestr));
|
||||
strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH);
|
||||
WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to leave %s group without joining one first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr);
|
||||
WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) attempted to leave %s group without joining one first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr);
|
||||
}
|
||||
|
||||
// Delete User
|
||||
|
@ -1087,11 +1078,10 @@ void send_scan_results(SceNetAdhocctlUserNode * user)
|
|||
if (iResult < 0) ERROR_LOG(SCENET, "AdhocServer: send_scan_result[send peer complete] (Socket error %d)", errno);
|
||||
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
char safegamestr[10];
|
||||
memset(safegamestr, 0, sizeof(safegamestr));
|
||||
strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH);
|
||||
INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) requested information on %d %s groups", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], user->game->groupcount, safegamestr);
|
||||
INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) requested information on %d %s groups", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), user->game->groupcount, safegamestr);
|
||||
|
||||
// Exit Function
|
||||
return;
|
||||
|
@ -1101,14 +1091,13 @@ void send_scan_results(SceNetAdhocctlUserNode * user)
|
|||
else
|
||||
{
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
char safegamestr[10];
|
||||
memset(safegamestr, 0, sizeof(safegamestr));
|
||||
strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH);
|
||||
char safegroupstr[9];
|
||||
memset(safegroupstr, 0, sizeof(safegroupstr));
|
||||
strncpy(safegroupstr, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN);
|
||||
WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to scan for %s groups without disconnecting from %s first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr, safegroupstr);
|
||||
WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) attempted to scan for %s groups without disconnecting from %s first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr, safegroupstr);
|
||||
}
|
||||
|
||||
// Delete User
|
||||
|
@ -1200,14 +1189,13 @@ void spread_message(SceNetAdhocctlUserNode *user, const char *message)
|
|||
if(counter > 0)
|
||||
{
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
char safegamestr[10];
|
||||
memset(safegamestr, 0, sizeof(safegamestr));
|
||||
strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH);
|
||||
char safegroupstr[9];
|
||||
memset(safegroupstr, 0, sizeof(safegroupstr));
|
||||
strncpy(safegroupstr, (char *)user->group->group.data, ADHOCCTL_GROUPNAME_LEN);
|
||||
INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) sent \"%s\" to %d players in %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], message, counter, safegamestr, safegroupstr);
|
||||
INFO_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) sent \"%s\" to %d players in %s group %s", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), message, counter, safegamestr, safegroupstr);
|
||||
}
|
||||
|
||||
// Exit Function
|
||||
|
@ -1218,11 +1206,10 @@ void spread_message(SceNetAdhocctlUserNode *user, const char *message)
|
|||
else
|
||||
{
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
char safegamestr[10];
|
||||
memset(safegamestr, 0, sizeof(safegamestr));
|
||||
strncpy(safegamestr, user->game->game.data, PRODUCT_CODE_LENGTH);
|
||||
WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u) attempted to send a text message without joining a %s group first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3], safegamestr);
|
||||
WARN_LOG(SCENET, "AdhocServer: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s) attempted to send a text message without joining a %s group first", (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip), safegamestr);
|
||||
}
|
||||
|
||||
// Delete User
|
||||
|
@ -1417,7 +1404,7 @@ void game_product_override(SceNetAdhocctlProductCode * product)
|
|||
/**
|
||||
* Update Status Logfile
|
||||
*/
|
||||
void update_status(void)
|
||||
void update_status()
|
||||
{
|
||||
// Open Logfile
|
||||
FILE * log = File::OpenCFile(SERVER_STATUS_XMLOUT, "w");
|
||||
|
@ -1672,6 +1659,7 @@ const char * strcpyxml(char * out, const char * in, uint32_t size)
|
|||
*/
|
||||
int proAdhocServerThread(int port) // (int argc, char * argv[])
|
||||
{
|
||||
setCurrentThreadName("AdhocServer");
|
||||
// Result
|
||||
int result = 0;
|
||||
|
||||
|
@ -1806,7 +1794,7 @@ int create_listen_socket(uint16_t port)
|
|||
int bindresult = bind(fd, (struct sockaddr *)&local, sizeof(local));
|
||||
|
||||
// Bound Local Address to Socket
|
||||
if(bindresult != -1)
|
||||
if(bindresult != SOCKET_ERROR)
|
||||
{
|
||||
// Switch Socket into Listening Mode
|
||||
listen(fd, SERVER_LISTEN_BACKLOG);
|
||||
|
@ -1816,7 +1804,11 @@ int create_listen_socket(uint16_t port)
|
|||
}
|
||||
|
||||
// Notify User
|
||||
else ERROR_LOG(SCENET, "AdhocServer: Bind returned %i (Socket error %d)", bindresult, errno);
|
||||
else {
|
||||
ERROR_LOG(SCENET, "AdhocServer: Bind returned %i (Socket error %d)", bindresult, errno);
|
||||
I18NCategory* n = GetI18NCategory("Networking");
|
||||
host->NotifyUserMessage(std::string(n->T("AdhocServer Failed to Bind Port")) + " " + std::to_string(port), 3.0, 0x0000ff);
|
||||
}
|
||||
|
||||
// Close Socket
|
||||
closesocket(fd);
|
||||
|
@ -1880,7 +1872,7 @@ int server_loop(int server)
|
|||
u8 *pip = (u8*)&sip;
|
||||
if (gethostbyname(str)->h_addrtype == AF_INET && gethostbyname(str)->h_addr_list[0] != NULL) pip = (u8*)gethostbyname(str)->h_addr_list[0];
|
||||
sip = *(u32_le*)pip;
|
||||
WARN_LOG(SCENET, "AdhocServer: Replacing IP %s with %u.%u.%u.%u", inet_ntoa(addr.sin_addr), pip[0], pip[1], pip[2], pip[3]);
|
||||
WARN_LOG(SCENET, "AdhocServer: Replacing IP %s with %s", inet_ntoa(addr.sin_addr), inet_ntoa(*(in_addr*)&pip));
|
||||
}
|
||||
*/
|
||||
login_user_stream(loginresult, sip);
|
||||
|
@ -1942,8 +1934,7 @@ int server_loop(int server)
|
|||
else
|
||||
{
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
WARN_LOG(SCENET, "AdhocServer: Invalid Opcode 0x%02X in Waiting State from %u.%u.%u.%u", user->rx[0], ip[0], ip[1], ip[2], ip[3]);
|
||||
WARN_LOG(SCENET, "AdhocServer: Invalid Opcode 0x%02X in Waiting State from %s", user->rx[0], inet_ntoa(*(in_addr*)&user->resolver.ip));
|
||||
|
||||
// Logout User
|
||||
logout_user(user);
|
||||
|
@ -2026,8 +2017,7 @@ int server_loop(int server)
|
|||
else
|
||||
{
|
||||
// Notify User
|
||||
uint8_t * ip = (uint8_t *)&user->resolver.ip;
|
||||
WARN_LOG(SCENET, "AdhocServer: Invalid Opcode 0x%02X in Logged-In State from %s (MAC: %02X:%02X:%02X:%02X:%02X:%02X - IP: %u.%u.%u.%u)", user->rx[0], (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], ip[0], ip[1], ip[2], ip[3]);
|
||||
WARN_LOG(SCENET, "AdhocServer: Invalid Opcode 0x%02X in Logged-In State from %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x - IP: %s)", user->rx[0], (char *)user->resolver.name.data, user->resolver.mac.data[0], user->resolver.mac.data[1], user->resolver.mac.data[2], user->resolver.mac.data[3], user->resolver.mac.data[4], user->resolver.mac.data[5], inet_ntoa(*(in_addr*)&user->resolver.ip));
|
||||
|
||||
// Logout User
|
||||
logout_user(user);
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#define SERVER_STATUS_XMLOUT "www/status.xml"
|
||||
|
||||
// Server Shutdown Message
|
||||
#define SERVER_SHUTDOWN_MESSAGE "PROMETHEUS HUB IS SHUTTING DOWN!"
|
||||
#define SERVER_SHUTDOWN_MESSAGE "ADHOC SERVER HUB IS SHUTTING DOWN!"
|
||||
|
||||
typedef struct db_crosslink{
|
||||
char id_from[PRODUCT_CODE_LENGTH + 1]; //SceNetAdhocctlProductCode id_from;
|
||||
|
@ -298,7 +298,7 @@ void logout_user(SceNetAdhocctlUserNode * user);
|
|||
/**
|
||||
* Free Database Memory
|
||||
*/
|
||||
void free_database(void);
|
||||
void free_database();
|
||||
|
||||
/**
|
||||
* Connect User to Game Group
|
||||
|
@ -358,7 +358,7 @@ void game_product_override(SceNetAdhocctlProductCode * product);
|
|||
/**
|
||||
* Update Status Logfile
|
||||
*/
|
||||
void update_status(void);
|
||||
void update_status();
|
||||
|
||||
/**
|
||||
* Server Entry Point
|
||||
|
|
|
@ -45,8 +45,8 @@
|
|||
#include "Core/Instance.h"
|
||||
|
||||
static bool netInited;
|
||||
static bool netInetInited;
|
||||
static bool netApctlInited;
|
||||
bool netInetInited;
|
||||
bool netApctlInited;
|
||||
u32 netDropRate = 0;
|
||||
u32 netDropDuration = 0;
|
||||
u32 netPoolAddr = 0;
|
||||
|
@ -118,12 +118,25 @@ void __NetInit() {
|
|||
|
||||
net::Init();
|
||||
InitLocalIP();
|
||||
INFO_LOG(SCENET, "LocalHost IP will be %s", inet_ntoa(((sockaddr_in*)&localIP)->sin_addr));
|
||||
|
||||
char tmpmac[18];
|
||||
SceNetEtherAddr mac;
|
||||
getLocalMac(&mac);
|
||||
INFO_LOG(SCENET, "LocalHost IP will be %s [MAC: %s]", inet_ntoa(((sockaddr_in*)&localIP)->sin_addr), mac2str(&mac, tmpmac));
|
||||
//net::Init();
|
||||
__ResetInitNetLib();
|
||||
}
|
||||
|
||||
void __NetShutdown() {
|
||||
// Checks to avoid confusing logspam
|
||||
if (netAdhocctlInited) sceNetAdhocctlTerm();
|
||||
if (netAdhocInited) sceNetAdhocTerm();
|
||||
|
||||
if (netApctlInited) sceNetApctlTerm();
|
||||
if (netInetInited) sceNetInetTerm();
|
||||
|
||||
if (netInited) sceNetTerm();
|
||||
|
||||
__ResetInitNetLib();
|
||||
|
||||
net::Shutdown();
|
||||
|
@ -149,6 +162,10 @@ void __NetDoState(PointerWrap &p) {
|
|||
if (!s)
|
||||
return;
|
||||
|
||||
auto cur_netInited = netInited;
|
||||
auto cur_netInetInited = netInetInited;
|
||||
auto cur_netApctlInited = netApctlInited;
|
||||
|
||||
p.Do(netInited);
|
||||
p.Do(netInetInited);
|
||||
p.Do(netApctlInited);
|
||||
|
@ -170,6 +187,12 @@ void __NetDoState(PointerWrap &p) {
|
|||
p.Do(netThread1Addr);
|
||||
p.Do(netThread2Addr);
|
||||
}
|
||||
// Let's not change "Inited" value when Loading SaveState in the middle of multiplayer to prevent memory & port leaks
|
||||
if (p.mode == p.MODE_READ) {
|
||||
netApctlInited = cur_netApctlInited;
|
||||
netInetInited = cur_netInetInited;
|
||||
netInited = cur_netInited;
|
||||
}
|
||||
}
|
||||
|
||||
static inline u32 AllocUser(u32 size, bool fromTop, const char *name) {
|
||||
|
@ -186,10 +209,32 @@ static inline void FreeUser(u32 &addr) {
|
|||
}
|
||||
|
||||
static u32 sceNetTerm() {
|
||||
//May also need to Terminate netAdhocctl and netAdhoc since the game (ie. GTA:VCS, Wipeout Pulse, etc) might not called them before calling sceNetTerm and causing them to behave strangely on the next sceNetInit+sceNetAdhocInit
|
||||
// May also need to Terminate netAdhocctl and netAdhoc to free some resources & threads, since the game (ie. GTA:VCS, Wipeout Pulse, etc) might not called them before calling sceNetTerm and causing them to behave strangely on the next sceNetInit & sceNetAdhocInit
|
||||
if (netAdhocctlInited) sceNetAdhocctlTerm();
|
||||
if (netAdhocInited) sceNetAdhocTerm();
|
||||
|
||||
if (netApctlInited) sceNetApctlTerm();
|
||||
if (netInetInited) sceNetInetTerm();
|
||||
|
||||
// Library is initialized
|
||||
if (netInited) {
|
||||
// Delete PDP Sockets
|
||||
deleteAllPDP();
|
||||
|
||||
// Delete PTP Sockets
|
||||
deleteAllPTP();
|
||||
|
||||
// Delete GameMode Buffer
|
||||
//deleteAllGMB();
|
||||
|
||||
// Terminate Internet Library
|
||||
//sceNetInetTerm();
|
||||
|
||||
// Unload Internet Modules (Just keep it in memory... unloading crashes?!)
|
||||
// if (_manage_modules != 0) sceUtilityUnloadModule(PSP_MODULE_NET_INET);
|
||||
// Library shutdown
|
||||
}
|
||||
|
||||
WARN_LOG(SCENET, "sceNetTerm()");
|
||||
netInited = false;
|
||||
FreeUser(netPoolAddr);
|
||||
|
@ -199,12 +244,20 @@ static u32 sceNetTerm() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// TODO: should that struct actually be initialized here?
|
||||
static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netinitPri, u32 netinitStack) {
|
||||
/*
|
||||
Parameters:
|
||||
poolsize - Memory pool size (appears to be for the whole of the networking library).
|
||||
calloutprio - Priority of the SceNetCallout thread.
|
||||
calloutstack - Stack size of the SceNetCallout thread (defaults to 4096 on non 1.5 firmware regardless of what value is passed).
|
||||
netintrprio - Priority of the SceNetNetintr thread.
|
||||
netintrstack - Stack size of the SceNetNetintr thread (defaults to 4096 on non 1.5 firmware regardless of what value is passed).
|
||||
*/
|
||||
static u32 sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netinitPri, u32 netinitStack) {
|
||||
// TODO: Create Network Threads using given priority & stack
|
||||
// TODO: The correct behavior is actually to allocate more and leak the other threads/pool.
|
||||
// But we reset here for historic reasons (GTA:VCS potentially triggers this.)
|
||||
if (netInited)
|
||||
sceNetTerm();
|
||||
sceNetTerm(); // This cleanup attempt might not worked when SaveState were loaded in the middle of multiplayer game and re-entering multiplayer, thus causing memory leaks & wasting binded ports. May be we shouldn't save/load "Inited" vars on SaveState?
|
||||
|
||||
if (poolSize == 0) {
|
||||
return hleLogError(SCENET, SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE, "invalid pool size");
|
||||
|
@ -236,13 +289,32 @@ static int sceNetInit(u32 poolSize, u32 calloutPri, u32 calloutStack, u32 netini
|
|||
|
||||
WARN_LOG(SCENET, "sceNetInit(poolsize=%d, calloutpri=%i, calloutstack=%d, netintrpri=%i, netintrstack=%d) at %08x", poolSize, calloutPri, calloutStack, netinitPri, netinitStack, currentMIPS->pc);
|
||||
netInited = true;
|
||||
netMallocStat.maximum = poolSize;
|
||||
netMallocStat.free = poolSize;
|
||||
netMallocStat.pool = 0;
|
||||
netMallocStat.pool = poolSize; // This should be the poolSize isn't?
|
||||
netMallocStat.maximum = poolSize/2; // According to JPCSP's sceNetGetMallocStat this is Currently Used size = (poolSize - free), faked to half the pool
|
||||
netMallocStat.free = poolSize - netMallocStat.maximum;
|
||||
|
||||
// Clear Socket Translator Memory
|
||||
memset(&pdp, 0, sizeof(pdp));
|
||||
memset(&ptp, 0, sizeof(ptp));
|
||||
|
||||
return hleLogSuccessI(SCENET, 0);
|
||||
}
|
||||
|
||||
// Free(delete) thread info / data.
|
||||
// Normal usage: sceKernelDeleteThread followed by sceNetFreeThreadInfo with the same threadID as argument
|
||||
static int sceNetFreeThreadinfo(SceUID thid) {
|
||||
ERROR_LOG(SCENET, "UNIMPL sceNetFreeThreadinfo(%i)", thid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Abort a thread.
|
||||
static int sceNetThreadAbort(SceUID thid) {
|
||||
ERROR_LOG(SCENET, "UNIMPL sceNetThreadAbort(%i)", thid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 sceWlanGetEtherAddr(u32 addrAddr) {
|
||||
if (!Memory::IsValidRange(addrAddr, 6)) {
|
||||
// More correctly, it should crash.
|
||||
|
@ -364,7 +436,7 @@ static int sceNetInetInit() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int sceNetInetTerm() {
|
||||
int sceNetInetTerm() {
|
||||
ERROR_LOG(SCENET, "UNIMPL sceNetInetTerm()");
|
||||
netInetInited = false;
|
||||
|
||||
|
@ -380,7 +452,7 @@ static int sceNetApctlInit() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int sceNetApctlTerm() {
|
||||
int sceNetApctlTerm() {
|
||||
ERROR_LOG(SCENET, "UNIMPL sceNeApctlTerm()");
|
||||
netApctlInited = false;
|
||||
|
||||
|
@ -602,9 +674,9 @@ const HLEFunction sceNet[] = {
|
|||
{0X89360950, &WrapI_UU<sceNetEtherNtostr>, "sceNetEtherNtostr", 'i', "xx" },
|
||||
{0XD27961C9, &WrapI_UU<sceNetEtherStrton>, "sceNetEtherStrton", 'i', "xx" },
|
||||
{0X0BF0A3AE, &WrapU_U<sceNetGetLocalEtherAddr>, "sceNetGetLocalEtherAddr", 'x', "x" },
|
||||
{0X50647530, nullptr, "sceNetFreeThreadinfo", '?', "" },
|
||||
{0X50647530, &WrapI_I<sceNetFreeThreadinfo>, "sceNetFreeThreadinfo", 'i', "i" },
|
||||
{0XCC393E48, &WrapI_U<sceNetGetMallocStat>, "sceNetGetMallocStat", 'i', "x" },
|
||||
{0XAD6844C6, nullptr, "sceNetThreadAbort", '?', "" },
|
||||
{0XAD6844C6, &WrapI_I<sceNetThreadAbort>, "sceNetThreadAbort", 'i', "i" },
|
||||
};
|
||||
|
||||
const HLEFunction sceNetResolver[] = {
|
||||
|
|
|
@ -60,7 +60,7 @@ typedef struct SceNetInetSockaddr {
|
|||
uint8_t sa_len;
|
||||
uint8_t sa_family;
|
||||
uint8_t sa_data[14];
|
||||
} SceNetInetSockaddr;
|
||||
} PACK SceNetInetSockaddr;
|
||||
|
||||
// Sockaddr_in
|
||||
typedef struct SceNetInetSockaddrIn {
|
||||
|
@ -69,19 +69,19 @@ typedef struct SceNetInetSockaddrIn {
|
|||
u16_le sin_port; //uint16_t
|
||||
u32_le sin_addr; //uint32_t
|
||||
uint8_t sin_zero[8];
|
||||
} SceNetInetSockaddrIn;
|
||||
} PACK SceNetInetSockaddrIn;
|
||||
|
||||
// Polling Event Field
|
||||
typedef struct SceNetInetPollfd { //similar format to pollfd in 32bit (pollfd in 64bit have different size)
|
||||
s32_le fd;
|
||||
s16_le events;
|
||||
s16_le revents;
|
||||
} SceNetInetPollfd;
|
||||
} PACK SceNetInetPollfd;
|
||||
|
||||
struct ProductStruct {
|
||||
typedef struct ProductStruct { // Similar to SceNetAdhocctlAdhocId ?
|
||||
s32_le unknown; // Unknown, set to 0 // Product Type ?
|
||||
char product[PRODUCT_CODE_LENGTH]; // Game ID (Example: ULUS10000)
|
||||
};
|
||||
} PACK ProductStruct;
|
||||
|
||||
struct ApctlHandler {
|
||||
u32 entryPoint;
|
||||
|
@ -90,6 +90,9 @@ struct ApctlHandler {
|
|||
|
||||
class PointerWrap;
|
||||
|
||||
extern bool netInetInited;
|
||||
extern bool netApctlInited;
|
||||
|
||||
void Register_sceNet();
|
||||
void Register_sceWlanDrv();
|
||||
void Register_sceNetUpnp();
|
||||
|
@ -100,4 +103,7 @@ void __NetInit();
|
|||
void __NetShutdown();
|
||||
void __NetDoState(PointerWrap &p);
|
||||
|
||||
int sceNetInetPoll(void *fds, u32 nfds, int timeout);
|
||||
int sceNetInetPoll(void *fds, u32 nfds, int timeout);
|
||||
int sceNetInetTerm();
|
||||
int sceNetApctlTerm();
|
||||
static u32 sceNetTerm();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,6 +17,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Core/HLE/proAdhoc.h"
|
||||
|
||||
typedef struct MatchingArgs {
|
||||
u32_le data[6]; //ContextID, Opcode, bufAddr[ to MAC], OptLen, OptAddr[, EntryPoint]
|
||||
} PACK;
|
||||
|
@ -25,6 +27,7 @@ class PointerWrap;
|
|||
|
||||
void Register_sceNetAdhoc();
|
||||
|
||||
u32_le __CreateHLELoop(u32_le* loopAddr, const char* sceFuncName, const char* hleFuncName, const char* tagName = NULL);
|
||||
void __NetAdhocInit();
|
||||
void __NetAdhocShutdown();
|
||||
void __NetAdhocDoState(PointerWrap &p);
|
||||
|
@ -37,5 +40,12 @@ int sceNetAdhocctlCreate(const char * groupName);
|
|||
// May need to use these from sceNet.cpp
|
||||
extern bool netAdhocInited;
|
||||
extern bool netAdhocctlInited;
|
||||
extern int adhocDefaultTimeout;
|
||||
extern int adhocEventPollDelayMS;
|
||||
extern int adhocMatchingEventDelayMS;
|
||||
extern int adhocEventDelayMS;
|
||||
extern std::recursive_mutex adhocEvtMtx;
|
||||
extern int IsAdhocctlInCB;
|
||||
|
||||
int sceNetAdhocctlTerm();
|
||||
int sceNetAdhocTerm();
|
||||
|
|
Loading…
Add table
Reference in a new issue