From b18671f11337b6c0d9252d29223dbb2bcb8544f3 Mon Sep 17 00:00:00 2001 From: Jack Garrard Date: Sat, 27 Aug 2022 01:47:52 -0700 Subject: [PATCH 01/11] Move packet type check to after packet data recv --- source/server/SocketClient.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/server/SocketClient.cpp b/source/server/SocketClient.cpp index 8abc7e6..407ac98 100644 --- a/source/server/SocketClient.cpp +++ b/source/server/SocketClient.cpp @@ -133,8 +133,7 @@ bool SocketClient::RECV() { int fullSize = header->mPacketSize + sizeof(Packet); - if (header->mType > PacketType::UNKNOWN && header->mType < PacketType::End && - fullSize <= MAXPACKSIZE && fullSize > 0 && valread == 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], @@ -171,6 +170,12 @@ bool SocketClient::RECV() { } } + 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); + free(packetBuf); + return true; + } + Packet *packet = reinterpret_cast(packetBuf); if(mPacketQueue.size() < maxBufSize - 1) { @@ -180,7 +185,7 @@ bool SocketClient::RECV() { } } } else { - Logger::log("Failed to aquire valid data! Packet Type: %d Full Packet Size %d valread size: %d", header->mType, fullSize, valread); + Logger::log("Failed to acquire valid data! Packet Type: %d Full Packet Size %d valread size: %d", header->mType, fullSize, valread); } return true; From 7c17db2d93d1d2f077420c25aeba59264ba2632c Mon Sep 17 00:00:00 2001 From: Jack Garrard Date: Sun, 23 Oct 2022 14:41:16 -0700 Subject: [PATCH 02/11] Fix free issue from wrong heap if unknown packet --- source/server/SocketClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/server/SocketClient.cpp b/source/server/SocketClient.cpp index 310ce9c..ec89113 100644 --- a/source/server/SocketClient.cpp +++ b/source/server/SocketClient.cpp @@ -199,7 +199,7 @@ bool SocketClient::recv() { 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); - free(packetBuf); + mHeap->free(packetBuf); return true; } From 89415e6f969ed7171cc83221b91032d3053fef73 Mon Sep 17 00:00:00 2001 From: Jack Garrard Date: Thu, 27 Oct 2022 00:26:26 -0700 Subject: [PATCH 03/11] Hopefully prevent close socket race condition --- source/server/SocketBase.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/source/server/SocketBase.cpp b/source/server/SocketBase.cpp index 4f82d95..b9c408a 100644 --- a/source/server/SocketBase.cpp +++ b/source/server/SocketBase.cpp @@ -72,12 +72,13 @@ s32 SocketBase::getFd() { bool SocketBase::closeSocket() { - this->socket_log_state = SOCKET_LOG_DISCONNECTED; // probably not safe to assume socket will be closed + if (this->socket_log_state != SOCKET_LOG_DISCONNECTED) { + nn::Result result = nn::socket::Close(this->socket_log_socket); + if (result.isSuccess()) { + this->socket_log_state = SOCKET_LOG_DISCONNECTED; + } + return result.isSuccess(); + } - nn::Result result = nn::socket::Close(this->socket_log_socket); - - return result.isSuccess(); + return true; } - - - From 64b56c32dac2d435b125932f8379d88fa7ab6748 Mon Sep 17 00:00:00 2001 From: Jack Garrard Date: Thu, 27 Oct 2022 01:02:32 -0700 Subject: [PATCH 04/11] Add race protection to message queues --- include/server/SocketClient.hpp | 6 ++++++ source/server/Client.cpp | 8 +++++++- source/server/SocketClient.cpp | 25 +++++++++++++++++++++++-- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/include/server/SocketClient.hpp b/include/server/SocketClient.hpp index 2f6dd74..fcecd97 100644 --- a/include/server/SocketClient.hpp +++ b/include/server/SocketClient.hpp @@ -50,6 +50,10 @@ class SocketClient : public SocketBase { u32 getRecvCount() { return mRecvQueue.getCount(); } u32 getRecvMaxCount() { return mRecvQueue.getMaxCount(); } + void clearMessageQueues(); + void setQueueOpen(bool value) { mPacketQueueOpen = value; } + + void setIsFirstConn(bool value) { mIsFirstConnect = value; } private: @@ -63,6 +67,8 @@ class SocketClient : public SocketBase { int maxBufSize = 100; bool mIsFirstConnect = true; + bool mPacketQueueOpen = true; + /** * @param str a string containing an IPv4 address or a hostname that can be resolved via DNS diff --git a/source/server/Client.cpp b/source/server/Client.cpp index 9f8f1c4..b77c5ca 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -122,7 +122,13 @@ void Client::restartConnection() { playerDC->mUserID = sInstance->mUserID; - sInstance->mSocket->queuePacket(playerDC); + + sInstance->mSocket->setQueueOpen(false); + sInstance->mSocket->clearMessageQueues(); + + sInstance->mSocket->send(playerDC); + + sInstance->mHeap->free(playerDC); if (sInstance->mSocket->closeSocket()) { Logger::log("Sucessfully Closed Socket.\n"); diff --git a/source/server/SocketClient.cpp b/source/server/SocketClient.cpp index ec89113..4bec07a 100644 --- a/source/server/SocketClient.cpp +++ b/source/server/SocketClient.cpp @@ -78,6 +78,8 @@ nn::Result SocketClient::init(const char* ip, u16 port) { return result; } + this->mPacketQueueOpen = true; + this->socket_log_state = SOCKET_LOG_CONNECTED; Logger::log("Socket fd: %d\n", socket_log_socket); @@ -205,7 +207,7 @@ bool SocketClient::recv() { Packet *packet = reinterpret_cast(packetBuf); - if (!mRecvQueue.isFull()) { + if (!mRecvQueue.isFull() && mPacketQueueOpen) { mRecvQueue.push((s64)packet, sead::MessageQueue::BlockType::NonBlocking); } else { mHeap->free(packetBuf); @@ -257,6 +259,8 @@ bool SocketClient::closeSocket() { Logger::log("Closing Socket.\n"); + mPacketQueueOpen = false; + bool result = false; if (!(result = SocketBase::closeSocket())) { @@ -340,7 +344,7 @@ void SocketClient::recvFunc() { } bool SocketClient::queuePacket(Packet* packet) { - if (socket_log_state == SOCKET_LOG_CONNECTED) { + if (socket_log_state == SOCKET_LOG_CONNECTED && mPacketQueueOpen) { mSendQueue.push((s64)packet, sead::MessageQueue::BlockType::NonBlocking); // as this is non-blocking, it // will always return true. @@ -363,3 +367,20 @@ void SocketClient::trySendQueue() { Packet* SocketClient::tryGetPacket(sead::MessageQueue::BlockType blockType) { return socket_log_state == SOCKET_LOG_CONNECTED ? (Packet*)mRecvQueue.pop(blockType) : nullptr; } + +void SocketClient::clearMessageQueues() { + bool prevQueueOpenness = this->mPacketQueueOpen; + this->mPacketQueueOpen = false; + + while (mSendQueue.getCount() > 0) { + Packet* curPacket = (Packet*)mSendQueue.pop(sead::MessageQueue::BlockType::Blocking); + mHeap->free(curPacket); + } + + while (mRecvQueue.getCount() > 0) { + Packet* curPacket = (Packet*)mRecvQueue.pop(sead::MessageQueue::BlockType::Blocking); + mHeap->free(curPacket); + } + + this->mPacketQueueOpen = prevQueueOpenness; +} From 27b9a095f7b6bd8d1c02eef80afee35ab53f7d94 Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Fri, 23 Jun 2023 04:18:41 +0200 Subject: [PATCH 05/11] fix: mark player as not a seeker when H&S is disabled If a player is a seeker and then disables H&S, they should no longer be considered as a seeker by other players. (Because staying as a seeker will kill hiders when touching them). --- source/server/Client.cpp | 2 +- source/server/hns/HideAndSeekMode.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/source/server/Client.cpp b/source/server/Client.cpp index 4457ef0..c047fdd 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -622,7 +622,7 @@ void Client::sendTagInfPacket() { packet->mUserID = sInstance->mUserID; - packet->isIt = hsMode->isPlayerIt(); + packet->isIt = hsMode->isPlayerIt() && hsMode->isModeActive(); packet->minutes = curInfo->mHidingTime.mMinutes; packet->seconds = curInfo->mHidingTime.mSeconds; diff --git a/source/server/hns/HideAndSeekMode.cpp b/source/server/hns/HideAndSeekMode.cpp index 65e97c0..9efbdaf 100644 --- a/source/server/hns/HideAndSeekMode.cpp +++ b/source/server/hns/HideAndSeekMode.cpp @@ -84,6 +84,8 @@ void HideAndSeekMode::begin() { playGuideLyt->end(); GameModeBase::begin(); + + Client::sendTagInfPacket(); } void HideAndSeekMode::end() { @@ -109,6 +111,8 @@ void HideAndSeekMode::end() { playGuideLyt->appear(); GameModeBase::end(); + + Client::sendTagInfPacket(); } void HideAndSeekMode::update() { From 48356926727033f5b8bcb4556b5e35614c55f6f2 Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Sat, 24 Jun 2023 01:27:14 +0200 Subject: [PATCH 06/11] fix: resend TagInf packet on reconnect and for new players --- include/server/Client.hpp | 1 + source/server/Client.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/include/server/Client.hpp b/include/server/Client.hpp index 028fee9..5a0b4a3 100644 --- a/include/server/Client.hpp +++ b/include/server/Client.hpp @@ -229,6 +229,7 @@ class Client { GameInf lastGameInfPacket = GameInf(); GameInf emptyGameInfPacket = GameInf(); CostumeInf lastCostumeInfPacket = CostumeInf(); + TagInf lastTagInfPacket = TagInf(); Keyboard* mKeyboard = nullptr; // keyboard for setting server IP diff --git a/source/server/Client.cpp b/source/server/Client.cpp index 4457ef0..cb59fe2 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -361,6 +361,8 @@ void Client::readFunc() { mSocket->send(&lastPlayerInfPacket); if (lastCostumeInfPacket.mUserID == mUserID) mSocket->send(&lastCostumeInfPacket); + if (lastTagInfPacket.mUserID == mUserID) + mSocket->send(&lastTagInfPacket); break; case PacketType::COSTUMEINF: @@ -629,6 +631,8 @@ void Client::sendTagInfPacket() { packet->updateType = static_cast(TagUpdateType::STATE | TagUpdateType::TIME); sInstance->mSocket->queuePacket(packet); + + sInstance->lastTagInfPacket = *packet; } /** @@ -696,6 +700,11 @@ void Client::resendInitPackets() { if (lastGameInfPacket != emptyGameInfPacket) { mSocket->queuePacket(&lastGameInfPacket); } + + // TagInfPacket + if (lastTagInfPacket.mUserID == mUserID) { + mSocket->queuePacket(&lastTagInfPacket); + } } /** From 2bef6f796ec4c9dd6f50e66787d1972f9e78a12b Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Sat, 24 Jun 2023 02:42:54 +0200 Subject: [PATCH 07/11] fix: resend CaptureInf packet on reconnect and for new players --- include/server/Client.hpp | 1 + source/server/Client.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/include/server/Client.hpp b/include/server/Client.hpp index 5a0b4a3..4ced2aa 100644 --- a/include/server/Client.hpp +++ b/include/server/Client.hpp @@ -230,6 +230,7 @@ class Client { GameInf emptyGameInfPacket = GameInf(); CostumeInf lastCostumeInfPacket = CostumeInf(); TagInf lastTagInfPacket = TagInf(); + CaptureInf lastCaptureInfPacket = CaptureInf(); Keyboard* mKeyboard = nullptr; // keyboard for setting server IP diff --git a/source/server/Client.cpp b/source/server/Client.cpp index cb59fe2..ccc81b2 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -363,6 +363,8 @@ void Client::readFunc() { mSocket->send(&lastCostumeInfPacket); if (lastTagInfPacket.mUserID == mUserID) mSocket->send(&lastTagInfPacket); + if (lastCaptureInfPacket.mUserID == mUserID) + mSocket->send(&lastCaptureInfPacket); break; case PacketType::COSTUMEINF: @@ -677,12 +679,14 @@ void Client::sendCaptureInfPacket(const PlayerActorHakoniwa* player) { packet->mUserID = sInstance->mUserID; strcpy(packet->hackName, tryConvertName(player->mHackKeeper->getCurrentHackName())); sInstance->mSocket->queuePacket(packet); + sInstance->lastCaptureInfPacket = *packet; sInstance->isSentCaptureInf = true; } else if (!sInstance->isClientCaptured && sInstance->isSentCaptureInf) { CaptureInf *packet = new CaptureInf(); packet->mUserID = sInstance->mUserID; strcpy(packet->hackName, ""); sInstance->mSocket->queuePacket(packet); + sInstance->lastCaptureInfPacket = *packet; sInstance->isSentCaptureInf = false; } } @@ -705,6 +709,11 @@ void Client::resendInitPackets() { if (lastTagInfPacket.mUserID == mUserID) { mSocket->queuePacket(&lastTagInfPacket); } + + // CaptureInfPacket + if (lastCaptureInfPacket.mUserID == mUserID) { + mSocket->queuePacket(&lastCaptureInfPacket); + } } /** From f810e8f07d742bb5ca4a50113ac471c60d898620 Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Sat, 24 Jun 2023 04:09:47 +0200 Subject: [PATCH 08/11] fix: send empty TagInf and CaptureInf on first connection Because other players might still have old values saved in their puppet. --- source/server/SocketClient.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/source/server/SocketClient.cpp b/source/server/SocketClient.cpp index 2389cc7..9495df2 100644 --- a/source/server/SocketClient.cpp +++ b/source/server/SocketClient.cpp @@ -104,6 +104,21 @@ nn::Result SocketClient::init(const char* ip, u16 port) { // on a reconnect, resend some maybe missing packets if (initPacket.conType == ConnectionTypes::RECONNECT) { client->resendInitPackets(); + } else { + // empty TagInf + TagInf tagInf; + tagInf.mUserID = initPacket.mUserID; + tagInf.isIt = false; + tagInf.minutes = 0; + tagInf.seconds = 0; + tagInf.updateType = static_cast(TagUpdateType::STATE | TagUpdateType::TIME); + send(&tagInf); + + // empty CaptureInf + CaptureInf capInf; + capInf.mUserID = initPacket.mUserID; + strcpy(capInf.hackName, ""); + send(&capInf); } return result; From 366ad5e8886516d21bd7df7145e345190f6e8074 Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Fri, 7 Jul 2023 23:30:10 +0200 Subject: [PATCH 09/11] remove reconnect button --- .../StageSceneStateServerConfig.hpp | 9 +-- include/server/Client.hpp | 10 --- source/server/Client.cpp | 77 ------------------- source/states/StageSceneStateServerConfig.cpp | 48 +----------- 4 files changed, 6 insertions(+), 138 deletions(-) diff --git a/include/game/StageScene/StageSceneStateServerConfig.hpp b/include/game/StageScene/StageSceneStateServerConfig.hpp index 8956bdc..9f9c245 100644 --- a/include/game/StageScene/StageSceneStateServerConfig.hpp +++ b/include/game/StageScene/StageSceneStateServerConfig.hpp @@ -29,7 +29,6 @@ class StageSceneStateServerConfig : public al::HostStateBase, public enum ServerConfigOption { GAMEMODECONFIG, GAMEMODESWITCH, - RECONNECT, SETIP, SETPORT }; @@ -42,11 +41,9 @@ class StageSceneStateServerConfig : public al::HostStateBase, public void exeMainMenu(); void exeOpenKeyboardIP(); void exeOpenKeyboardPort(); - void exeRestartServer(); void exeGamemodeConfig(); void exeGamemodeSelect(); void exeSaveData(); - void exeConnectError(); void endSubMenu(); @@ -63,7 +60,7 @@ class StageSceneStateServerConfig : public al::HostStateBase, public SimpleLayoutMenu* mCurrentMenu = nullptr; CommonVerticalList* mCurrentList = nullptr; - // Root Page, contains buttons for gamemode config, server reconnecting, and server ip address changing + // Root Page, contains buttons for gamemode config, and server ip address changing SimpleLayoutMenu* mMainOptions = nullptr; CommonVerticalList *mMainOptionsList = nullptr; // Sub-Page of Mode config, used to select a gamemode for the client to use @@ -86,9 +83,7 @@ namespace { NERVE_HEADER(StageSceneStateServerConfig, MainMenu) NERVE_HEADER(StageSceneStateServerConfig, OpenKeyboardIP) NERVE_HEADER(StageSceneStateServerConfig, OpenKeyboardPort) - NERVE_HEADER(StageSceneStateServerConfig, RestartServer) NERVE_HEADER(StageSceneStateServerConfig, GamemodeConfig) NERVE_HEADER(StageSceneStateServerConfig, GamemodeSelect) NERVE_HEADER(StageSceneStateServerConfig, SaveData) - NERVE_HEADER(StageSceneStateServerConfig, ConnectError) -} \ No newline at end of file +} diff --git a/include/server/Client.hpp b/include/server/Client.hpp index 028fee9..fb63593 100644 --- a/include/server/Client.hpp +++ b/include/server/Client.hpp @@ -16,7 +16,6 @@ #include "al/LiveActor/LiveActor.h" #include "al/layout/LayoutInitInfo.h" #include "al/layout/SimpleLayoutAppearWaitEnd.h" -#include "al/layout/WindowConfirmWait.h" #include "al/util.hpp" #include "al/layout/LayoutActor.h" #include "al/gamepad/util.h" @@ -88,7 +87,6 @@ class Client { bool startThread(); void readFunc(); - static void restartConnection(); static bool isSocketActive() { return sInstance ? sInstance->mSocket->isConnected() : false; }; bool isPlayerConnected(int index) { return mPuppetInfoArr[index]->isConnected; } @@ -175,12 +173,6 @@ class Client { static bool openKeyboardIP(); static bool openKeyboardPort(); - static void showConnect(); - - static void showConnectError(const char16_t* msg); - - static void hideConnect(); - void resetCollectedShines(); void removeShine(int shineId); @@ -241,8 +233,6 @@ class Client { // --- Game Layouts --- - al::WindowConfirmWait* mConnectionWait; - al::SimpleLayoutAppearWaitEnd *mConnectStatus; // --- Game Info --- diff --git a/source/server/Client.cpp b/source/server/Client.cpp index 4457ef0..a53fcda 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -71,13 +71,8 @@ Client::Client() { */ void Client::init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor holder) { - mConnectionWait = new (mHeap) al::WindowConfirmWait("ServerWaitConnect", "WindowConfirmWait", initInfo); - mConnectStatus = new (mHeap) al::SimpleLayoutAppearWaitEnd("", "SaveMessage", initInfo, 0, false); - mConnectionWait->setTxtMessage(u"Connecting to Server."); - mConnectionWait->setTxtMessageConfirm(u"Failed to Connect!"); - al::setPaneString(mConnectStatus, "TxtSave", u"Connecting to Server.", 0); al::setPaneString(mConnectStatus, "TxtSaveSh", u"Connecting to Server.", 0); @@ -105,44 +100,6 @@ bool Client::startThread() { } } -/** - * @brief restarts currently active connection to server - * - */ -void Client::restartConnection() { - - if (!sInstance) { - Logger::log("Static Instance is null!\n"); - return; - } - - sead::ScopedCurrentHeapSetter setter(sInstance->mHeap); - - Logger::log("Sending Disconnect.\n"); - - PlayerDC *playerDC = new PlayerDC(); - - playerDC->mUserID = sInstance->mUserID; - - sInstance->mSocket->queuePacket(playerDC); - - if (sInstance->mSocket->closeSocket()) { - Logger::log("Sucessfully Closed Socket.\n"); - } - - sInstance->mConnectCount = 0; - - sInstance->mIsConnectionActive = sInstance->mSocket->init(sInstance->mServerIP.cstr(), sInstance->mServerPort).isSuccess(); - - if(sInstance->mSocket->getLogState() == SOCKET_LOG_CONNECTED) { - - Logger::log("Reconnect Sucessful!\n"); - - } else { - Logger::log("Reconnect Unsuccessful.\n"); - } -} - /** * @brief starts a connection using client's TCP socket class, pulling up the software keyboard for user inputted IP if save file does not have one saved. * @@ -1393,37 +1350,3 @@ Shine* Client::findStageShine(int shineID) { } return nullptr; } - -void Client::showConnectError(const char16_t* msg) { - if (!sInstance) - return; - - sInstance->mConnectionWait->setTxtMessageConfirm(msg); - - al::hidePane(sInstance->mConnectionWait, "Page01"); // hide A button prompt - - if (!sInstance->mConnectionWait->mIsAlive) { - sInstance->mConnectionWait->appear(); - - sInstance->mConnectionWait->playLoop(); - } - - al::startAction(sInstance->mConnectionWait, "Confirm", "State"); -} - -void Client::showConnect() { - if (!sInstance) - return; - - sInstance->mConnectionWait->appear(); - - sInstance->mConnectionWait->playLoop(); - -} - -void Client::hideConnect() { - if (!sInstance) - return; - - sInstance->mConnectionWait->tryEnd(); -} diff --git a/source/states/StageSceneStateServerConfig.cpp b/source/states/StageSceneStateServerConfig.cpp index e8d0e2e..34c478a 100644 --- a/source/states/StageSceneStateServerConfig.cpp +++ b/source/states/StageSceneStateServerConfig.cpp @@ -41,14 +41,13 @@ StageSceneStateServerConfig::StageSceneStateServerConfig(const char *name, al::S mMainOptionsList->unkInt1 = 1; - mMainOptionsList->initDataNoResetSelected(5); + mMainOptionsList->initDataNoResetSelected(4); - sead::SafeArray, 5>* mainMenuOptions = - new sead::SafeArray, 5>(); + sead::SafeArray, 4>* mainMenuOptions = + new sead::SafeArray, 4>(); mainMenuOptions->mBuffer[ServerConfigOption::GAMEMODECONFIG].copy(u"Gamemode Config"); mainMenuOptions->mBuffer[ServerConfigOption::GAMEMODESWITCH].copy(u"Change Gamemode"); - mainMenuOptions->mBuffer[ServerConfigOption::RECONNECT].copy(u"Reconnect to Server"); mainMenuOptions->mBuffer[ServerConfigOption::SETIP].copy(u"Change Server IP"); mainMenuOptions->mBuffer[ServerConfigOption::SETPORT].copy(u"Change Server Port"); @@ -176,10 +175,6 @@ void StageSceneStateServerConfig::exeMainMenu() { al::setNerve(this, &nrvStageSceneStateServerConfigGamemodeSelect); break; } - case ServerConfigOption::RECONNECT: { - al::setNerve(this, &nrvStageSceneStateServerConfigRestartServer); - break; - } case ServerConfigOption::SETIP: { al::setNerve(this, &nrvStageSceneStateServerConfigOpenKeyboardIP); break; @@ -233,27 +228,6 @@ void StageSceneStateServerConfig::exeOpenKeyboardPort() { } } -void StageSceneStateServerConfig::exeRestartServer() { - if (al::isFirstStep(this)) { - mCurrentList->deactivate(); - - Client::showConnect(); - - Client::restartConnection(); - } - - if (Client::isSocketActive()) { - - Client::hideConnect(); - - al::startHitReaction(mCurrentMenu, "リセット", 0); - - al::setNerve(this, &nrvStageSceneStateServerConfigMainMenu); - } else { - al::setNerve(this, &nrvStageSceneStateServerConfigConnectError); - } -} - void StageSceneStateServerConfig::exeGamemodeConfig() { if (al::isFirstStep(this)) { mGamemodeConfigMenu = &mGamemodeConfigMenus[GameModeManager::instance()->getGameMode()]; @@ -290,18 +264,6 @@ void StageSceneStateServerConfig::exeGamemodeSelect() { } } -void StageSceneStateServerConfig::exeConnectError() { - if (al::isFirstStep(this)) { - Client::showConnectError(u"Failed to Reconnect!"); - } - - if (al::isGreaterEqualStep(this, 60)) { // close after 1 second - Client::hideConnect(); - al::startHitReaction(mCurrentMenu, "リセット", 0); - al::setNerve(this, &nrvStageSceneStateServerConfigMainMenu); - } -} - void StageSceneStateServerConfig::exeSaveData() { if (al::isFirstStep(this)) { @@ -373,9 +335,7 @@ namespace { NERVE_IMPL(StageSceneStateServerConfig, MainMenu) NERVE_IMPL(StageSceneStateServerConfig, OpenKeyboardIP) NERVE_IMPL(StageSceneStateServerConfig, OpenKeyboardPort) -NERVE_IMPL(StageSceneStateServerConfig, RestartServer) NERVE_IMPL(StageSceneStateServerConfig, GamemodeConfig) NERVE_IMPL(StageSceneStateServerConfig, GamemodeSelect) NERVE_IMPL(StageSceneStateServerConfig, SaveData) -NERVE_IMPL(StageSceneStateServerConfig, ConnectError) -} \ No newline at end of file +} From c736878df1515eabc2ac0844dd0b3f04e8283107 Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Sat, 8 Jul 2023 04:31:56 +0200 Subject: [PATCH 10/11] `Toggle H&S Gravity` with real toggle functionality --- include/server/hns/HideAndSeekConfigMenu.hpp | 8 +++-- source/server/hns/HideAndSeekConfigMenu.cpp | 35 ++++++++++--------- source/states/StageSceneStateServerConfig.cpp | 10 +++--- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/include/server/hns/HideAndSeekConfigMenu.hpp b/include/server/hns/HideAndSeekConfigMenu.hpp index f2039c9..3564912 100644 --- a/include/server/hns/HideAndSeekConfigMenu.hpp +++ b/include/server/hns/HideAndSeekConfigMenu.hpp @@ -9,11 +9,13 @@ public: HideAndSeekConfigMenu(); void initMenu(const al::LayoutInitInfo &initInfo) override; - const sead::WFixedSafeString<0x200> *getStringData() override; + const sead::WFixedSafeString<0x200>* getStringData() override; bool updateMenu(int selectIndex) override; const int getMenuSize() override { return mItemCount; } private: - static constexpr int mItemCount = 2; -}; \ No newline at end of file + static constexpr int mItemCount = 1; + sead::SafeArray, mItemCount>* gravityOn = nullptr; + sead::SafeArray, mItemCount>* gravityOff = nullptr; +}; diff --git a/source/server/hns/HideAndSeekConfigMenu.cpp b/source/server/hns/HideAndSeekConfigMenu.cpp index 79fc7a4..c34e786 100644 --- a/source/server/hns/HideAndSeekConfigMenu.cpp +++ b/source/server/hns/HideAndSeekConfigMenu.cpp @@ -5,20 +5,27 @@ #include "server/hns/HideAndSeekMode.hpp" #include "server/Client.hpp" -HideAndSeekConfigMenu::HideAndSeekConfigMenu() : GameModeConfigMenu() {} +HideAndSeekConfigMenu::HideAndSeekConfigMenu() : GameModeConfigMenu() { + gravityOn = new sead::SafeArray, mItemCount>(); + gravityOn->mBuffer[0].copy(u"Toggle H&S Gravity (ON)"); + + gravityOff = new sead::SafeArray, mItemCount>(); + gravityOff->mBuffer[0].copy(u"Toggle H&S Gravity (OFF)"); +} void HideAndSeekConfigMenu::initMenu(const al::LayoutInitInfo &initInfo) { } -const sead::WFixedSafeString<0x200> *HideAndSeekConfigMenu::getStringData() { - sead::SafeArray, mItemCount>* gamemodeConfigOptions = - new sead::SafeArray, mItemCount>(); - - gamemodeConfigOptions->mBuffer[0].copy(u"Toggle H&S Gravity On"); - gamemodeConfigOptions->mBuffer[1].copy(u"Toggle H&S Gravity Off"); - - return gamemodeConfigOptions->mBuffer; +const sead::WFixedSafeString<0x200>* HideAndSeekConfigMenu::getStringData() { + HideAndSeekInfo *curMode = GameModeManager::instance()->getInfo(); + return ( + GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK) + && curMode != nullptr + && curMode->mIsUseGravity + ? gravityOn->mBuffer + : gravityOff->mBuffer + ); } bool HideAndSeekConfigMenu::updateMenu(int selectIndex) { @@ -35,13 +42,7 @@ bool HideAndSeekConfigMenu::updateMenu(int selectIndex) { switch (selectIndex) { case 0: { if (GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)) { - curMode->mIsUseGravity = true; - } - return true; - } - case 1: { - if (GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)) { - curMode->mIsUseGravity = false; + curMode->mIsUseGravity = !curMode->mIsUseGravity; } return true; } @@ -50,4 +51,4 @@ bool HideAndSeekConfigMenu::updateMenu(int selectIndex) { return false; } -} \ No newline at end of file +} diff --git a/source/states/StageSceneStateServerConfig.cpp b/source/states/StageSceneStateServerConfig.cpp index 34c478a..4ec5bfc 100644 --- a/source/states/StageSceneStateServerConfig.cpp +++ b/source/states/StageSceneStateServerConfig.cpp @@ -100,11 +100,6 @@ StageSceneStateServerConfig::StageSceneStateServerConfig(const char *name, al::S entry.mList = new CommonVerticalList(entry.mLayout, initInfo, true); al::setPaneString(entry.mLayout, "TxtOption", u"Gamemode Configuration", 0); - - entry.mList->initDataNoResetSelected(entry.mMenu->getMenuSize()); - - - entry.mList->addStringData(entry.mMenu->getStringData(), "TxtContent"); } @@ -231,8 +226,13 @@ void StageSceneStateServerConfig::exeOpenKeyboardPort() { void StageSceneStateServerConfig::exeGamemodeConfig() { if (al::isFirstStep(this)) { mGamemodeConfigMenu = &mGamemodeConfigMenus[GameModeManager::instance()->getGameMode()]; + + mGamemodeConfigMenu->mList->initDataNoResetSelected(mGamemodeConfigMenu->mMenu->getMenuSize()); + mGamemodeConfigMenu->mList->addStringData(mGamemodeConfigMenu->mMenu->getStringData(), "TxtContent"); + mCurrentList = mGamemodeConfigMenu->mList; mCurrentMenu = mGamemodeConfigMenu->mLayout; + subMenuStart(); } From 45cd4442c87f12898829e8717a5d234219345a82 Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Sat, 8 Jul 2023 20:45:53 +0200 Subject: [PATCH 11/11] recycle the reconnect error to warn about the default Ryujinx profile ID --- include/server/Client.hpp | 6 +++- source/server/Client.cpp | 32 ++++++++++++++++++- source/states/StageSceneStateServerConfig.cpp | 9 ++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/include/server/Client.hpp b/include/server/Client.hpp index fb63593..7d3d898 100644 --- a/include/server/Client.hpp +++ b/include/server/Client.hpp @@ -16,6 +16,7 @@ #include "al/LiveActor/LiveActor.h" #include "al/layout/LayoutInitInfo.h" #include "al/layout/SimpleLayoutAppearWaitEnd.h" +#include "al/layout/WindowConfirmWait.h" #include "al/util.hpp" #include "al/layout/LayoutActor.h" #include "al/gamepad/util.h" @@ -173,6 +174,9 @@ class Client { static bool openKeyboardIP(); static bool openKeyboardPort(); + static void showUIMessage(const char16_t* msg); + static void hideUIMessage(); + void resetCollectedShines(); void removeShine(int shineId); @@ -232,7 +236,7 @@ class Client { bool mIsFirstConnect = true; // --- Game Layouts --- - + al::WindowConfirmWait* mUIMessage; al::SimpleLayoutAppearWaitEnd *mConnectStatus; // --- Game Info --- diff --git a/source/server/Client.cpp b/source/server/Client.cpp index a53fcda..207adcf 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -72,10 +72,13 @@ Client::Client() { void Client::init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor holder) { mConnectStatus = new (mHeap) al::SimpleLayoutAppearWaitEnd("", "SaveMessage", initInfo, 0, false); - al::setPaneString(mConnectStatus, "TxtSave", u"Connecting to Server.", 0); al::setPaneString(mConnectStatus, "TxtSaveSh", u"Connecting to Server.", 0); + mUIMessage = new (mHeap) al::WindowConfirmWait("ServerWaitConnect", "WindowConfirmWait", initInfo); + mUIMessage->setTxtMessage(u"a"); + mUIMessage->setTxtMessageConfirm(u"b"); + mHolder = holder; startThread(); @@ -250,6 +253,33 @@ bool Client::openKeyboardPort() { return isFirstConnect; } + +void Client::showUIMessage(const char16_t* msg) { + if (!sInstance) { + return; + } + + sInstance->mUIMessage->setTxtMessageConfirm(msg); + + al::hidePane(sInstance->mUIMessage, "Page01"); // hide A button prompt + + if (!sInstance->mUIMessage->mIsAlive) { + sInstance->mUIMessage->appear(); + + sInstance->mUIMessage->playLoop(); + } + + al::startAction(sInstance->mUIMessage, "Confirm", "State"); +} + +void Client::hideUIMessage() { + if (!sInstance) { + return; + } + + sInstance->mUIMessage->tryEnd(); +} + /** * @brief main thread function for read thread, responsible for processing packets from server * diff --git a/source/states/StageSceneStateServerConfig.cpp b/source/states/StageSceneStateServerConfig.cpp index 4ec5bfc..3d6a096 100644 --- a/source/states/StageSceneStateServerConfig.cpp +++ b/source/states/StageSceneStateServerConfig.cpp @@ -109,6 +109,15 @@ StageSceneStateServerConfig::StageSceneStateServerConfig(const char *name, al::S void StageSceneStateServerConfig::init() { initNerve(&nrvStageSceneStateServerConfigMainMenu, 0); + + #ifdef EMU + char ryujinx[0x10] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + nn::account::Uid user; + nn::account::GetLastOpenedUser(&user); + if (memcmp(user.data, ryujinx, 0x10) == 0) { + Client::showUIMessage(u"Error: Ryujinx default profile detected.\nYou have to create a new user profile!"); + } + #endif } void StageSceneStateServerConfig::appear(void) {