mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #13579 from ANR2ME/adhoc_fix
Adhoc fix - Updating Adhocctl behavior after doing some small test
This commit is contained in:
commit
a4a0b4ba00
5 changed files with 612 additions and 325 deletions
|
@ -21,6 +21,10 @@
|
|||
// This is a direct port of Coldbird's code from http://code.google.com/p/aemu/
|
||||
// All credit goes to him!
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include "Common/CommonWindows.h"
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
@ -62,6 +66,7 @@ SceNetAdhocctlPeerInfo * friends = NULL;
|
|||
SceNetAdhocctlScanInfo * networks = NULL;
|
||||
SceNetAdhocctlScanInfo * newnetworks = NULL;
|
||||
u64 adhocctlStartTime = 0;
|
||||
bool isAdhocctlBusy = false;
|
||||
int adhocctlState = ADHOCCTL_STATE_DISCONNECTED;
|
||||
int adhocctlCurrentMode = ADHOCCTL_MODE_NONE;
|
||||
int adhocConnectionType = ADHOC_CONNECT;
|
||||
|
@ -315,7 +320,7 @@ void changeBlockingMode(int fd, int nonblocking) {
|
|||
#endif
|
||||
}
|
||||
|
||||
int countAvailableNetworks() {
|
||||
int countAvailableNetworks(const bool excludeSelf) {
|
||||
// Network Count
|
||||
int count = 0;
|
||||
|
||||
|
@ -323,7 +328,7 @@ int countAvailableNetworks() {
|
|||
SceNetAdhocctlScanInfo * group = networks;
|
||||
|
||||
// Count Groups
|
||||
for (; group != NULL; group = group->next) count++;
|
||||
for (; group != NULL && (!excludeSelf || !isLocalMAC(&group->bssid.mac_addr)); group = group->next) count++;
|
||||
|
||||
// Return Network Count
|
||||
return count;
|
||||
|
@ -1165,6 +1170,7 @@ 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);
|
||||
isAdhocctlBusy = false;
|
||||
DEBUG_LOG(SCENET, "AfterAdhocMipsCall::run [ID=%i][Event=%d] [cbId: %u][retV0: %08x]", HandlerID, EventID, call.cbId, v0);
|
||||
//call.setReturnValue(v0);
|
||||
}
|
||||
|
@ -1334,6 +1340,10 @@ int friendFinder(){
|
|||
if (initNetwork(&product_code) == 0) {
|
||||
networkInited = true;
|
||||
INFO_LOG(SCENET, "FriendFinder: Network [RE]Initialized");
|
||||
// At this point we are most-likely not in a Group within the Adhoc Server, so we should probably reset AdhocctlState
|
||||
adhocctlState = ADHOCCTL_STATE_DISCONNECTED;
|
||||
netAdhocGameModeEntered = false;
|
||||
isAdhocctlBusy = false;
|
||||
}
|
||||
else {
|
||||
networkInited = false;
|
||||
|
@ -1395,6 +1405,12 @@ int friendFinder(){
|
|||
}
|
||||
}
|
||||
|
||||
// Calculate EnterGameMode Timeout to prevent waiting forever for disconnected players
|
||||
if (isAdhocctlBusy && adhocctlState == ADHOCCTL_STATE_DISCONNECTED && adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE && netAdhocGameModeEntered && static_cast<s64>(now - adhocctlStartTime) > netAdhocEnterGameModeTimeout) {
|
||||
netAdhocGameModeEntered = false;
|
||||
notifyAdhocctlHandlers(ADHOCCTL_EVENT_ERROR, ERROR_NET_ADHOC_TIMEOUT);
|
||||
}
|
||||
|
||||
// Handle Packets
|
||||
if (rxpos > 0) {
|
||||
// BSSID Packet
|
||||
|
@ -1419,14 +1435,14 @@ int friendFinder(){
|
|||
}) == gameModeMacs.end()) {
|
||||
// Arrange the order to be consistent on all players (Host on top), Starting from our self the rest of new players will be added to the back
|
||||
gameModeMacs.push_back(localMac);
|
||||
|
||||
// FIXME: OPCODE_CONNECT_BSSID only triggered once, but the timing of ADHOCCTL_EVENT_GAME notification could be too soon, since there could be more players that need to join before the event should be notified
|
||||
if (netAdhocGameModeEntered && gameModeMacs.size() >= requiredGameModeMacs.size()) {
|
||||
notifyAdhocctlHandlers(ADHOCCTL_EVENT_GAME, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
WARN_LOG(SCENET, "GameMode SelfMember [%s] Already Existed!", mac2str(&localMac).c_str());
|
||||
|
||||
if (gameModeMacs.size() >= requiredGameModeMacs.size()) {
|
||||
//adhocctlState = ADHOCCTL_STATE_GAMEMODE;
|
||||
notifyAdhocctlHandlers(ADHOCCTL_EVENT_GAME, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//adhocctlState = ADHOCCTL_STATE_CONNECTED;
|
||||
|
@ -1521,17 +1537,16 @@ int friendFinder(){
|
|||
it = gameModeMacs.begin() + 1;
|
||||
gameModeMacs.insert(it, packet->mac);
|
||||
}
|
||||
|
||||
// From JPCSP: Join complete when all the required MACs have joined
|
||||
if (netAdhocGameModeEntered && requiredGameModeMacs.size() > 0 && gameModeMacs.size() == requiredGameModeMacs.size()) {
|
||||
// TODO: Should we replace gameModeMacs contents with requiredGameModeMacs contents to make sure they are in the same order with macs from sceNetAdhocctlCreateEnterGameMode? But may not be consistent with the list on client side!
|
||||
//gameModeMacs = requiredGameModeMacs;
|
||||
notifyAdhocctlHandlers(ADHOCCTL_EVENT_GAME, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
WARN_LOG(SCENET, "GameMode Member [%s] Already Existed!", mac2str(&packet->mac).c_str());
|
||||
|
||||
// From JPCSP: Join complete when all the required MACs have joined
|
||||
if (requiredGameModeMacs.size() > 0 && gameModeMacs.size() >= requiredGameModeMacs.size()) {
|
||||
// TODO: Should we replace gameModeMacs contents with requiredGameModeMacs contents to make sure they are in the same order with macs from sceNetAdhocctlCreateEnterGameMode? But may not be consistent with the list on client side!
|
||||
//gameModeMacs = requiredGameModeMacs;
|
||||
//adhocctlState = ADHOCCTL_STATE_GAMEMODE;
|
||||
notifyAdhocctlHandlers(ADHOCCTL_EVENT_GAME, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Update HUD User Count
|
||||
|
@ -1572,13 +1587,14 @@ int friendFinder(){
|
|||
// Log Incoming Peer Delete Request
|
||||
INFO_LOG(SCENET, "FriendFinder: Incoming Peer Data Delete Request...");
|
||||
|
||||
/*if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) {
|
||||
if (adhocctlCurrentMode == ADHOCCTL_MODE_GAMEMODE) {
|
||||
auto peer = findFriendByIP(packet->ip);
|
||||
gameModeMacs.erase(std::remove_if(gameModeMacs.begin(), gameModeMacs.end(),
|
||||
[peer](SceNetEtherAddr const& e) {
|
||||
return isMacMatch(&e, &peer->mac_addr);
|
||||
}), gameModeMacs.end());
|
||||
}*/
|
||||
for (auto& gma : replicaGameModeAreas)
|
||||
if (isMacMatch(&gma.mac, &peer->mac_addr)) {
|
||||
gma.updateTimestamp = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Delete User by IP, should delete by MAC since IP can be shared (behind NAT) isn't?
|
||||
deleteFriendByIP(packet->ip);
|
||||
|
@ -1633,7 +1649,8 @@ int friendFinder(){
|
|||
// Set group parameters
|
||||
// Since 0 is not a valid active channel we fake the channel for Automatic Channel (JPCSP use 11 as default). Ridge Racer 2 will ignore any groups with channel 0 or that doesn't matched with channel value returned from sceUtilityGetSystemParamInt (which mean sceUtilityGetSystemParamInt must not return channel 0 when connected to a network?)
|
||||
group->channel = parameter.channel; //(parameter.channel == PSP_SYSTEMPARAM_ADHOC_CHANNEL_AUTOMATIC) ? defaultWlanChannel : parameter.channel;
|
||||
group->mode = adhocctlCurrentMode;
|
||||
// This Mode should be a valid mode (>=0), probably should be sent by AdhocServer since there are 2 possibilities (Normal and GameMode). Air Conflicts - Aces Of World War 2 (which use GameMode) seems to relies on this Mode value.
|
||||
group->mode = std::max(ADHOCCTL_MODE_NORMAL, adhocctlCurrentMode); // default to ADHOCCTL_MODE_NORMAL
|
||||
|
||||
// Link into Group List
|
||||
newnetworks = group;
|
||||
|
|
|
@ -114,9 +114,15 @@ inline bool isDisconnected(int errcode) { return (errcode == EPIPE || errcode ==
|
|||
#define ADHOC_GAMEMODE_PORT 31000
|
||||
#define GAMEMODE_UPDATE_INTERVAL 500 // 12000 usec on JPCSP, but lower value works better on BattleZone (in order to get full speed 60 FPS)
|
||||
#define GAMEMODE_INIT_DELAY 10000
|
||||
#define GAMEMODE_SYNC_TIMEOUT 250000
|
||||
|
||||
// GameMode Type
|
||||
#define ADHOCCTL_GAMETYPE_1A 1
|
||||
#define ADHOCCTL_GAMETYPE_1B 2
|
||||
#define ADHOCCTL_GAMETYPE_2A 3
|
||||
|
||||
// psp strutcs and definitions
|
||||
#define ADHOCCTL_MODE_NONE -1
|
||||
#define ADHOCCTL_MODE_NONE -1 // We only use this internally as initial value before attempting to create/connect/join/scan any group
|
||||
#define ADHOCCTL_MODE_NORMAL 0 // ADHOCCTL_MODE_ADHOC
|
||||
#define ADHOCCTL_MODE_GAMEMODE 1
|
||||
|
||||
|
@ -141,7 +147,7 @@ inline bool isDisconnected(int errcode) { return (errcode == EPIPE || errcode ==
|
|||
// 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
|
||||
#define PSP_ADHOCCTL_TYPE_SYSTEM 2 // Used for GameSharing?
|
||||
|
||||
// Kernel Utility Netconf Adhoc Types
|
||||
#define UTILITY_NETCONF_TYPE_CONNECT_ADHOC 2
|
||||
|
@ -321,6 +327,7 @@ typedef struct GameModeArea {
|
|||
//int socket; // PDP socket?
|
||||
u64 updateTimestamp;
|
||||
int dataUpdated;
|
||||
int dataSent;
|
||||
SceNetEtherAddr mac;
|
||||
u8* data; // upto "size" bytes started from "addr" ?
|
||||
} PACK GameModeArea;
|
||||
|
@ -393,8 +400,8 @@ typedef struct SceNetAdhocGameModeBufferStat {
|
|||
// Adhoc ID (Game Product Key)
|
||||
#define ADHOCCTL_ADHOCID_LEN 9
|
||||
typedef struct SceNetAdhocctlAdhocId {
|
||||
s32_le type;
|
||||
uint8_t data[ADHOCCTL_ADHOCID_LEN];
|
||||
s32_le type; // Air Conflicts - Aces Of World War 2 is using 2 for GameSharing?
|
||||
uint8_t data[ADHOCCTL_ADHOCID_LEN]; // Air Conflicts - Aces Of World War 2 is using "000000001" for GameSharing?
|
||||
uint8_t padding[3];
|
||||
} PACK SceNetAdhocctlAdhocId; // should this be packed?
|
||||
#ifdef _MSC_VER
|
||||
|
@ -913,6 +920,7 @@ extern bool friendFinderRunning;
|
|||
extern SceNetAdhocctlPeerInfo * friends;
|
||||
extern SceNetAdhocctlScanInfo * networks;
|
||||
extern u64 adhocctlStartTime;
|
||||
extern bool isAdhocctlBusy;
|
||||
extern int adhocctlState;
|
||||
extern int adhocctlCurrentMode;
|
||||
extern int adhocConnectionType;
|
||||
|
@ -1025,7 +1033,7 @@ void changeBlockingMode(int fd, int nonblocking);
|
|||
* Count Virtual Networks by analyzing the Friend List
|
||||
* @return Number of Virtual Networks
|
||||
*/
|
||||
int countAvailableNetworks();
|
||||
int countAvailableNetworks(const bool excludeSelf = false);
|
||||
|
||||
/*
|
||||
* Find an existing group in networks
|
||||
|
|
|
@ -676,8 +676,6 @@ static u32 sceWlanGetEtherAddr(u32 addrAddr) {
|
|||
return hleLogError(SCENET, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "illegal address");
|
||||
}
|
||||
|
||||
// FIXME: Return 0x80410180 (pspnet[_core] error code?) when Adhocctl not connected to a group (ie. ADHOCCTL_STATE_DISCONNECTED)?
|
||||
|
||||
u8 *addr = Memory::GetPointer(addrAddr);
|
||||
if (PPSSPP_ID > 1) {
|
||||
Memory::Memset(addrAddr, PPSSPP_ID, 6);
|
||||
|
@ -697,6 +695,10 @@ static u32 sceWlanGetEtherAddr(u32 addrAddr) {
|
|||
}
|
||||
|
||||
static u32 sceNetGetLocalEtherAddr(u32 addrAddr) {
|
||||
// FIXME: Return 0x80410180 (pspnet[_core] error code?) before successful attempt to Create/Connect/Join a Group? (ie. adhocctlCurrentMode == ADHOCCTL_MODE_NONE)
|
||||
if (adhocctlCurrentMode == ADHOCCTL_MODE_NONE)
|
||||
return hleLogDebug(SCENET, 0x80410180, "address not available?");
|
||||
|
||||
return sceWlanGetEtherAddr(addrAddr);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -98,6 +98,8 @@ int NetAdhoc_Term();
|
|||
extern bool netAdhocInited;
|
||||
extern bool netAdhocctlInited;
|
||||
extern bool networkInited;
|
||||
extern bool netAdhocGameModeEntered;
|
||||
extern int netAdhocEnterGameModeTimeout;
|
||||
extern int adhocDefaultTimeout; //3000000 usec
|
||||
extern int adhocDefaultDelay; //10000
|
||||
extern int adhocExtraDelay; //20000
|
||||
|
|
Loading…
Add table
Reference in a new issue