From 88de1dcecf9c89674e7002d0b20ac375d2510775 Mon Sep 17 00:00:00 2001 From: CraftyBoss Date: Fri, 8 Jul 2022 01:02:28 -0700 Subject: [PATCH] shift to sead singleton for Client, new custom heap for Client usage --- include/actors/PuppetActor.h | 10 ++++-- include/puppets/PuppetHolder.hpp | 4 ++- include/server/Client.hpp | 15 ++++---- source/layouts/NameTag.cpp | 2 +- source/main.cpp | 14 ++++---- source/puppets/PuppetActor.cpp | 3 +- source/puppets/PuppetHolder.cpp | 41 ++++++++++++++++++++- source/puppets/PuppetMain.cpp | 2 +- source/server/Client.cpp | 62 ++++++++++++++++---------------- 9 files changed, 101 insertions(+), 52 deletions(-) diff --git a/include/actors/PuppetActor.h b/include/actors/PuppetActor.h index c32f93a..3f88254 100644 --- a/include/actors/PuppetActor.h +++ b/include/actors/PuppetActor.h @@ -35,7 +35,13 @@ class PuppetActor : public al::LiveActor { virtual void makeActorDead(void) override; virtual void attackSensor(al::HitSensor *, al::HitSensor *) override; - virtual bool receiveMsg(const al::SensorMsg *, al::HitSensor *, al::HitSensor *) override; + virtual bool receiveMsg(const al::SensorMsg*, al::HitSensor*, al::HitSensor*) override; + + virtual const char* getName() const override { + if (mInfo) + return mInfo->puppetName; + return mActorName; + } void initOnline(PuppetInfo *pupInfo); @@ -50,8 +56,6 @@ class PuppetActor : public al::LiveActor { PuppetInfo* getInfo() { return mInfo; } - const char *getPuppetName() { return mInfo->puppetName; } - bool addCapture(PuppetHackActor *capture, const char *hackType); al::LiveActor* getCurrentModel(); diff --git a/include/puppets/PuppetHolder.hpp b/include/puppets/PuppetHolder.hpp index 0b4efd6..d01f5f4 100644 --- a/include/puppets/PuppetHolder.hpp +++ b/include/puppets/PuppetHolder.hpp @@ -28,8 +28,10 @@ class PuppetHolder { void clearPuppets() { mPuppetArr.clear(); } + bool resizeHolder(int size); + private: - sead::PtrArray mPuppetArr; + sead::PtrArray mPuppetArr = sead::PtrArray(); PuppetActor *mDebugPuppet; diff --git a/include/server/Client.hpp b/include/server/Client.hpp index 6fc062e..651dd72 100644 --- a/include/server/Client.hpp +++ b/include/server/Client.hpp @@ -32,6 +32,7 @@ #include "game/GameData/GameDataHolderWriter.h" #include "game/GameData/GameDataFunction.h" +#include "heap/seadHeap.h" #include "layouts/HideAndSeekIcon.h" #include "rs/util.hpp" @@ -76,10 +77,10 @@ struct UIDIndexNode { class HideAndSeekIcon; class Client { - public: - static Client *sInstance; + SEAD_SINGLETON_DISPOSER(Client) - Client(int bufferSize); + public: + Client(); void init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor holder); @@ -145,7 +146,7 @@ class Client { static GameModeConfigMenu* tryCreateModeMenu(); - static int getMaxPlayerCount() { return sInstance ? sInstance->maxPuppets : 10;} + static int getMaxPlayerCount() { return sInstance ? sInstance->maxPuppets + 1 : 10;} static void toggleCurrentMode(); @@ -204,8 +205,6 @@ class Client { // public for debug purposes SocketClient *mSocket; - int maxPuppets; - private: void updatePlayerInfo(PlayerInf *packet); void updateHackCapInfo(HackCapInf *packet); @@ -287,6 +286,8 @@ class Client { u8 mScenario = 0; + sead::Heap *mHeap = nullptr; // Heap that Client::sInstance was created in + // --- Mode Info --- GameModeBase* mCurMode = nullptr; @@ -299,6 +300,8 @@ class Client { // --- Puppet Info --- + int maxPuppets = 9; // default max player count is 10, so default max puppets will be 9 + PuppetInfo *mPuppetInfoArr[MAXPUPINDEX]; PuppetHolder *mPuppetHolder = nullptr; diff --git a/source/layouts/NameTag.cpp b/source/layouts/NameTag.cpp index 5d42f81..44bbe4b 100644 --- a/source/layouts/NameTag.cpp +++ b/source/layouts/NameTag.cpp @@ -37,7 +37,7 @@ void NameTag::appear() { return; } - setText(mPuppet->getPuppetName()); + setText(mPuppet->getName()); al::startAction(this, "Appear", 0); LayoutActor::appear(); diff --git a/source/main.cpp b/source/main.cpp index 92917d3..871878d 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -88,9 +88,9 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead: gTextWriter->setCursorFromTopLeft(sead::Vector2f(10.f, (dispHeight / 3) + 30.f)); gTextWriter->setScaleFromFontHeight(20.f); - gTextWriter->printf("Client Socket Connection Status: %s\n", Client::sInstance->mSocket->getStateChar()); - gTextWriter->printf("nn::socket::GetLastErrno: 0x%x\n", Client::sInstance->mSocket->socket_errno); - gTextWriter->printf("Packet Queue Length: %d\n", Client::sInstance->mSocket->mPacketQueue.size()); + gTextWriter->printf("Client Socket Connection Status: %s\n", Client::instance()->mSocket->getStateChar()); + gTextWriter->printf("nn::socket::GetLastErrno: 0x%x\n", Client::instance()->mSocket->socket_errno); + gTextWriter->printf("Packet Queue Length: %d\n", Client::instance()->mSocket->mPacketQueue.size()); gTextWriter->printf("Total Connected Players: %d\n", Client::getConnectCount() + 1); al::Scene *curScene = curSequence->curScene; @@ -283,7 +283,7 @@ ulong constructHook() { // hook for constructing anything we need to globally b : [result] "=r"( initInfo)); // Save our scenes init info to a gloabl ptr so we can access it later - Client::sInstance = new Client(playBufSize); + Client::createInstance(al::getCurrentHeap()); return 0x20; } @@ -294,7 +294,7 @@ bool threadInit(HakoniwaSequence *mainSeq) { // hook for initializing client cl al::initLayoutInitInfo(&lytInfo, mainSeq->mLytKit, 0, mainSeq->mAudioDirector, initInfo->mSystemInfo->mLayoutSys, initInfo->mSystemInfo->mMessageSys, initInfo->mSystemInfo->mGamePadSys); - Client::sInstance->init(lytInfo, mainSeq->mGameDataHolder); + Client::instance()->init(lytInfo, mainSeq->mGameDataHolder); return GameDataFunction::isPlayDemoOpening(mainSeq->mGameDataHolder); } @@ -344,9 +344,9 @@ bool hakoniwaSequenceHook(HakoniwaSequence* sequence) { if (al::isPadTriggerRight(-1)) debugPuppetIndex++; if(debugPuppetIndex < 0) { - debugPuppetIndex = playBufSize - 2; + debugPuppetIndex = Client::getMaxPlayerCount() - 2; } - if (debugPuppetIndex >= playBufSize - 1) + if (debugPuppetIndex >= Client::getMaxPlayerCount() - 1) debugPuppetIndex = 0; } diff --git a/source/puppets/PuppetActor.cpp b/source/puppets/PuppetActor.cpp index cf1be28..1a5fdb2 100644 --- a/source/puppets/PuppetActor.cpp +++ b/source/puppets/PuppetActor.cpp @@ -210,7 +210,7 @@ void PuppetActor::control() { } void PuppetActor::makeActorAlive() { - + al::LiveActor *curModel = getCurrentModel(); if (al::isDead(curModel)) { @@ -227,6 +227,7 @@ void PuppetActor::makeActorAlive() { } al::LiveActor::makeActorAlive(); + } } diff --git a/source/puppets/PuppetHolder.cpp b/source/puppets/PuppetHolder.cpp index 5fe34a9..d650478 100644 --- a/source/puppets/PuppetHolder.cpp +++ b/source/puppets/PuppetHolder.cpp @@ -1,13 +1,52 @@ #include "puppets/PuppetHolder.hpp" +#include +#include "actors/PuppetActor.h" #include "al/util.hpp" +#include "container/seadPtrArray.h" +#include "heap/seadHeap.h" +#include "heap/seadHeapMgr.h" #include "logger.hpp" PuppetHolder::PuppetHolder(int size) { - mPuppetArr = sead::PtrArray(); if(!mPuppetArr.tryAllocBuffer(size, nullptr)) { Logger::log("Buffer Alloc Failed on Puppet Holder!\n"); } } +/** + * @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 + * @return returns true if resizing was sucessful + */ +bool PuppetHolder::resizeHolder(int size) { + + if (mPuppetArr.capacity() == size) + return true; // no need to resize if we're already at the same capacity + + sead::Heap *seqHeap = sead::HeapMgr::instance()->findHeapByName("SequenceHeap", 0); + + if (!mPuppetArr.isBufferReady()) + return mPuppetArr.tryAllocBuffer(size, seqHeap); + + sead::PtrArray newPuppets = sead::PtrArray(); + + if (newPuppets.tryAllocBuffer(size, seqHeap)) { + + int curPupCount = mPuppetArr.size(); + + for (int i = 0; i < curPupCount > size ? size : curPupCount; i++) { + newPuppets.pushBack(mPuppetArr[i]); + } + + mPuppetArr.freeBuffer(); + + mPuppetArr = newPuppets; + + return true; + } else { + return false; + } +} bool PuppetHolder::tryRegisterPuppet(PuppetActor *puppet) { if(!mPuppetArr.isFull()) { diff --git a/source/puppets/PuppetMain.cpp b/source/puppets/PuppetMain.cpp index 2f60af4..c485ec2 100644 --- a/source/puppets/PuppetMain.cpp +++ b/source/puppets/PuppetMain.cpp @@ -60,7 +60,7 @@ void initPuppetActors(al::Scene *scene, al::ActorInitInfo const &rootInfo, char al::PlacementInfo playerPlacement = al::PlacementInfo(); al::getPlacementInfoByIndex(&playerPlacement, rootPlacement, 0); - for (size_t i = 0; i < Client::sInstance->maxPuppets; i++) + for (size_t i = 0; i < Client::getMaxPlayerCount(); i++) { createPuppetActorFromFactory(rootInfo, playerPlacement, false); } diff --git a/source/server/Client.cpp b/source/server/Client.cpp index 581b657..7d2ce93 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -12,6 +12,9 @@ #include "game/Player/PlayerActorHakoniwa.h" #include "game/SaveData/SaveDataAccessFunction.h" #include "game/StageScene/StageScene.h" +#include "heap/seadDisposer.h" +#include "heap/seadHeap.h" +#include "heap/seadFrameHeap.h" #include "heap/seadHeapMgr.h" #include "helpers.hpp" #include "layouts/HideAndSeekIcon.h" @@ -35,7 +38,7 @@ #include "server/HideAndSeekConfigMenu.hpp" #include "server/HideAndSeekMode.hpp" -Client* Client::sInstance; +SEAD_SINGLETON_DISPOSER_IMPL(Client) typedef void (Client::*ClientThreadFunc)(void); @@ -44,21 +47,21 @@ typedef void (Client::*ClientThreadFunc)(void); * * @param bufferSize defines the maximum amount of puppets the client can handle */ -Client::Client(int bufferSize) { +Client::Client() { + + mHeap = sead::FrameHeap::create(0x100000, "ClientHeap", sead::HeapMgr::instance()->getCurrentHeap(), 8, sead::Heap::cHeapDirection_Forward, false); + + sead::ScopedCurrentHeapSetter heapSetter(mHeap); // every new call after this will use ClientHeap instead of SequenceHeap + this->mReadThread = new al::AsyncFunctorThread("ClientReadThread", al::FunctorV0M(this, &Client::readFunc), 0, 0x10000, {0}); - // this->recvThread = new al::AsyncFunctorThread("ClientRecvThread", - // al::FunctorV0M(this, &Client::recvFunc), 0, 0x10000, - // {0}); mKeyboard = new Keyboard(nn::swkbd::GetRequiredStringBufferSize()); mSocket = new SocketClient("SocketClient"); - maxPuppets = bufferSize - 1; - mPuppetHolder = new PuppetHolder(maxPuppets); - for (size_t i = 0; i < bufferSize + 1; i++) + for (size_t i = 0; i < maxPuppets; i++) { mPuppetInfoArr[i] = new PuppetInfo(); @@ -83,6 +86,7 @@ Client::Client(int bufferSize) { nn::account::Nickname playerName; nn::account::GetNickname(&playerName, mUserID); + Logger::setLogName(playerName.name); // set Debug logger name to player name mUsername = playerName.name; @@ -90,13 +94,8 @@ Client::Client(int bufferSize) { Logger::log("%s Build Number: %s\n", playerName.name, TOSTRING(BUILDVERSTR)); - Logger::setLogName(playerName.name); // set Debug logger name to player name + mServerMode = GameMode::HIDEANDSEEK; // temp for testing - mServerMode = GameMode::HIDEANDSEEK; // temp for testing - - if(!sInstance) { - sInstance = this; - } } /** @@ -106,7 +105,7 @@ Client::Client(int bufferSize) { */ void Client::init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor holder) { - mConnectionWait = new al::WindowConfirmWait("ServerWaitConnect", "WindowConfirmWait", initInfo); + mConnectionWait = new (mHeap) al::WindowConfirmWait("ServerWaitConnect", "WindowConfirmWait", initInfo); mConnectionWait->setTxtMessage(u"Connecting to Server."); @@ -115,6 +114,7 @@ void Client::init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor hol mHolder = holder; StartThreads(); + } /** @@ -352,7 +352,7 @@ void Client::readFunc() { waitForGameInit = false; } - // we can use the start of readFunc to display an al::WindowConfirmWait while the server + // we can use the start of readFunc to display an al::WindowConfirmWait while the client // connects mConnectionWait->appear(); @@ -1094,7 +1094,7 @@ void Client::setStageInfo(GameDataHolderAccessor holder) { sInstance->mStageName = GameDataFunction::getCurrentStageName(holder); sInstance->mScenario = holder.mData->mGameDataFile->getScenarioNo(); //holder.mData->mGameDataFile->getMainScenarioNoCurrent(); - Client::sInstance->mPuppetHolder->setStageInfo(sInstance->mStageName.cstr(), sInstance->mScenario); + sInstance->mPuppetHolder->setStageInfo(sInstance->mStageName.cstr(), sInstance->mScenario); } } @@ -1106,8 +1106,8 @@ void Client::setStageInfo(GameDataHolderAccessor holder) { * @return false */ bool Client::tryAddPuppet(PuppetActor *puppet) { - if(Client::sInstance) { - return Client::sInstance->mPuppetHolder->tryRegisterPuppet(puppet); + if(sInstance) { + return sInstance->mPuppetHolder->tryRegisterPuppet(puppet); }else { return false; } @@ -1121,8 +1121,8 @@ bool Client::tryAddPuppet(PuppetActor *puppet) { * @return false */ bool Client::tryAddDebugPuppet(PuppetActor *puppet) { - if(Client::sInstance) { - return Client::sInstance->mPuppetHolder->tryRegisterDebugPuppet(puppet); + if(sInstance) { + return sInstance->mPuppetHolder->tryRegisterDebugPuppet(puppet); }else { return false; } @@ -1135,8 +1135,8 @@ bool Client::tryAddDebugPuppet(PuppetActor *puppet) { * @return PuppetActor* */ PuppetActor *Client::getPuppet(int idx) { - if(Client::sInstance) { - return Client::sInstance->mPuppetHolder->getPuppetActor(idx); + if(sInstance) { + return sInstance->mPuppetHolder->getPuppetActor(idx); }else { return nullptr; } @@ -1148,8 +1148,8 @@ PuppetActor *Client::getPuppet(int idx) { * @return PuppetInfo* */ PuppetInfo *Client::getLatestInfo() { - if(Client::sInstance) { - return Client::getPuppetInfo(Client::sInstance->mPuppetHolder->getSize() - 1); + if(sInstance) { + return Client::getPuppetInfo(sInstance->mPuppetHolder->getSize() - 1); }else { return nullptr; } @@ -1162,9 +1162,9 @@ PuppetInfo *Client::getLatestInfo() { * @return PuppetInfo* */ PuppetInfo *Client::getPuppetInfo(int idx) { - if(Client::sInstance) { + if(sInstance) { // unsafe get - PuppetInfo *curInfo = Client::sInstance->mPuppetInfoArr[idx]; + PuppetInfo *curInfo = sInstance->mPuppetInfoArr[idx]; if (!curInfo) { Logger::log("Attempting to Access Puppet Out of Bounds! Value: %d\n", idx); @@ -1317,8 +1317,8 @@ void Client::clearArrays() { * @return PuppetInfo* */ PuppetInfo *Client::getDebugPuppetInfo() { - if(Client::sInstance) { - return &Client::sInstance->mDebugPuppetInfo; + if(sInstance) { + return &sInstance->mDebugPuppetInfo; }else { return nullptr; } @@ -1330,8 +1330,8 @@ PuppetInfo *Client::getDebugPuppetInfo() { * @return PuppetActor* */ PuppetActor *Client::getDebugPuppet() { - if(Client::sInstance) { - return Client::sInstance->mPuppetHolder->getDebugPuppet(); + if(sInstance) { + return sInstance->mPuppetHolder->getDebugPuppet(); }else { return nullptr; }