Merge pull request #39 from speyejack/udp-client
Allow udp communication for movement
This commit is contained in:
commit
1da9626a44
10
Makefile
10
Makefile
|
@ -45,15 +45,15 @@ emu:
|
||||||
mv $(shell basename $(CURDIR))$(SMOVER).nso starlight_patch_$(SMOVER)/yuzu/subsdk1
|
mv $(shell basename $(CURDIR))$(SMOVER).nso starlight_patch_$(SMOVER)/yuzu/subsdk1
|
||||||
# builds and sends project to FTP server hosted on provided IP
|
# builds and sends project to FTP server hosted on provided IP
|
||||||
send: all
|
send: all
|
||||||
python3.8 scripts/sendPatch.py $(IP) $(PROJNAME)
|
python3 scripts/sendPatch.py $(IP) $(PROJNAME)
|
||||||
|
|
||||||
log: all
|
log: all
|
||||||
python3.8 scripts/tcpServer.py $(SERVERIP)
|
python3 scripts/tcpServer.py $(SERVERIP)
|
||||||
|
|
||||||
sendlog: all
|
sendlog: all
|
||||||
python3.8 scripts/sendPatch.py $(IP) $(PROJNAME) $(USER) $(PASS)
|
python3 scripts/sendPatch.py $(IP) $(PROJNAME) $(USER) $(PASS)
|
||||||
python3.8 scripts/tcpServer.py $(SERVERIP)
|
python3 scripts/tcpServer.py $(SERVERIP)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) clean -f MakefileNSO
|
$(MAKE) clean -f MakefileNSO
|
||||||
@rm -fr starlight_patch_*
|
@rm -fr starlight_patch_*
|
||||||
|
|
|
@ -37,8 +37,8 @@ namespace al {
|
||||||
al::GameDrawInfo *mDrawInfo; // 0x38 from Application::sInstance + 0x30
|
al::GameDrawInfo *mDrawInfo; // 0x38 from Application::sInstance + 0x30
|
||||||
ProjectNfpDirector *mProjNfpDirector; // 0x48
|
ProjectNfpDirector *mProjNfpDirector; // 0x48
|
||||||
al::HtmlViewer *mHtmlViewer; // 0x50
|
al::HtmlViewer *mHtmlViewer; // 0x50
|
||||||
ApplicationMessageReceiver *mMessageReciever; // 0x58
|
ApplicationMessageReceiver *mMessageReceiver; // 0x58
|
||||||
al::WaveVibrationHolder *mWaveVibrationHolder; // 0x60
|
al::WaveVibrationHolder *mWaveVibrationHolder; // 0x60
|
||||||
void *gap2;
|
void *gap2;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
|
|
||||||
|
struct pollfd
|
||||||
|
{
|
||||||
|
s32 fd;
|
||||||
|
s16 events;
|
||||||
|
s16 revents;
|
||||||
|
};
|
||||||
|
|
||||||
struct in_addr
|
struct in_addr
|
||||||
{
|
{
|
||||||
|
@ -38,13 +44,19 @@ s32 Connect(s32 socket, const sockaddr* address, u32 addressLen);
|
||||||
Result Close(s32 socket);
|
Result Close(s32 socket);
|
||||||
|
|
||||||
s32 Send(s32 socket, const void* data, ulong dataLen, s32 flags);
|
s32 Send(s32 socket, const void* data, ulong dataLen, s32 flags);
|
||||||
|
s32 SendTo(s32 socket, const void* data, ulong dataLen, s32 flags, const struct sockaddr* to, u32 toLen);
|
||||||
s32 Recv(s32 socket, void* out, ulong outLen, s32 flags);
|
s32 Recv(s32 socket, void* out, ulong outLen, s32 flags);
|
||||||
|
s32 RecvFrom(s32 socket, void* out, ulong outLen, s32 flags, struct sockaddr* from, u32* fromLen);
|
||||||
|
|
||||||
|
s32 GetSockName(s32 socket, struct sockaddr* name, u32* dataLen);
|
||||||
u16 InetHtons(u16 val);
|
u16 InetHtons(u16 val);
|
||||||
|
u16 InetNtohs(u16 val);
|
||||||
s32 InetAton(const char* addressStr, in_addr* addressOut);
|
s32 InetAton(const char* addressStr, in_addr* addressOut);
|
||||||
|
|
||||||
struct hostent* GetHostByName(const char* name);
|
struct hostent* GetHostByName(const char* name);
|
||||||
|
|
||||||
u32 GetLastErrno();
|
u32 GetLastErrno();
|
||||||
|
s32 Bind(s32 fd, sockaddr* addr, u32 addrlen);
|
||||||
|
s32 Poll(struct pollfd* fd, u64 addr, s32 timeout);
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Packet.h"
|
||||||
|
|
||||||
|
struct PACKED HolePunch : Packet {
|
||||||
|
HolePunch() : Packet() {this->mType = PacketType::HOLEPUNCH; mPacketSize = sizeof(HolePunch) - sizeof(Packet);};
|
||||||
|
};
|
|
@ -26,6 +26,8 @@ enum PacketType : short {
|
||||||
CAPTUREINF,
|
CAPTUREINF,
|
||||||
CHANGESTAGE,
|
CHANGESTAGE,
|
||||||
CMD,
|
CMD,
|
||||||
|
UDPINIT,
|
||||||
|
HOLEPUNCH,
|
||||||
End // end of enum for bounds checking
|
End // end of enum for bounds checking
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,7 +45,9 @@ USED static const char *packetNames[] = {
|
||||||
"Moon Collection",
|
"Moon Collection",
|
||||||
"Capture Info",
|
"Capture Info",
|
||||||
"Change Stage",
|
"Change Stage",
|
||||||
"Server Command"
|
"Server Command",
|
||||||
|
"Udp Initialization",
|
||||||
|
"Hole punch",
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SenderType {
|
enum SenderType {
|
||||||
|
@ -83,4 +87,6 @@ struct PACKED Packet {
|
||||||
#include "packets/CaptureInf.h"
|
#include "packets/CaptureInf.h"
|
||||||
#include "packets/HackCapInf.h"
|
#include "packets/HackCapInf.h"
|
||||||
#include "packets/ChangeStagePacket.h"
|
#include "packets/ChangeStagePacket.h"
|
||||||
#include "packets/InitPacket.h"
|
#include "packets/InitPacket.h"
|
||||||
|
#include "packets/UdpPacket.h"
|
||||||
|
#include "packets/HolePunchPacket.h"
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Packet.h"
|
||||||
|
|
||||||
|
struct PACKED UdpInit : Packet {
|
||||||
|
UdpInit() : Packet() {this->mType = PacketType::UDPINIT; mPacketSize = sizeof(UdpInit) - sizeof(Packet);};
|
||||||
|
u16 port = 0;
|
||||||
|
};
|
|
@ -194,6 +194,8 @@ class Client {
|
||||||
void updateTagInfo(TagInf *packet);
|
void updateTagInfo(TagInf *packet);
|
||||||
void updateCaptureInfo(CaptureInf* packet);
|
void updateCaptureInfo(CaptureInf* packet);
|
||||||
void sendToStage(ChangeStagePacket* packet);
|
void sendToStage(ChangeStagePacket* packet);
|
||||||
|
void sendUdpHolePunch();
|
||||||
|
void sendUdpInit();
|
||||||
void disconnectPlayer(PlayerDC *packet);
|
void disconnectPlayer(PlayerDC *packet);
|
||||||
|
|
||||||
PuppetInfo* findPuppetInfo(const nn::account::Uid& id, bool isFindAvailable);
|
PuppetInfo* findPuppetInfo(const nn::account::Uid& id, bool isFindAvailable);
|
||||||
|
@ -214,7 +216,7 @@ class Client {
|
||||||
|
|
||||||
// --- Server Syncing Members ---
|
// --- Server Syncing Members ---
|
||||||
|
|
||||||
// array of shine IDs for checking if multiple shines have been collected in quick sucession, all moons within the players stage that match the ID will be deleted
|
// array of shine IDs for checking if multiple shines have been collected in quick succession, all moons within the players stage that match the ID will be deleted
|
||||||
sead::SafeArray<int, 128> curCollectedShines;
|
sead::SafeArray<int, 128> curCollectedShines;
|
||||||
int collectedShineCount = 0;
|
int collectedShineCount = 0;
|
||||||
|
|
||||||
|
|
|
@ -31,12 +31,13 @@ class SocketClient : public SocketBase {
|
||||||
|
|
||||||
bool startThreads();
|
bool startThreads();
|
||||||
void endThreads();
|
void endThreads();
|
||||||
|
void waitForThreads();
|
||||||
|
|
||||||
bool send(Packet* packet);
|
bool send(Packet* packet);
|
||||||
bool recv();
|
bool recv();
|
||||||
|
|
||||||
bool queuePacket(Packet *packet);
|
bool queuePacket(Packet *packet);
|
||||||
void trySendQueue();
|
bool trySendQueue();
|
||||||
|
|
||||||
void sendFunc();
|
void sendFunc();
|
||||||
void recvFunc();
|
void recvFunc();
|
||||||
|
@ -46,6 +47,10 @@ class SocketClient : public SocketBase {
|
||||||
void printPacket(Packet* packet);
|
void printPacket(Packet* packet);
|
||||||
bool isConnected() { return socket_log_state == SOCKET_LOG_CONNECTED; }
|
bool isConnected() { return socket_log_state == SOCKET_LOG_CONNECTED; }
|
||||||
|
|
||||||
|
u16 getLocalUdpPort();
|
||||||
|
s32 setPeerUdpPort(u16 port);
|
||||||
|
const char* getUdpStateChar();
|
||||||
|
|
||||||
u32 getSendCount() { return mSendQueue.getCount(); }
|
u32 getSendCount() { return mSendQueue.getCount(); }
|
||||||
u32 getSendMaxCount() { return mSendQueue.getMaxCount(); }
|
u32 getSendMaxCount() { return mSendQueue.getMaxCount(); }
|
||||||
|
|
||||||
|
@ -67,12 +72,21 @@ class SocketClient : public SocketBase {
|
||||||
|
|
||||||
sead::MessageQueue mRecvQueue;
|
sead::MessageQueue mRecvQueue;
|
||||||
sead::MessageQueue mSendQueue;
|
sead::MessageQueue mSendQueue;
|
||||||
|
char* recvBuf = nullptr;
|
||||||
|
|
||||||
int maxBufSize = 100;
|
int maxBufSize = 100;
|
||||||
bool mIsFirstConnect = true;
|
bool mIsFirstConnect = true;
|
||||||
bool mPacketQueueOpen = true;
|
bool mPacketQueueOpen = true;
|
||||||
|
int pollTime = 0;
|
||||||
|
|
||||||
|
|
||||||
|
bool mHasRecvUdp;
|
||||||
|
s32 mUdpSocket;
|
||||||
|
sockaddr mUdpAddress;
|
||||||
|
|
||||||
|
bool recvTcp();
|
||||||
|
bool recvUdp();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param str a string containing an IPv4 address or a hostname that can be resolved via DNS
|
* @param str a string containing an IPv4 address or a hostname that can be resolved via DNS
|
||||||
* @param out IPv4 address
|
* @param out IPv4 address
|
||||||
|
|
|
@ -35,36 +35,37 @@ if '.' not in consoleIP:
|
||||||
print(sys.argv[0], "ERROR: Please specify with `IP=[Your console's IP]`")
|
print(sys.argv[0], "ERROR: Please specify with `IP=[Your console's IP]`")
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
isNeedOtherSwitch = True
|
isNeedOtherSwitch = False
|
||||||
|
|
||||||
altSwitchIP = sys.argv[2]
|
|
||||||
if '.' not in altSwitchIP:
|
|
||||||
isNeedOtherSwitch = False
|
|
||||||
|
|
||||||
consolePort = 5000
|
consolePort = 5000
|
||||||
|
|
||||||
if len(sys.argv) < 4:
|
if len(sys.argv) < 3:
|
||||||
projName = 'StarlightBase'
|
projName = 'StarlightBase'
|
||||||
else:
|
else:
|
||||||
projName = sys.argv[3]
|
projName = sys.argv[2]
|
||||||
|
|
||||||
|
if len(sys.argv) < 5:
|
||||||
|
user = 'crafty'
|
||||||
|
passwd = 'boss'
|
||||||
|
else:
|
||||||
|
user = sys.argv[3]
|
||||||
|
passwd = sys.argv[4]
|
||||||
|
|
||||||
curDir = os.curdir
|
curDir = os.curdir
|
||||||
|
|
||||||
ftp = FTP()
|
ftp = FTP()
|
||||||
|
|
||||||
otherftp = FTP()
|
|
||||||
|
|
||||||
print(f'Connecting to {consoleIP}... ', end='')
|
print(f'Connecting to {consoleIP}... ', end='')
|
||||||
ftp.connect(consoleIP, consolePort)
|
ftp.connect(consoleIP, consolePort)
|
||||||
print('logging into server...', end='')
|
print('logging into server...', end='')
|
||||||
ftp.login('crafty','boss')
|
ftp.login(user,passwd)
|
||||||
print('Connected!')
|
print('Connected!')
|
||||||
|
|
||||||
if isNeedOtherSwitch:
|
if isNeedOtherSwitch:
|
||||||
print(f'Connecting to {altSwitchIP}... ', end='')
|
print(f'Connecting to {altSwitchIP}... ', end='')
|
||||||
otherftp.connect(altSwitchIP, consolePort)
|
otherftp.connect(altSwitchIP, consolePort)
|
||||||
print('logging into server...', end='')
|
print('logging into server...', end='')
|
||||||
otherftp.login('crafty','boss')
|
otherftp.login(user,passwd)
|
||||||
print('Connected!')
|
print('Connected!')
|
||||||
|
|
||||||
patchDirectories = []
|
patchDirectories = []
|
||||||
|
|
|
@ -118,6 +118,7 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead:
|
||||||
}
|
}
|
||||||
|
|
||||||
gTextWriter->printf("Client Socket Connection Status: %s\n", Client::instance()->mSocket->getStateChar());
|
gTextWriter->printf("Client Socket Connection Status: %s\n", Client::instance()->mSocket->getStateChar());
|
||||||
|
gTextWriter->printf("Udp socket status: %s\n", Client::instance()->mSocket->getUdpStateChar());
|
||||||
//gTextWriter->printf("nn::socket::GetLastErrno: 0x%x\n", Client::instance()->mSocket->socket_errno);
|
//gTextWriter->printf("nn::socket::GetLastErrno: 0x%x\n", Client::instance()->mSocket->socket_errno);
|
||||||
gTextWriter->printf("Connected Players: %d/%d\n", Client::getConnectCount() + 1, Client::getMaxPlayerCount());
|
gTextWriter->printf("Connected Players: %d/%d\n", Client::getConnectCount() + 1, Client::getMaxPlayerCount());
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ PuppetHolder::PuppetHolder(int size) {
|
||||||
* @brief resizes puppet ptr array by creating a new ptr array and storing previous ptrs in it, before freeing the previous array
|
* @brief resizes puppet ptr array by creating a new ptr array and storing previous ptrs in it, before freeing the previous array
|
||||||
*
|
*
|
||||||
* @param size the size of the new ptr array
|
* @param size the size of the new ptr array
|
||||||
* @return returns true if resizing was sucessful
|
* @return returns true if resizing was successful
|
||||||
*/
|
*/
|
||||||
bool PuppetHolder::resizeHolder(int size) {
|
bool PuppetHolder::resizeHolder(int size) {
|
||||||
|
|
||||||
|
@ -106,4 +106,4 @@ bool PuppetHolder::checkInfoIsInStage(PuppetInfo *info) {
|
||||||
void PuppetHolder::setStageInfo(const char *stageName, u8 scenarioNo) {
|
void PuppetHolder::setStageInfo(const char *stageName, u8 scenarioNo) {
|
||||||
mStageName = stageName;
|
mStageName = stageName;
|
||||||
mScenarioNo = scenarioNo;
|
mScenarioNo = scenarioNo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,13 +89,13 @@ void Client::init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor hol
|
||||||
/**
|
/**
|
||||||
* @brief starts client read thread
|
* @brief starts client read thread
|
||||||
*
|
*
|
||||||
* @return true if read thread was sucessfully started
|
* @return true if read thread was succesfully started
|
||||||
* @return false if read thread was unable to start, or thread was already started.
|
* @return false if read thread was unable to start, or thread was already started.
|
||||||
*/
|
*/
|
||||||
bool Client::startThread() {
|
bool Client::startThread() {
|
||||||
if(mReadThread->isDone() ) {
|
if(mReadThread->isDone() ) {
|
||||||
mReadThread->start();
|
mReadThread->start();
|
||||||
Logger::log("Read Thread Sucessfully Started.\n");
|
Logger::log("Read Thread Successfully Started.\n");
|
||||||
return true;
|
return true;
|
||||||
}else {
|
}else {
|
||||||
Logger::log("Read Thread has already started! Or other unknown reason.\n");
|
Logger::log("Read Thread has already started! Or other unknown reason.\n");
|
||||||
|
@ -139,7 +139,7 @@ bool Client::startConnection() {
|
||||||
|
|
||||||
if (mIsConnectionActive) {
|
if (mIsConnectionActive) {
|
||||||
|
|
||||||
Logger::log("Sucessful Connection. Waiting to recieve init packet.\n");
|
Logger::log("Succesful Connection. Waiting to receive init packet.\n");
|
||||||
|
|
||||||
bool waitingForInitPacket = true;
|
bool waitingForInitPacket = true;
|
||||||
// wait for client init packet
|
// wait for client init packet
|
||||||
|
@ -163,11 +163,13 @@ bool Client::startConnection() {
|
||||||
mHeap->free(curPacket);
|
mHeap->free(curPacket);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Logger::log("Recieve failed! Stopping Connection.\n");
|
Logger::log("Receive failed! Stopping Connection.\n");
|
||||||
mIsConnectionActive = false;
|
mIsConnectionActive = false;
|
||||||
waitingForInitPacket = false;
|
waitingForInitPacket = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mIsConnectionActive;
|
return mIsConnectionActive;
|
||||||
|
@ -313,7 +315,7 @@ void Client::readFunc() {
|
||||||
|
|
||||||
while(mIsConnectionActive) {
|
while(mIsConnectionActive) {
|
||||||
|
|
||||||
Packet *curPacket = mSocket->tryGetPacket(); // will block until a packet has been recieved, or socket disconnected
|
Packet *curPacket = mSocket->tryGetPacket(); // will block until a packet has been received, or socket disconnected
|
||||||
|
|
||||||
if (curPacket) {
|
if (curPacket) {
|
||||||
|
|
||||||
|
@ -377,6 +379,19 @@ void Client::readFunc() {
|
||||||
maxPuppets = initPacket->maxPlayers - 1;
|
maxPuppets = initPacket->maxPlayers - 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PacketType::UDPINIT: {
|
||||||
|
UdpInit* initPacket = (UdpInit*)curPacket;
|
||||||
|
Logger::log("Received udp init packet from server\n");
|
||||||
|
|
||||||
|
sInstance->mSocket->setPeerUdpPort(initPacket->port);
|
||||||
|
sendUdpHolePunch();
|
||||||
|
sendUdpInit();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PacketType::HOLEPUNCH:
|
||||||
|
sendUdpHolePunch();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Logger::log("Discarding Unknown Packet Type.\n");
|
Logger::log("Discarding Unknown Packet Type.\n");
|
||||||
break;
|
break;
|
||||||
|
@ -384,8 +399,8 @@ void Client::readFunc() {
|
||||||
|
|
||||||
mHeap->free(curPacket);
|
mHeap->free(curPacket);
|
||||||
|
|
||||||
}else { // if false, socket has errored or disconnected, so close the socket and end this thread.
|
}else { // if false, socket has errored or disconnected, so restart the connection
|
||||||
Logger::log("Client Socket Encountered an Error! Errno: 0x%x\n", mSocket->socket_errno);
|
Logger::log("Client Socket Encountered an Error, restarting connection! Errno: 0x%x\n", mSocket->socket_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -967,7 +982,45 @@ void Client::sendToStage(ChangeStagePacket* packet) {
|
||||||
GameDataFunction::tryChangeNextStage(accessor, &info);
|
GameDataFunction::tryChangeNextStage(accessor, &info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Send a udp holepunch packet to the server
|
||||||
|
*/
|
||||||
|
void Client::sendUdpHolePunch() {
|
||||||
|
|
||||||
|
if (!sInstance) {
|
||||||
|
Logger::log("Static Instance is Null!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sead::ScopedCurrentHeapSetter setter(sInstance->mHeap);
|
||||||
|
|
||||||
|
HolePunch *packet = new HolePunch();
|
||||||
|
|
||||||
|
packet->mUserID = sInstance->mUserID;
|
||||||
|
|
||||||
|
sInstance->mSocket->queuePacket(packet);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Send a udp init packet to server
|
||||||
|
*/
|
||||||
|
void Client::sendUdpInit() {
|
||||||
|
|
||||||
|
if (!sInstance) {
|
||||||
|
Logger::log("Static Instance is Null!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sead::ScopedCurrentHeapSetter setter(sInstance->mHeap);
|
||||||
|
|
||||||
|
UdpInit *packet = new UdpInit();
|
||||||
|
|
||||||
|
packet->mUserID = sInstance->mUserID;
|
||||||
|
packet->port = sInstance->mSocket->getLocalUdpPort();
|
||||||
|
|
||||||
|
sInstance->mSocket->queuePacket(packet);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
|
|
|
@ -72,13 +72,13 @@ s32 SocketBase::getFd() {
|
||||||
|
|
||||||
bool SocketBase::closeSocket() {
|
bool SocketBase::closeSocket() {
|
||||||
|
|
||||||
if (this->socket_log_state != SOCKET_LOG_DISCONNECTED) {
|
if (this->socket_log_state != SOCKET_LOG_DISCONNECTED) {
|
||||||
nn::Result result = nn::socket::Close(this->socket_log_socket);
|
nn::Result result = nn::socket::Close(this->socket_log_socket);
|
||||||
if (result.isSuccess()) {
|
if (result.isSuccess()) {
|
||||||
this->socket_log_state = SOCKET_LOG_DISCONNECTED;
|
this->socket_log_state = SOCKET_LOG_DISCONNECTED;
|
||||||
}
|
}
|
||||||
return result.isSuccess();
|
return result.isSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "nn/result.h"
|
#include "nn/result.h"
|
||||||
#include "nn/socket.h"
|
#include "nn/socket.h"
|
||||||
#include "packets/Packet.h"
|
#include "packets/Packet.h"
|
||||||
|
#include "packets/UdpPacket.h"
|
||||||
#include "server/Client.hpp"
|
#include "server/Client.hpp"
|
||||||
#include "thread/seadMessageQueue.h"
|
#include "thread/seadMessageQueue.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
@ -16,12 +17,18 @@
|
||||||
SocketClient::SocketClient(const char* name, sead::Heap* heap, Client* client) : mHeap(heap), SocketBase(name) {
|
SocketClient::SocketClient(const char* name, sead::Heap* heap, Client* client) : mHeap(heap), SocketBase(name) {
|
||||||
|
|
||||||
this->client = client;
|
this->client = client;
|
||||||
|
#if EMU
|
||||||
|
this->pollTime = 0;
|
||||||
|
#else
|
||||||
|
this->pollTime = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
mRecvThread = new al::AsyncFunctorThread("SocketRecvThread", al::FunctorV0M<SocketClient*, SocketThreadFunc>(this, &SocketClient::recvFunc), 0, 0x1000, {0});
|
mRecvThread = new al::AsyncFunctorThread("SocketRecvThread", al::FunctorV0M<SocketClient*, SocketThreadFunc>(this, &SocketClient::recvFunc), 0, 0x1000, {0});
|
||||||
mSendThread = new al::AsyncFunctorThread("SocketSendThread", al::FunctorV0M<SocketClient*, SocketThreadFunc>(this, &SocketClient::sendFunc), 0, 0x1000, {0});
|
mSendThread = new al::AsyncFunctorThread("SocketSendThread", al::FunctorV0M<SocketClient*, SocketThreadFunc>(this, &SocketClient::sendFunc), 0, 0x1000, {0});
|
||||||
|
|
||||||
mRecvQueue.allocate(maxBufSize, mHeap);
|
mRecvQueue.allocate(maxBufSize, mHeap);
|
||||||
mSendQueue.allocate(maxBufSize, mHeap);
|
mSendQueue.allocate(maxBufSize, mHeap);
|
||||||
|
recvBuf = (char*)mHeap->alloc(MAXPACKSIZE+1);
|
||||||
};
|
};
|
||||||
|
|
||||||
nn::Result SocketClient::init(const char* ip, u16 port) {
|
nn::Result SocketClient::init(const char* ip, u16 port) {
|
||||||
|
@ -31,6 +38,7 @@ nn::Result SocketClient::init(const char* ip, u16 port) {
|
||||||
|
|
||||||
in_addr hostAddress = { 0 };
|
in_addr hostAddress = { 0 };
|
||||||
sockaddr serverAddress = { 0 };
|
sockaddr serverAddress = { 0 };
|
||||||
|
sockaddr udpAddress = { 0 };
|
||||||
|
|
||||||
Logger::log("SocketClient::init: %s:%d sock %s\n", ip, port, getStateChar());
|
Logger::log("SocketClient::init: %s:%d sock %s\n", ip, port, getStateChar());
|
||||||
|
|
||||||
|
@ -80,13 +88,25 @@ nn::Result SocketClient::init(const char* ip, u16 port) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((this->mUdpSocket = nn::socket::Socket(2, 2, 17)) < 0) {
|
||||||
|
Logger::log("Udp Socket failed to create");
|
||||||
|
this->socket_errno = nn::socket::GetLastErrno();
|
||||||
|
this->socket_log_state = SOCKET_LOG_UNAVAILABLE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
udpAddress.address = hostAddress;
|
||||||
|
udpAddress.port = 0;
|
||||||
|
udpAddress.family = 2;
|
||||||
|
this->mUdpAddress = udpAddress;
|
||||||
|
this->mHasRecvUdp = false;
|
||||||
this->mPacketQueueOpen = true;
|
this->mPacketQueueOpen = true;
|
||||||
|
|
||||||
this->socket_log_state = SOCKET_LOG_CONNECTED;
|
this->socket_log_state = SOCKET_LOG_CONNECTED;
|
||||||
|
|
||||||
Logger::log("Socket fd: %d\n", socket_log_socket);
|
Logger::log("Socket fd: %d\n", socket_log_socket);
|
||||||
|
|
||||||
startThreads(); // start recv and send threads after sucessful connection
|
startThreads(); // start recv and send threads after succesful connection
|
||||||
|
|
||||||
// send init packet to server once we connect (an issue with the server prevents this from working properly, waiting for a fix to implement)
|
// send init packet to server once we connect (an issue with the server prevents this from working properly, waiting for a fix to implement)
|
||||||
|
|
||||||
|
@ -127,24 +147,77 @@ nn::Result SocketClient::init(const char* ip, u16 port) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16 SocketClient::getLocalUdpPort() {
|
||||||
|
sockaddr udpAddress = { 0 };
|
||||||
|
u32 size = sizeof(udpAddress);
|
||||||
|
|
||||||
|
nn::Result result;
|
||||||
|
if((result = nn::socket::GetSockName(this->mUdpSocket, &udpAddress, &size)).isFailure()) {
|
||||||
|
this->socket_errno = nn::socket::GetLastErrno();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nn::socket::InetNtohs(udpAddress.port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
s32 SocketClient::setPeerUdpPort(u16 port) {
|
||||||
|
u16 net_port = nn::socket::InetHtons(port);
|
||||||
|
this->mUdpAddress.port = net_port;
|
||||||
|
|
||||||
|
nn::Result result;
|
||||||
|
if((result = nn::socket::Connect(this->mUdpSocket, &this->mUdpAddress, sizeof(this->mUdpAddress))).isFailure()) {
|
||||||
|
Logger::log("Udp socket connection failed to connect to port %d!\n", port);
|
||||||
|
this->socket_errno = nn::socket::GetLastErrno();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* SocketClient::getUdpStateChar() {
|
||||||
|
if (this->mUdpAddress.port == 0) {
|
||||||
|
return "Waiting for handshake";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this->mHasRecvUdp) {
|
||||||
|
return "Waiting for holepunch";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Utilizing UDP";
|
||||||
|
}
|
||||||
bool SocketClient::send(Packet *packet) {
|
bool SocketClient::send(Packet *packet) {
|
||||||
|
|
||||||
if (this->socket_log_state != SOCKET_LOG_CONNECTED)
|
if (this->socket_log_state != SOCKET_LOG_CONNECTED || packet == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
char* buffer = reinterpret_cast<char*>(packet);
|
char* buffer = reinterpret_cast<char*>(packet);
|
||||||
|
|
||||||
int valread = 0;
|
int valread = 0;
|
||||||
|
|
||||||
if (packet->mType != PLAYERINF && packet->mType != HACKCAPINF)
|
int fd = -1;
|
||||||
Logger::log("Sending packet: %s\n", packetNames[packet->mType]);
|
if ((packet->mType != PLAYERINF && packet->mType != HACKCAPINF && packet->mType != HOLEPUNCH)
|
||||||
|
|| (!this->mHasRecvUdp && packet->mType != HOLEPUNCH)
|
||||||
|
|| this->mUdpAddress.port == 0) {
|
||||||
|
|
||||||
if ((valread = nn::socket::Send(this->socket_log_socket, buffer, packet->mPacketSize + sizeof(Packet), 0) > 0)) {
|
if (packet->mType != PLAYERINF && packet->mType != HACKCAPINF) {
|
||||||
|
Logger::log("Sending packet: %s\n", packetNames[packet->mType]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = this->socket_log_socket;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
fd = this->mUdpSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((valread = nn::socket::Send(fd, buffer, packet->mPacketSize + sizeof(Packet), 0) > 0)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
Logger::log("Failed to Fully Send Packet! Result: %d Type: %s Packet Size: %d\n", valread, packetNames[packet->mType], packet->mPacketSize);
|
Logger::log("Failed to Fully Send Packet! Result: %d Type: %s Packet Size: %d\n", valread, packetNames[packet->mType], packet->mPacketSize);
|
||||||
this->socket_errno = nn::socket::GetLastErrno();
|
this->socket_errno = nn::socket::GetLastErrno();
|
||||||
this->tryReconnect();
|
this->closeSocket();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -155,20 +228,68 @@ bool SocketClient::recv() {
|
||||||
if (this->socket_log_state != SOCKET_LOG_CONNECTED) {
|
if (this->socket_log_state != SOCKET_LOG_CONNECTED) {
|
||||||
Logger::log("Unable To Receive! Socket Not Connected.\n");
|
Logger::log("Unable To Receive! Socket Not Connected.\n");
|
||||||
this->socket_errno = nn::socket::GetLastErrno();
|
this->socket_errno = nn::socket::GetLastErrno();
|
||||||
return this->tryReconnect();
|
this->closeSocket();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int fd_count = 2;
|
||||||
|
struct pollfd pfds[fd_count] = {{0}, {0}};
|
||||||
|
|
||||||
|
// TCP Connection
|
||||||
|
pfds[0].fd = this->socket_log_socket;
|
||||||
|
pfds[0].events = 1;
|
||||||
|
pfds[0].revents = 0;
|
||||||
|
|
||||||
|
// UDP Connection
|
||||||
|
pfds[1].fd = this->mUdpSocket;
|
||||||
|
pfds[1].events = 1;
|
||||||
|
pfds[1].revents = 0;
|
||||||
|
|
||||||
|
|
||||||
|
int result = nn::socket::Poll(pfds, fd_count, this->pollTime);
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
return true;
|
||||||
|
} else if (result < 0) {
|
||||||
|
Logger::log("Error occurred when polling for packets\n");
|
||||||
|
this->socket_errno = nn::socket::GetLastErrno();
|
||||||
|
this->closeSocket();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 index = -1;
|
||||||
|
for (int i = 0; i < fd_count; i++){
|
||||||
|
if (pfds[i].revents & 1) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
return recvTcp();
|
||||||
|
case 1:
|
||||||
|
return recvUdp();
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SocketClient::recvTcp() {
|
||||||
int headerSize = sizeof(Packet);
|
int headerSize = sizeof(Packet);
|
||||||
char headerBuf[sizeof(Packet)] = {};
|
|
||||||
int valread = 0;
|
int valread = 0;
|
||||||
|
s32 fd = this->socket_log_socket;
|
||||||
|
|
||||||
// read only the size of a header
|
// read only the size of a header
|
||||||
while(valread < headerSize) {
|
while(valread < headerSize) {
|
||||||
int result = nn::socket::Recv(this->socket_log_socket, headerBuf + valread,
|
int result = 0;
|
||||||
headerSize - valread, this->sock_flags);
|
result = nn::socket::Recv(fd, recvBuf + valread,
|
||||||
|
headerSize - valread, this->sock_flags);
|
||||||
|
|
||||||
this->socket_errno = nn::socket::GetLastErrno();
|
this->socket_errno = nn::socket::GetLastErrno();
|
||||||
|
|
||||||
if(result > 0) {
|
if(result > 0) {
|
||||||
valread += result;
|
valread += result;
|
||||||
} else {
|
} else {
|
||||||
|
@ -176,75 +297,129 @@ bool SocketClient::recv() {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
Logger::log("Header Read Failed! Value: %d Total Read: %d\n", result, valread);
|
Logger::log("Header Read Failed! Value: %d Total Read: %d\n", result, valread);
|
||||||
return this->tryReconnect(); // if we sucessfully reconnect, we dont want
|
this->closeSocket();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(valread > 0) {
|
if(valread <= 0) { // if we error'd, close the socket
|
||||||
Packet* header = reinterpret_cast<Packet*>(headerBuf);
|
|
||||||
|
|
||||||
int fullSize = header->mPacketSize + sizeof(Packet);
|
|
||||||
|
|
||||||
if (fullSize <= MAXPACKSIZE && fullSize > 0 && valread == sizeof(Packet)) {
|
|
||||||
|
|
||||||
if (header->mType != PLAYERINF && header->mType != HACKCAPINF) {
|
|
||||||
Logger::log("Received packet (from %02X%02X):", header->mUserID.data[0],
|
|
||||||
header->mUserID.data[1]);
|
|
||||||
Logger::disableName();
|
|
||||||
Logger::log(" Size: %d", header->mPacketSize);
|
|
||||||
Logger::log(" Type: %d", header->mType);
|
|
||||||
if(packetNames[header->mType])
|
|
||||||
Logger::log(" Type String: %s\n", packetNames[header->mType]);
|
|
||||||
Logger::enableName();
|
|
||||||
}
|
|
||||||
|
|
||||||
char* packetBuf = (char*)mHeap->alloc(fullSize);
|
|
||||||
|
|
||||||
if (packetBuf) {
|
|
||||||
|
|
||||||
memcpy(packetBuf, headerBuf, sizeof(Packet));
|
|
||||||
|
|
||||||
while (valread < fullSize) {
|
|
||||||
|
|
||||||
int result = nn::socket::Recv(this->socket_log_socket, packetBuf + valread,
|
|
||||||
fullSize - valread, this->sock_flags);
|
|
||||||
|
|
||||||
this->socket_errno = nn::socket::GetLastErrno();
|
|
||||||
|
|
||||||
if (result > 0) {
|
|
||||||
valread += result;
|
|
||||||
} else {
|
|
||||||
mHeap->free(packetBuf);
|
|
||||||
Logger::log("Packet Read Failed! Value: %d\nPacket Size: %d\nPacket Type: %s\n", result, header->mPacketSize, packetNames[header->mType]);
|
|
||||||
return this->tryReconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(header->mType > PacketType::UNKNOWN && header->mType < PacketType::End)) {
|
|
||||||
Logger::log("Failed to acquire valid packet type! Packet Type: %d Full Packet Size %d valread size: %d", header->mType, fullSize, valread);
|
|
||||||
mHeap->free(packetBuf);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Packet *packet = reinterpret_cast<Packet*>(packetBuf);
|
|
||||||
|
|
||||||
if (!mRecvQueue.isFull() && mPacketQueueOpen) {
|
|
||||||
mRecvQueue.push((s64)packet, sead::MessageQueue::BlockType::NonBlocking);
|
|
||||||
} else {
|
|
||||||
mHeap->free(packetBuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Logger::log("Failed to acquire valid data! Packet Type: %d Full Packet Size %d valread size: %d", header->mType, fullSize, valread);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} else { // if we error'd, close the socket
|
|
||||||
Logger::log("valread was zero! Disconnecting.\n");
|
Logger::log("valread was zero! Disconnecting.\n");
|
||||||
this->socket_errno = nn::socket::GetLastErrno();
|
this->socket_errno = nn::socket::GetLastErrno();
|
||||||
return this->tryReconnect();
|
this->closeSocket();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Packet* header = reinterpret_cast<Packet*>(recvBuf);
|
||||||
|
int fullSize = header->mPacketSize + sizeof(Packet);
|
||||||
|
|
||||||
|
if (!(fullSize <= MAXPACKSIZE && fullSize > 0 && valread == sizeof(Packet))) {
|
||||||
|
Logger::log("Failed to acquire valid data! Packet Type: %d Full Packet Size %d valread size: %d\n", header->mType, fullSize, valread);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header->mType != PLAYERINF && header->mType != HACKCAPINF) {
|
||||||
|
Logger::log("Received packet (from %02X%02X):", header->mUserID.data[0],
|
||||||
|
header->mUserID.data[1]);
|
||||||
|
Logger::disableName();
|
||||||
|
Logger::log(" Size: %d", header->mPacketSize);
|
||||||
|
Logger::log(" Type: %d", header->mType);
|
||||||
|
if(packetNames[header->mType])
|
||||||
|
Logger::log(" Type String: %s\n", packetNames[header->mType]);
|
||||||
|
Logger::enableName();
|
||||||
|
}
|
||||||
|
|
||||||
|
char* packetBuf = (char*)mHeap->alloc(fullSize);
|
||||||
|
|
||||||
|
if (!packetBuf) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
memcpy(packetBuf, recvBuf, sizeof(Packet));
|
||||||
|
|
||||||
|
while (valread < fullSize) {
|
||||||
|
|
||||||
|
int result = nn::socket::Recv(fd, packetBuf + valread,
|
||||||
|
fullSize - valread, this->sock_flags);
|
||||||
|
|
||||||
|
this->socket_errno = nn::socket::GetLastErrno();
|
||||||
|
|
||||||
|
if (result > 0) {
|
||||||
|
valread += result;
|
||||||
|
} else {
|
||||||
|
mHeap->free(packetBuf);
|
||||||
|
Logger::log("Packet Read Failed! Value: %d\nPacket Size: %d\nPacket Type: %s\n", result, header->mPacketSize, packetNames[header->mType]);
|
||||||
|
this->closeSocket();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(header->mType > PacketType::UNKNOWN && header->mType < PacketType::End)) {
|
||||||
|
Logger::log("Failed to acquire valid packet type! Packet Type: %d Full Packet Size %d valread size: %d\n", header->mType, fullSize, valread);
|
||||||
|
mHeap->free(packetBuf);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Packet *packet = reinterpret_cast<Packet*>(packetBuf);
|
||||||
|
|
||||||
|
if (!mRecvQueue.isFull() && mPacketQueueOpen) {
|
||||||
|
mRecvQueue.push((s64)packet, sead::MessageQueue::BlockType::NonBlocking);
|
||||||
|
} else {
|
||||||
|
mHeap->free(packetBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SocketClient::recvUdp() {
|
||||||
|
int headerSize = sizeof(Packet);
|
||||||
|
s32 fd = this->mUdpSocket;
|
||||||
|
|
||||||
|
int valread = nn::socket::Recv(fd, recvBuf, MAXPACKSIZE, this->sock_flags);
|
||||||
|
|
||||||
|
if (valread == 0) {
|
||||||
|
Logger::log("Udp connection valread was zero. Disconnecting.\n");
|
||||||
|
this->closeSocket();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valread < headerSize){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Packet* header = reinterpret_cast<Packet*>(recvBuf);
|
||||||
|
int fullSize = header->mPacketSize + sizeof(Packet);
|
||||||
|
// Verify packet size is appropriate
|
||||||
|
if (valread < fullSize || valread > MAXPACKSIZE || fullSize > MAXPACKSIZE){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify type of packet
|
||||||
|
if (!(header->mType > PacketType::UNKNOWN && header->mType < PacketType::End)) {
|
||||||
|
Logger::log("Failed to acquire valid packet type! Packet Type: %d Full Packet Size %d valread size: %d\n", header->mType, fullSize, valread);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->mHasRecvUdp = true;
|
||||||
|
|
||||||
|
char* packetBuf = (char*)mHeap->alloc(fullSize);
|
||||||
|
if (!packetBuf) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(packetBuf, recvBuf, fullSize);
|
||||||
|
|
||||||
|
|
||||||
|
Packet *packet = reinterpret_cast<Packet*>(packetBuf);
|
||||||
|
|
||||||
|
if(!mRecvQueue.isFull()) {
|
||||||
|
mRecvQueue.push((s64)packet, sead::MessageQueue::BlockType::NonBlocking);
|
||||||
|
} else {
|
||||||
|
mHeap->free(packetBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// prints packet to debug logger
|
// prints packet to debug logger
|
||||||
|
@ -281,6 +456,8 @@ bool SocketClient::closeSocket() {
|
||||||
|
|
||||||
Logger::log("Closing Socket.\n");
|
Logger::log("Closing Socket.\n");
|
||||||
|
|
||||||
|
mHasRecvUdp = false;
|
||||||
|
mUdpAddress.port = 0;
|
||||||
mPacketQueueOpen = false;
|
mPacketQueueOpen = false;
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
@ -315,7 +492,7 @@ bool SocketClient::stringToIPAddress(const char* str, in_addr* out) {
|
||||||
/**
|
/**
|
||||||
* @brief starts client read thread
|
* @brief starts client read thread
|
||||||
*
|
*
|
||||||
* @return true if read thread was sucessfully started
|
* @return true if read thread was successfully started
|
||||||
* @return false if read thread was unable to start, or thread was already started.
|
* @return false if read thread was unable to start, or thread was already started.
|
||||||
*/
|
*/
|
||||||
bool SocketClient::startThreads() {
|
bool SocketClient::startThreads() {
|
||||||
|
@ -326,7 +503,7 @@ bool SocketClient::startThreads() {
|
||||||
if(this->mRecvThread->isDone() && this->mSendThread->isDone()) {
|
if(this->mRecvThread->isDone() && this->mSendThread->isDone()) {
|
||||||
this->mRecvThread->start();
|
this->mRecvThread->start();
|
||||||
this->mSendThread->start();
|
this->mSendThread->start();
|
||||||
Logger::log("Socket threads sucessfully started.\n");
|
Logger::log("Socket threads succesfully started.\n");
|
||||||
return true;
|
return true;
|
||||||
}else {
|
}else {
|
||||||
Logger::log("Socket threads failed to start.\n");
|
Logger::log("Socket threads failed to start.\n");
|
||||||
|
@ -339,14 +516,18 @@ void SocketClient::endThreads() {
|
||||||
mSendThread->mDelegateThread->destroy();
|
mSendThread->mDelegateThread->destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SocketClient::waitForThreads() {
|
||||||
|
while (!mRecvThread->isDone()){}
|
||||||
|
while (!mSendThread->isDone()){}
|
||||||
|
}
|
||||||
|
|
||||||
void SocketClient::sendFunc() {
|
void SocketClient::sendFunc() {
|
||||||
|
|
||||||
Logger::log("Starting Send Thread.\n");
|
Logger::log("Starting Send Thread.\n");
|
||||||
|
|
||||||
while (true) {
|
while (trySendQueue() || socket_log_state != SOCKET_LOG_DISCONNECTED) {}
|
||||||
trySendQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Logger::log("Sending packet failed!\n");
|
||||||
Logger::log("Ending Send Thread.\n");
|
Logger::log("Ending Send Thread.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,12 +537,13 @@ void SocketClient::recvFunc() {
|
||||||
|
|
||||||
Logger::log("Starting Recv Thread.\n");
|
Logger::log("Starting Recv Thread.\n");
|
||||||
|
|
||||||
while (true) {
|
while (recv() || socket_log_state != SOCKET_LOG_DISCONNECTED) {}
|
||||||
if (!recv()) {
|
|
||||||
Logger::log("Receiving Packet Failed!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Free up all blocked threads
|
||||||
|
mSendQueue.push(0, sead::MessageQueue::BlockType::NonBlocking);
|
||||||
|
mRecvQueue.push(0, sead::MessageQueue::BlockType::NonBlocking);
|
||||||
|
|
||||||
|
Logger::log("Receiving Packet Failed!\n");
|
||||||
Logger::log("Ending Recv Thread.\n");
|
Logger::log("Ending Recv Thread.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,13 +559,15 @@ bool SocketClient::queuePacket(Packet* packet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketClient::trySendQueue() {
|
bool SocketClient::trySendQueue() {
|
||||||
|
|
||||||
Packet* curPacket = (Packet*)mSendQueue.pop(sead::MessageQueue::BlockType::Blocking);
|
Packet* curPacket = (Packet*)mSendQueue.pop(sead::MessageQueue::BlockType::Blocking);
|
||||||
|
|
||||||
send(curPacket);
|
bool successful = send(curPacket);
|
||||||
|
|
||||||
mHeap->free(curPacket);
|
mHeap->free(curPacket);
|
||||||
|
|
||||||
|
return successful;
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet* SocketClient::tryGetPacket(sead::MessageQueue::BlockType blockType) {
|
Packet* SocketClient::tryGetPacket(sead::MessageQueue::BlockType blockType) {
|
||||||
|
|
|
@ -111,7 +111,7 @@ void Logger::log(const char* fmt, ...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Logger::pingSocket() {
|
bool Logger::pingSocket() {
|
||||||
return socket_log("ping") > 0; // if value is greater than zero, than the socket recieved our message, otherwise the connection was lost.
|
return socket_log("ping") > 0; // if value is greater than zero, than the socket received our message, otherwise the connection was lost.
|
||||||
}
|
}
|
||||||
|
|
||||||
void tryInitSocket() {
|
void tryInitSocket() {
|
||||||
|
@ -119,4 +119,4 @@ void tryInitSocket() {
|
||||||
#if DEBUGLOG
|
#if DEBUGLOG
|
||||||
Logger::createInstance(); // creates a static instance for debug logger
|
Logger::createInstance(); // creates a static instance for debug logger
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue