Fix Multiplayer with more than 2 people
At least on Citra and quite hacky Join Menu still shows wrong player count, but this affects nothing
This commit is contained in:
parent
d2f7796b79
commit
6513c0d1fa
6 changed files with 79 additions and 20 deletions
BIN
Minicraft3DS.zip
BIN
Minicraft3DS.zip
Binary file not shown.
|
@ -101,6 +101,7 @@ void ingameMenuTick(PlayerData *pd, int menu) {
|
||||||
case MENU_LOSE:
|
case MENU_LOSE:
|
||||||
if (pd->inputs.k_accept.clicked){
|
if (pd->inputs.k_accept.clicked){
|
||||||
pd->ingameMenu = MENU_NONE;
|
pd->ingameMenu = MENU_NONE;
|
||||||
|
pd->entity.level = 1;
|
||||||
playerSpawn(pd);
|
playerSpawn(pd);
|
||||||
//TODO: This canceled to main menu, but what should I do in multiplayer?
|
//TODO: This canceled to main menu, but what should I do in multiplayer?
|
||||||
}
|
}
|
||||||
|
|
|
@ -587,6 +587,7 @@ void tickMenu(int menu){
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
networkScan();
|
||||||
currentMenu = MENU_MULTIPLAYER_JOIN;
|
currentMenu = MENU_MULTIPLAYER_JOIN;
|
||||||
currentSelection = 0;
|
currentSelection = 0;
|
||||||
menuScanTimer = 0;
|
menuScanTimer = 0;
|
||||||
|
|
|
@ -21,6 +21,8 @@ udsBindContext networkBindCtx;
|
||||||
|
|
||||||
udsConnectionStatus networkStatus;
|
udsConnectionStatus networkStatus;
|
||||||
|
|
||||||
|
u16 networkConnectedMask;
|
||||||
|
|
||||||
//new code
|
//new code
|
||||||
//structure in buffer is u16(seqID),u16(size),size(data), ...
|
//structure in buffer is u16(seqID),u16(size),size(data), ...
|
||||||
void *networkSendBuffer;
|
void *networkSendBuffer;
|
||||||
|
@ -57,7 +59,15 @@ void networkThreadMain(void *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void networkUpdateStatus() {
|
void networkUpdateStatus() {
|
||||||
udsGetConnectionStatus(&networkStatus);
|
/*for(int i=0; i<10; i++) {
|
||||||
|
Result ret = udsGetConnectionStatus(&networkStatus);
|
||||||
|
if(!R_FAILED(ret)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
if(udsWaitConnectionStatusEvent(false, false)) {
|
||||||
|
udsGetConnectionStatus(&networkStatus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void networkHandleRecieve() {
|
void networkHandleRecieve() {
|
||||||
|
@ -101,8 +111,12 @@ void networkHandleRecieve() {
|
||||||
networkSeqRecvLast[sourceNetworkNodeID] = seqID;
|
networkSeqRecvLast[sourceNetworkNodeID] = seqID;
|
||||||
ackToSend = seqID;
|
ackToSend = seqID;
|
||||||
|
|
||||||
//handle data
|
//handle data - TODO: WARNING: Do not send sizeof(u16) packets or else they will get confused with this one
|
||||||
processPacket(readPointer, size);
|
if(size==sizeof(u16)) {
|
||||||
|
networkConnectedMask = *((u16*) readPointer);
|
||||||
|
} else {
|
||||||
|
processPacket(readPointer, size);
|
||||||
|
}
|
||||||
} else if(seqID<=nextID-1) {
|
} else if(seqID<=nextID-1) {
|
||||||
ackToSend = nextID-1;
|
ackToSend = nextID-1;
|
||||||
}
|
}
|
||||||
|
@ -143,12 +157,27 @@ void networkHandleSend() {
|
||||||
|
|
||||||
//send frame
|
//send frame
|
||||||
if(currentSize>0) {
|
if(currentSize>0) {
|
||||||
//send frame
|
//TODO: Once we have our own custom mask, no longer broadcast, but send directly because bcast doesn't always reach everyone?
|
||||||
Result ret = udsSendTo(UDS_BROADCAST_NETWORKNODEID, NETWORK_CHANNEL, UDS_SENDFLAG_Default, networkSendBuffer+networkSendBufferStartPos, currentSize);
|
if(networkConnectedMask==0) {
|
||||||
if(UDS_CHECK_SENDTO_FATALERROR(ret)) {
|
//send frame
|
||||||
//TODO: what do?
|
Result ret = udsSendTo(UDS_BROADCAST_NETWORKNODEID, NETWORK_CHANNEL, UDS_SENDFLAG_Default, networkSendBuffer+networkSendBufferStartPos, currentSize);
|
||||||
} else if(R_FAILED(ret)) {
|
if(UDS_CHECK_SENDTO_FATALERROR(ret)) {
|
||||||
//TODO: what do?
|
//TODO: what do?
|
||||||
|
} else if(R_FAILED(ret)) {
|
||||||
|
//TODO: what do?
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(int i=1; i<=UDS_MAXNODES; i++) {
|
||||||
|
if(i!=networkGetLocalNodeID()/* && networkIsNodeConnected(i)*/ && networkConnectedMask & (1 << (i-1))) {
|
||||||
|
//send frame
|
||||||
|
Result ret = udsSendTo(i, NETWORK_CHANNEL, UDS_SENDFLAG_Default, networkSendBuffer+networkSendBufferStartPos, currentSize);
|
||||||
|
if(UDS_CHECK_SENDTO_FATALERROR(ret)) {
|
||||||
|
//TODO: what do?
|
||||||
|
} else if(R_FAILED(ret)) {
|
||||||
|
//TODO: what do?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +189,7 @@ void clearSendAckedBuffer() {
|
||||||
//find last ack recieved from all com partners
|
//find last ack recieved from all com partners
|
||||||
u16 ackID = 0;
|
u16 ackID = 0;
|
||||||
for(int i=1; i<=UDS_MAXNODES; i++) {
|
for(int i=1; i<=UDS_MAXNODES; i++) {
|
||||||
if(i!=networkGetLocalNodeID() && networkIsNodeConnected(i)) {
|
if(i!=networkGetLocalNodeID()/* && networkIsNodeConnected(i)*/ && networkConnectedMask & (1 << (i-1))) {
|
||||||
if(networkSeqSendConf[i]==0) {
|
if(networkSeqSendConf[i]==0) {
|
||||||
ackID = 0;
|
ackID = 0;
|
||||||
return;
|
return;
|
||||||
|
@ -235,6 +264,7 @@ void networkInit() {
|
||||||
scannedNetworks = NULL;
|
scannedNetworks = NULL;
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
isServer = false;
|
isServer = false;
|
||||||
|
networkConnectedMask = 0;
|
||||||
|
|
||||||
networkWriteBuffer = malloc(NETWORK_MAXDATASIZE);
|
networkWriteBuffer = malloc(NETWORK_MAXDATASIZE);
|
||||||
if(networkWriteBuffer==NULL) {
|
if(networkWriteBuffer==NULL) {
|
||||||
|
@ -331,9 +361,11 @@ bool networkHost() {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if(udsWaitConnectionStatusEvent(false, false)) {}
|
if(udsWaitConnectionStatusEvent(false, false)) {}
|
||||||
|
udsGetConnectionStatus(&networkStatus);
|
||||||
udsSetNewConnectionsBlocked(false, true, false);
|
udsSetNewConnectionsBlocked(false, true, false);
|
||||||
isConnected = true;
|
isConnected = true;
|
||||||
isServer = true;
|
isServer = true;
|
||||||
|
networkConnectedMask = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -392,8 +424,10 @@ bool networkConnect(int pos) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if(udsWaitConnectionStatusEvent(false, false)) {}
|
if(udsWaitConnectionStatusEvent(false, false)) {}
|
||||||
|
udsGetConnectionStatus(&networkStatus);
|
||||||
isConnected = true;
|
isConnected = true;
|
||||||
isServer = false;
|
isServer = false;
|
||||||
|
networkConnectedMask = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,18 +437,9 @@ bool networkConnect(int pos) {
|
||||||
void networkDisconnect() {
|
void networkDisconnect() {
|
||||||
//For clients this just means disconnect, for the server it means destroy the network
|
//For clients this just means disconnect, for the server it means destroy the network
|
||||||
if(udsRunning && isConnected) {
|
if(udsRunning && isConnected) {
|
||||||
//TODO
|
|
||||||
if(isServer) {
|
|
||||||
//TODO: Clients need to cleanup too, how can I tell they got disconnected
|
|
||||||
udsDestroyNetwork();
|
|
||||||
} else {
|
|
||||||
udsDisconnectNetwork();
|
|
||||||
}
|
|
||||||
udsUnbind(&networkBindCtx);
|
|
||||||
|
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
isServer = false;
|
|
||||||
|
|
||||||
|
LightLock_Lock(&sendBufferLock);
|
||||||
//reset send buffer
|
//reset send buffer
|
||||||
networkSendBufferStartPos = 0;
|
networkSendBufferStartPos = 0;
|
||||||
networkSendBufferEndPos = 0;
|
networkSendBufferEndPos = 0;
|
||||||
|
@ -426,10 +451,38 @@ void networkDisconnect() {
|
||||||
networkSeqSendConf[i] = 0;
|
networkSeqSendConf[i] = 0;
|
||||||
networkSeqRecvLast[i] = 0;
|
networkSeqRecvLast[i] = 0;
|
||||||
}
|
}
|
||||||
|
LightLock_Unlock(&sendBufferLock);
|
||||||
|
|
||||||
|
//With new changes citra now crashes HOST with "cannot be a router if we are not a host" when exiting game with more than 2 people
|
||||||
|
svcSleepThread(220000 * 1000); //HACK: prevent citra crash (>20*networkthreadsleep) (wait unti no more stuff gets send)
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
if(isServer) {
|
||||||
|
//TODO: Clients need to cleanup too, how can I tell they got disconnected
|
||||||
|
udsDestroyNetwork();
|
||||||
|
} else {
|
||||||
|
udsDisconnectNetwork();
|
||||||
|
}
|
||||||
|
udsUnbind(&networkBindCtx);
|
||||||
|
|
||||||
|
isServer = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void networkStart() {
|
||||||
|
//TODO: This sends the node_bitmask from server to everyone else, because it is uncorrect on some clients?
|
||||||
|
if(udsRunning && isConnected && isServer) {
|
||||||
|
void *buffer = networkWriteBuffer;
|
||||||
|
|
||||||
|
*((u16*) buffer) = networkStatus.node_bitmask;
|
||||||
|
networkConnectedMask = networkStatus.node_bitmask;
|
||||||
|
|
||||||
|
networkSend(networkWriteBuffer, sizeof(u16));
|
||||||
|
networkSendWaitFlush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool networkConnected() {
|
bool networkConnected() {
|
||||||
return isConnected;
|
return isConnected;
|
||||||
|
|
|
@ -30,6 +30,8 @@ bool networkGetScanName(char *name, int pos);
|
||||||
bool networkConnect(int pos);
|
bool networkConnect(int pos);
|
||||||
void networkDisconnect();
|
void networkDisconnect();
|
||||||
|
|
||||||
|
void networkStart();
|
||||||
|
|
||||||
void networkUpdateStatus();
|
void networkUpdateStatus();
|
||||||
bool networkConnected();
|
bool networkConnected();
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ void setupGameServer() {
|
||||||
|
|
||||||
networkHostStopConnections();
|
networkHostStopConnections();
|
||||||
|
|
||||||
|
networkStart();
|
||||||
|
|
||||||
//send start info (seed)
|
//send start info (seed)
|
||||||
size = writeStartPacket(networkWriteBuffer, rand());
|
size = writeStartPacket(networkWriteBuffer, rand());
|
||||||
networkSend(networkWriteBuffer, size);
|
networkSend(networkWriteBuffer, size);
|
||||||
|
|
Loading…
Add table
Reference in a new issue