diff --git a/Makefile b/Makefile index 9c8c846..7b9a40e 100644 --- a/Makefile +++ b/Makefile @@ -4,17 +4,19 @@ .PHONY: all clean starlight send SMOVER ?= 100 -BUILDVER ?= 99.37 -IP ?= 10.0.0.221 +BUILDVER ?= 101 +BUILDVERSTR ?= 1.0.1 +IP ?= 10.0.0.221 # ftp server ip (usually is switch's local IP) DEBUGLOG ?= 0 # defaults to disable debug logger SERVERIP ?= 0.0.0.0 # put debug logger server IP here +ISEMU ?= 0 # set to 1 to compile for emulators PROJNAME ?= StarlightBase all: starlight starlight: - $(MAKE) all -f MakefileNSO SMOVER=$(SMOVER) BUILDVER=$(BUILDVER) DEBUGLOG=$(DEBUGLOG) SERVERIP=${SERVERIP} + $(MAKE) all -f MakefileNSO SMOVER=$(SMOVER) BUILDVERSTR=$(BUILDVERSTR) BUILDVER=$(BUILDVER) DEBUGLOG=$(DEBUGLOG) SERVERIP=${SERVERIP} EMU=${ISEMU} $(MAKE) starlight_patch_$(SMOVER)/*.ips mkdir -p starlight_patch_$(SMOVER)/atmosphere/exefs_patches/$(PROJNAME)/ @@ -29,9 +31,9 @@ starlight_patch_$(SMOVER)/*.ips: patches/*.slpatch patches/configs/$(SMOVER).con @rm -f starlight_patch_$(SMOVER)/*.ips python3 scripts/genPatch.py $(SMOVER) -# builds project with the file structure used in the yuzu emulator -yuzu: - $(MAKE) all -f MakefileNSO SMOVER=$(SMOVER) BUILDVER=$(BUILDVER) +# builds project with the file structure and flags used for emulators +emu: + $(MAKE) all -f MakefileNSO SMOVER=$(SMOVER) BUILDVERSTR=$(BUILDVERSTR) BUILDVER=$(BUILDVER) EMU=1 $(MAKE) starlight_patch_$(SMOVER)/*.ips mkdir -p starlight_patch_$(SMOVER)/yuzu/ diff --git a/MakefileNSO b/MakefileNSO index 43b1f34..a301b90 100644 --- a/MakefileNSO +++ b/MakefileNSO @@ -44,7 +44,7 @@ ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIC -ftls-model=local-exec CFLAGS := -g -Wall -ffunction-sections \ $(ARCH) $(DEFINES) -CFLAGS += $(INCLUDE) -D__SWITCH__ -DSMOVER=$(SMOVER) -O3 -DNNSDK -DSWITCH -DBUILDVER=$(BUILDVER) -DDEBUGLOG=$(DEBUGLOG) -DSERVERIP=$(SERVERIP) +CFLAGS += $(INCLUDE) -D__SWITCH__ -DSMOVER=$(SMOVER) -O3 -DNNSDK -DSWITCH -DBUILDVERSTR=$(BUILDVERSTR) -DBUILDVER=$(BUILDVER) -DDEBUGLOG=$(DEBUGLOG) -DSERVERIP=$(SERVERIP) -DEMU=$(EMU) CXXFLAGS := $(CFLAGS) -fno-rtti -fomit-frame-pointer -fno-exceptions -fno-asynchronous-unwind-tables -fno-unwind-tables -std=gnu++20 diff --git a/include/SocketBase.hpp b/include/SocketBase.hpp index e14bd72..9ffc58a 100644 --- a/include/SocketBase.hpp +++ b/include/SocketBase.hpp @@ -12,6 +12,7 @@ class SocketBase { SocketBase(const char *name); virtual nn::Result init(const char * ip, u16 port) = 0; + virtual bool closeSocket(); const char *getStateChar(); u8 getLogState(); @@ -19,7 +20,6 @@ class SocketBase { void set_sock_flags(int flags); - bool closeSocket(); void setName(const char *name) {strcpy(sockName, name);}; u32 socket_errno; diff --git a/include/al/scene/SceneObjFactory.h b/include/al/scene/SceneObjFactory.h new file mode 100644 index 0000000..eb8a73e --- /dev/null +++ b/include/al/scene/SceneObjFactory.h @@ -0,0 +1,89 @@ +#pragma once + +#include "al/scene/ISceneObj.h" +#include "al/scene/SceneObjHolder.h" +#include "SceneObjs.h" + +al::ISceneObj *sub_4C4300(int objIndex) { + switch (objIndex) + { + case 0: + return new AmiiboNpcDirector(); + case 1: + return new BgmAnimeSyncDirector(); + case 3: + return new CapManHeroDemoDirector(); + case 4: + return new CapMessageDirector(); + case 5: + return new CapMessageMoonNotifier(); + case 7: + return new CoinCollectHolder(); + case 8: + return new CoinCollectWatcher(); + case 9: + return new CollectBgmPlayer(); + case 11: + return new EchoEmitterHolder(); + case 12: + return new ElectricWireCameraTicketHolder(); + case 17: + return new FukankunZoomObjHolder(); + case 21: + return new GrowPlantDirector(); + case 22: + return new GuidePosInfoHolder(); + case 23: + return new HintPhotoLayoutHolder(); + case 26: + return new HtmlViewerRequester(); + case 29: + return new KidsModeLayoutAccessor(); + case 34: + return new LoginLotteryDirector(); + case 36: + return new MoviePlayer(); + case 39: + return new PaintObjHolder(); + case 42: + return new PlayerStartInfoHolder(); + case 44: + return new QuestInfoHolder(64); + case 49: + return new RandomItemSelector(); + case 52: + return nullptr; + case 53: + return new RhyhtmInfoWatcher(""); + case 55: + return new RouteGuideDirector(); + case 56: + return new SceneEventNotifier(); + case 60: + return new al::StageSyncCounter(); + case 62: + return new TalkNpcParamHolder(); + case 63: + return new TalkNpcSceneEventSwitcher(); + case 64: + return new TestStageTimeDirector(); + case 65: + return new TimeBalloonDirector(); + case 70: + return new TsukkunTraceHolder(); + case 71: + return new WipeHolderRequester(); + case 72: + return new YoshiFruitWatcher(); + case 73: + return new HelpAmiiboDirector(); + default: + return nullptr; + } +} + +class SceneObjFactory { +public: + al::SceneObjHolder *createSceneObjHolder(void) { return new al::SceneObjHolder(&sub_4C4300, 0x4A);} +}; + diff --git a/include/al/scene/SceneObjHolder.h b/include/al/scene/SceneObjHolder.h index ddf5afd..951d0d8 100644 --- a/include/al/scene/SceneObjHolder.h +++ b/include/al/scene/SceneObjHolder.h @@ -4,9 +4,11 @@ namespace al { + typedef al::ISceneObj* (*SceneObjCreator)(int); + class SceneObjHolder { public: - SceneObjHolder(al::ISceneObj* (*)(int), int); + SceneObjHolder(SceneObjCreator, int); ISceneObj *tryGetObj(int) const; // unsafe get still void setSceneObj(al::ISceneObj *,int); @@ -15,8 +17,14 @@ namespace al { ISceneObj *getObj(int) const; void create(int); + SceneObjCreator mObjCreator; + al::ISceneObj **mSceneObjs; + int mMaxObjCount; + }; + static_assert(sizeof(SceneObjHolder) == 0x18, "SceneObjHolder Size"); + class IUseSceneObjHolder { public: diff --git a/include/al/scene/SceneObjs.h b/include/al/scene/SceneObjs.h new file mode 100644 index 0000000..5bf9925 --- /dev/null +++ b/include/al/scene/SceneObjs.h @@ -0,0 +1,179 @@ +#pragma once + +#include "al/scene/ISceneObj.h" +#include "al/scene/SceneObjHolder.h" +#include "game/SceneObjs/RouteGuideDirector.h" + +// temp header to cleanup SceneObjFactory + +namespace al { + struct StageSyncCounter : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; + }; +} + +struct AmiiboNpcDirector : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct BgmAnimeSyncDirector : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct CapManHeroDemoDirector : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct CapMessageDirector : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct CapMessageMoonNotifier : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct CoinCollectHolder : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct CoinCollectWatcher : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct CollectBgmPlayer : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct EchoEmitterHolder : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct ElectricWireCameraTicketHolder : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct FukankunZoomObjHolder : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct GrowPlantDirector : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct GuidePosInfoHolder : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct HintPhotoLayoutHolder : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct HtmlViewerRequester : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct KidsModeLayoutAccessor : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct LoginLotteryDirector : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct MoviePlayer : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct PaintObjHolder : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct PlayerStartInfoHolder : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct RandomItemSelector : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct SceneEventNotifier : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct TalkNpcParamHolder : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct TalkNpcSceneEventSwitcher : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct TestStageTimeDirector : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct TimeBalloonDirector : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct TsukkunTraceHolder : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct WipeHolderRequester : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct YoshiFruitWatcher : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct HelpAmiiboDirector : public al::ISceneObj { + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; + +struct QuestInfoHolder : public al::ISceneObj { + QuestInfoHolder(int); + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; +struct RhyhtmInfoWatcher : public al::ISceneObj { + RhyhtmInfoWatcher(const char*); + virtual const char* getSceneObjName() override; + virtual void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + virtual void initSceneObj(void) override; +}; \ No newline at end of file diff --git a/include/game/GameData/GameDataHolderAccessor.h b/include/game/GameData/GameDataHolderAccessor.h index 60d1740..7e409d6 100644 --- a/include/game/GameData/GameDataHolderAccessor.h +++ b/include/game/GameData/GameDataHolderAccessor.h @@ -18,4 +18,5 @@ class GameDataHolderAccessor : public GameDataHolderWriter public: GameDataHolderAccessor(al::IUseSceneObjHolder const *IUseObjHolder) {mData = (GameDataHolder*)al::getSceneObj(IUseObjHolder, 18);} GameDataHolderAccessor(al::SceneObjHolder const *objHolder) {mData = (GameDataHolder*)objHolder->getObj(18); } + GameDataHolderAccessor() {mData = nullptr; } // default ctor }; \ No newline at end of file diff --git a/include/game/SaveData/SaveDataAccessFunction.h b/include/game/SaveData/SaveDataAccessFunction.h new file mode 100644 index 0000000..2ae6b8f --- /dev/null +++ b/include/game/SaveData/SaveDataAccessFunction.h @@ -0,0 +1,19 @@ +#pragma once + +#include "game/GameData/GameDataHolder.h" + +namespace SaveDataAccessFunction { + void startSaveDataInit(GameDataHolder *); + void startSaveDataInitSync(GameDataHolder *); + void startSaveDataLoadFile(GameDataHolder *); + void startSaveDataReadSync(GameDataHolder *); + void startSaveDataReadAll(GameDataHolder *); + void startSaveDataWrite(GameDataHolder *); + void startSaveDataWriteWithWindow(GameDataHolder *); + void startSaveDataCopyWithWindow(GameDataHolder *,int,int); + void startSaveDataDeleteWithWindow(GameDataHolder *,int); + void startSaveDataWriteSync(GameDataHolder *); + bool updateSaveDataAccess(GameDataHolder *,bool); + bool isEnableSave(GameDataHolder const*); + bool isDoneSave(GameDataHolder *); +} \ No newline at end of file diff --git a/include/game/SceneObjs/RouteGuideDirector.h b/include/game/SceneObjs/RouteGuideDirector.h new file mode 100644 index 0000000..e365f1b --- /dev/null +++ b/include/game/SceneObjs/RouteGuideDirector.h @@ -0,0 +1,31 @@ +#pragma once + +#include "al/LiveActor/LiveActor.h" +#include "al/scene/ISceneObj.h" + +class RouteGuideDirector : public al::LiveActor, public al::ISceneObj { +public: + RouteGuideDirector(); + + void initAfterPlacementSceneObj(al::ActorInitInfo const&) override; + + bool isValidate(void) const; + void offGuideSystem(void); + void deactivateGuide(void); + void onGuideSystem(void); + void activateGuide(void); + void offGuideByActor(al::LiveActor *); + void addInvidateList(al::LiveActor *); + void onGuideByActor(al::LiveActor *); + void removeInvidateList(al::LiveActor const*); + void addRouteGuidePointBufferCount(int); + void registerRouteGuidePoint(struct RouteGuidePoint *); + void addRouteGuideArrowBufferCount(int); + void registerRouteGuideArrow(struct RouteGuideArrowBase*); + + void exeOff(void); + void exeOn(void); + + virtual const char* getSceneObjName() override; + virtual void initSceneObj(void) override; +}; \ No newline at end of file diff --git a/include/game/StageScene/StageSceneStateServerConfig.hpp b/include/game/StageScene/StageSceneStateServerConfig.hpp index 0a69ece..f3c3469 100644 --- a/include/game/StageScene/StageSceneStateServerConfig.hpp +++ b/include/game/StageScene/StageSceneStateServerConfig.hpp @@ -44,6 +44,7 @@ class StageSceneStateServerConfig : public al::HostStateBase, public void exeRestartServer(); void exeGamemodeConfig(); void exeGamemodeSelect(); + void exeSaveData(); void endSubMenu(); @@ -82,4 +83,5 @@ namespace { NERVE_HEADER(StageSceneStateServerConfig, RestartServer) NERVE_HEADER(StageSceneStateServerConfig, GamemodeConfig) NERVE_HEADER(StageSceneStateServerConfig, GamemodeSelect) + NERVE_HEADER(StageSceneStateServerConfig, SaveData) } \ No newline at end of file diff --git a/include/nn/account.h b/include/nn/account.h index 1f05d2f..9b0b6c9 100644 --- a/include/nn/account.h +++ b/include/nn/account.h @@ -33,7 +33,11 @@ namespace nn return *this; } - inline void print() { + inline bool isEmpty() const { + return *this == EmptyId; + } + + inline void print() const { Logger::log("Player ID: 0x"); Logger::disableName(); for (size_t i = 0; i < 0x10; i++) { Logger::log("%02X", data[i]); } @@ -41,13 +45,15 @@ namespace nn Logger::enableName(); } - inline void print(const char *prefix) { + inline void print(const char *prefix) const { Logger::log("%s: 0x", prefix); Logger::disableName(); for (size_t i = 0; i < 0x10; i++) { Logger::log("%02X", data[i]); } Logger::log("\n"); Logger::enableName(); } + + static const Uid EmptyId; }; typedef u64 NetworkServiceAccountId; diff --git a/include/nn/system_settings.ini b/include/nn/system_settings.ini deleted file mode 100644 index 600d03c..0000000 --- a/include/nn/system_settings.ini +++ /dev/null @@ -1,53 +0,0 @@ -; Disable uploading error reports to Nintendo -[eupld] -; upload_enabled = u8!0x0 -; Control whether RO should ease its validation of NROs. -; (note: this is normally not necessary, and ips patches can be used.) -[ro] -; ease_nro_restriction = u8!0x1 -; Atmosphere custom settings -[atmosphere] -; Reboot from fatal automatically after some number of milliseconds. -; If field is not present or 0, fatal will wait indefinitely for user input. -; fatal_auto_reboot_interval = u64!0x0 -; Make the power menu's "reboot" button reboot to payload. -; Set to "normal" for normal reboot, "rcm" for rcm reboot. -; power_menu_reboot_function = str!payload -; Controls whether dmnt cheats should be toggled on or off by -; default. 1 = toggled on by default, 0 = toggled off by default. -; dmnt_cheats_enabled_by_default = u8!0x1 -; Controls whether dmnt should always save cheat toggle state -; for restoration on new game launch. 1 = always save toggles, -; 0 = only save toggles if toggle file exists. -; dmnt_always_save_cheat_toggles = u8!0x0 -; Enable writing to BIS partitions for HBL. -; This is probably undesirable for normal usage. -; enable_hbl_bis_write = u8!0x0 -; Enable reading the CAL0 partition for HBL. -; This is probably undesirable for normal usage. -; enable_hbl_cal_read = u8!0x0 -; Controls whether fs.mitm should redirect save files -; to directories on the sd card. -; 0 = Do not redirect, 1 = Redirect. -; NOTE: EXPERIMENTAL -; If you do not know what you are doing, do not touch this yet. -; fsmitm_redirect_saves_to_sd = u8!0x0 -; Controls whether to enable the deprecated hid mitm -; to fix compatibility with old homebrew. -; 0 = Do not enable, 1 = Enable. -; Please note this setting may be removed in a -; future release of Atmosphere. -; enable_deprecated_hid_mitm = u8!0x0 -; Controls whether am sees system settings "DebugModeFlag" as -; enabled or disabled. -; 0 = Disabled (not debug mode), 1 = Enabled (debug mode) -; enable_am_debug_mode = u8!0x0 -[hbloader] -; Controls the size of the homebrew heap when running as applet. -; If set to zero, all available applet memory is used as heap. -; The default is zero. -; applet_heap_size = u64!0x0 -; Controls the amount of memory to reserve when running as applet -; for usage by other applets. This setting has no effect if -; applet_heap_size is non-zero. The default is 0x8600000. -; applet_heap_reservation_size = u64!0x8600000 \ No newline at end of file diff --git a/include/server/Client.hpp b/include/server/Client.hpp index 14a10e2..67b3b0f 100644 --- a/include/server/Client.hpp +++ b/include/server/Client.hpp @@ -24,6 +24,7 @@ #include "container/seadPtrArray.h" #include "game/Actors/Shine.h" +#include "game/GameData/GameDataHolderAccessor.h" #include "game/Player/PlayerActorHakoniwa.h" #include "game/StageScene/StageScene.h" #include "game/Layouts/CoinCounter.h" @@ -65,6 +66,8 @@ #include +#define MAXPUPINDEX 32 + struct UIDIndexNode { nn::account::Uid uid; int puppetIndex; @@ -78,12 +81,12 @@ class Client { Client(int bufferSize); - void init(al::LayoutInitInfo const &initInfo); + void init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor holder); bool StartThreads(); void readFunc(); void recvFunc(); - static void stopConnection(); + static void restartConnection(); bool isDone() { return mReadThread->isDone(); }; static bool isSocketActive() { return sInstance ? sInstance->mSocket->isConnected() : false; }; @@ -215,7 +218,7 @@ class Client { void sendToStage(ChangeStagePacket* packet); void disconnectPlayer(PlayerDC *packet); - int findPuppetID(const nn::account::Uid& id); + PuppetInfo* findPuppetInfo(const nn::account::Uid& id, bool isFindAvailable); bool startConnection(); @@ -225,7 +228,7 @@ class Client { al::AsyncFunctorThread *mReadThread = nullptr; // TODO: use this thread to send any queued packets // al::AsyncFunctorThread *mRecvThread; // TODO: use this thread to recieve packets and update PuppetInfo - sead::SafeArray puppetPlayerID; + sead::SafeArray puppetPlayerID; int mConnectCount = 0; @@ -233,6 +236,8 @@ class Client { sead::FixedSafeString<0x20> mUsername; + bool mIsConnectionActive = false; + // --- 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 @@ -277,6 +282,8 @@ class Client { sead::FixedSafeString<0x40> mStageName; + GameDataHolderAccessor mHolder; + u8 mScenario = 0; // --- Mode Info --- @@ -291,7 +298,7 @@ class Client { // --- Puppet Info --- - PuppetInfo *mPuppetInfoArr[32]; + PuppetInfo *mPuppetInfoArr[MAXPUPINDEX]; PuppetHolder *mPuppetHolder = nullptr; diff --git a/include/server/SocketClient.hpp b/include/server/SocketClient.hpp index 0aa4959..128af87 100644 --- a/include/server/SocketClient.hpp +++ b/include/server/SocketClient.hpp @@ -22,7 +22,8 @@ class SocketClient : public SocketBase { mPacketQueue = sead::PtrArray(); mPacketQueue.tryAllocBuffer(maxBufSize, nullptr); }; - nn::Result init(const char * ip, u16 port) override; + nn::Result init(const char* ip, u16 port) override; + bool closeSocket() override; bool SEND(Packet *packet); bool RECV(); void printPacket(Packet* packet); diff --git a/source/main.cpp b/source/main.cpp index 01054cd..5b7a3ef 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -293,7 +293,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); + Client::sInstance->init(lytInfo, mainSeq->mGameDataHolder); return GameDataFunction::isPlayDemoOpening(mainSeq->mGameDataHolder); } diff --git a/source/server/Client.cpp b/source/server/Client.cpp index a6560d7..82bc48c 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -1,4 +1,5 @@ #include "server/Client.hpp" +#include #include #include "al/actor/ActorSceneInfo.h" #include "al/layout/WindowConfirmWait.h" @@ -8,6 +9,7 @@ #include "game/GameData/GameDataHolderAccessor.h" #include "game/Info/QuestInfo.h" #include "game/Player/PlayerActorHakoniwa.h" +#include "game/SaveData/SaveDataAccessFunction.h" #include "game/StageScene/StageScene.h" #include "heap/seadHeapMgr.h" #include "helpers.hpp" @@ -22,7 +24,9 @@ #include "packets/InitPacket.h" #include "packets/Packet.h" #include "packets/PlayerConnect.h" +#include "packets/PlayerDC.h" #include "packets/TagInf.h" +#include "puppets/PuppetInfo.h" #include "sead/basis/seadRawPrint.h" #include "sead/math/seadQuat.h" #include "server/gamemode/GameModeBase.hpp" @@ -62,7 +66,7 @@ Client::Client(int bufferSize) { strcpy(mDebugPuppetInfo.puppetName, "PuppetDebug"); - puppetPlayerID.fill({0, 0}); + puppetPlayerID.fill({0}); mConnectCount = 0; @@ -83,9 +87,7 @@ Client::Client(int bufferSize) { Logger::log("Player Name: %s\n", playerName.name); - #ifdef BUILDVER - Logger::log("%s Build Number: %s\n", playerName.name, TOSTRING(BUILDVER)); - #endif + Logger::log("%s Build Number: %s\n", playerName.name, TOSTRING(BUILDVERSTR)); Logger::setLogName(playerName.name); // set Debug logger name to player name @@ -101,7 +103,7 @@ Client::Client(int bufferSize) { * * @param initInfo init info used to create layouts used by client */ -void Client::init(al::LayoutInitInfo const &initInfo) { +void Client::init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor holder) { mConnectionWait = new al::WindowConfirmWait("ServerWaitConnect", "WindowConfirmWait", initInfo); @@ -109,9 +111,9 @@ void Client::init(al::LayoutInitInfo const &initInfo) { mConnectionWait->setTxtMessageConfirm(u"Failed to Connect!"); - StartThreads(); + mHolder = holder; - // mConnectionWait->tryEndForce(); + StartThreads(); } /** @@ -168,30 +170,43 @@ bool Client::StartThreads() { * @brief restarts currently active connection to server * */ -void Client::stopConnection() { +void Client::restartConnection() { if (!sInstance) { Logger::log("Static Instance is null!\n"); return; } - sInstance->mSocket->closeSocket(); + Logger::log("Sending Disconnect.\n"); + + PlayerDC playerDC = PlayerDC(); + + playerDC.mUserID = sInstance->mUserID; + + sInstance->mSocket->SEND(&playerDC); + + if (sInstance->mSocket->closeSocket()) { + Logger::log("Sucessfully Closed Socket.\n"); + } sInstance->puppetPlayerID.fill({0,0}); sInstance->mConnectCount = 0; - sInstance->mSocket->init(sInstance->mServerIP.cstr(), sInstance->mServerPort); + sInstance->mIsConnectionActive = sInstance->mSocket->init(sInstance->mServerIP.cstr(), sInstance->mServerPort).isSuccess(); if(sInstance->mSocket->getLogState() == SOCKET_LOG_CONNECTED) { - Logger::log("Connected!\n"); + Logger::log("Reconnect Sucessful!\n"); PlayerConnect initPacket; initPacket.mUserID = sInstance->mUserID; strcpy(initPacket.clientName, sInstance->mUsername.cstr()); initPacket.conType = ConnectionTypes::RECONNECT; sInstance->mSocket->SEND(&initPacket); + + } else { + Logger::log("Reconnect Unsuccessful.\n"); } } /** @@ -201,11 +216,15 @@ void Client::stopConnection() { * @return false if connection was unable to establish */ bool Client::startConnection() { + + bool isNeedSave = false; + if (mServerIP.isEmpty()) { mKeyboard->setHeaderText(u"Save File does not contain an IP!"); mKeyboard->setSubText(u"Please set a Server IP Below."); mServerIP = "0.0.0.0"; Client::openKeyboardIP(); + isNeedSave = true; } if (!mServerPort) { @@ -213,11 +232,19 @@ bool Client::startConnection() { mKeyboard->setSubText(u"Please set a Server Port Below."); mServerPort = 1027; Client::openKeyboardPort(); + isNeedSave = true; } - bool result = mSocket->init(mServerIP.cstr(), mServerPort).isSuccess(); + if (isNeedSave) { + SaveDataAccessFunction::startSaveDataWrite(mHolder.mData); + } + + mIsConnectionActive = mSocket->init(mServerIP.cstr(), mServerPort).isSuccess(); + + if (mIsConnectionActive) { + + Logger::log("Sucessful Connection. Waiting to recieve init packet.\n"); - if (result) { // wait for client init packet while (true) { @@ -234,19 +261,21 @@ bool Client::startConnection() { }else { Logger::log("First Packet was not Init!\n"); - result = false; + mIsConnectionActive = false; } free(curPacket); + } else { + Logger::log("Recieve failed! Stopping Connection.\n"); + mIsConnectionActive = false; } break; } } - - - return result; + + return mIsConnectionActive; } /** @@ -331,6 +360,8 @@ void Client::readFunc() { if (!startConnection()) { + Logger::log("Failed to Connect to Server.\n"); + al::hidePane(mConnectionWait, "Page01"); // hide A button prompt since connection message automatically hides after 0.25 seconds al::startAction(mConnectionWait, "Confirm", "State"); @@ -342,16 +373,6 @@ void Client::readFunc() { return; } - if (isFirstConnect) { - sead::Heap* seqHeap = sead::HeapMgr::instance()->findHeapByName("SequenceHeap", 0); - - if (seqHeap) { - Logger::log("Current Heap Name: %s\n", seqHeap->getName().cstr()); - } - - - } - PlayerConnect initPacket; initPacket.mUserID = mUserID; strcpy(initPacket.clientName, mUsername.cstr()); @@ -370,7 +391,7 @@ void Client::readFunc() { isFirstConnect = false; - while(true) { + while(mIsConnectionActive) { if (mSocket->getLogState() != SOCKET_LOG_CONNECTED) { @@ -383,14 +404,9 @@ void Client::readFunc() { // if we ever disconnect, reset all our values until we reconnect - puppetPlayerID.fill({0,0}); mConnectCount = 0; - mSocket->closeSocket(); - - mSocket->init(mServerIP.cstr(), mServerPort); - - if (mSocket->getLogState() == SOCKET_LOG_CONNECTED) { + if (mSocket->init(mServerIP.cstr(), mServerPort).isSuccess()) { Logger::log("Connected!\n"); @@ -399,12 +415,12 @@ void Client::readFunc() { mConnectionWait->tryEnd(); continue; + } else { + Logger::log("Connection Failed! Retrying in 5 Seconds.\n"); } nn::os::YieldThread(); // if we're currently waiting on the socket to be initialized, wait until it is nn::os::SleepThread(nn::TimeSpan::FromSeconds(5)); - - // TODO: if a reconnect is sucessful, we should let the server know that this client has already connected, and that their player ID is already active } @@ -474,11 +490,13 @@ void Client::readFunc() { } }else { // if false, socket has errored or disconnected, so close the socket and end this thread. - Logger::log("Client Socket Encountered an Error!\n"); + Logger::log("Client Socket Encountered an Error! Errno: 0x%x\n", mSocket->socket_errno); } nn::os::YieldThread(); // allow other threads to run } + + Logger::log("Client Read Thread ending.\n"); } /** * @brief unused thread function for receiving thread @@ -753,61 +771,55 @@ void Client::sendShineCollectPacket(int shineID) { * @param packet */ void Client::updatePlayerInfo(PlayerInf *packet) { - - int puppetIndex = findPuppetID(packet->mUserID); - if(puppetIndex >= 0) { - - PuppetInfo* curInfo = mPuppetInfoArr[puppetIndex]; - - if (!curInfo) { - Logger::log("Attempting to Access Puppet Out of Bounds! Value: %d\n", puppetIndex); - return; - } - - if(!curInfo->isConnected) { - curInfo->isConnected = true; - } - - curInfo->playerPos = packet->playerPos; - - // check if rotation is larger than zero and less than or equal to 1 - if(abs(packet->playerRot.x) > 0.f || abs(packet->playerRot.y) > 0.f || abs(packet->playerRot.z) > 0.f || abs(packet->playerRot.w) > 0.f) { - if(abs(packet->playerRot.x) <= 1.f || abs(packet->playerRot.y) <= 1.f || abs(packet->playerRot.z) <= 1.f || abs(packet->playerRot.w) <= 1.f) { - curInfo->playerRot = packet->playerRot; - } - } - - if (packet->actName != PlayerAnims::Type::Unknown) { - strcpy(curInfo->curAnimStr, PlayerAnims::FindStr(packet->actName)); - } else { - strcpy(curInfo->curAnimStr, "Wait"); - } - - if(packet->subActName != PlayerAnims::Type::Unknown) { - strcpy(curInfo->curSubAnimStr, PlayerAnims::FindStr(packet->subActName)); - } else { - strcpy(curInfo->curSubAnimStr, ""); - } - - curInfo->curAnim = packet->actName; - curInfo->curSubAnim = packet->subActName; - - for (size_t i = 0; i < 6; i++) - { - // weights can only be between 0 and 1 - if(packet->animBlendWeights[i] >= 0.f && packet->animBlendWeights[i] <= 1.f) { - curInfo->blendWeights[i] = packet->animBlendWeights[i]; - } - } - - //TEMP - - if(!curInfo->isCapThrow) { - curInfo->capPos = packet->playerPos; - } + PuppetInfo* curInfo = findPuppetInfo(packet->mUserID, false); + if (!curInfo) { + return; } + + if(!curInfo->isConnected) { + curInfo->isConnected = true; + } + + curInfo->playerPos = packet->playerPos; + + // check if rotation is larger than zero and less than or equal to 1 + if(abs(packet->playerRot.x) > 0.f || abs(packet->playerRot.y) > 0.f || abs(packet->playerRot.z) > 0.f || abs(packet->playerRot.w) > 0.f) { + if(abs(packet->playerRot.x) <= 1.f || abs(packet->playerRot.y) <= 1.f || abs(packet->playerRot.z) <= 1.f || abs(packet->playerRot.w) <= 1.f) { + curInfo->playerRot = packet->playerRot; + } + } + + if (packet->actName != PlayerAnims::Type::Unknown) { + strcpy(curInfo->curAnimStr, PlayerAnims::FindStr(packet->actName)); + } else { + strcpy(curInfo->curAnimStr, "Wait"); + } + + if(packet->subActName != PlayerAnims::Type::Unknown) { + strcpy(curInfo->curSubAnimStr, PlayerAnims::FindStr(packet->subActName)); + } else { + strcpy(curInfo->curSubAnimStr, ""); + } + + curInfo->curAnim = packet->actName; + curInfo->curSubAnim = packet->subActName; + + for (size_t i = 0; i < 6; i++) + { + // weights can only be between 0 and 1 + if(packet->animBlendWeights[i] >= 0.f && packet->animBlendWeights[i] <= 1.f) { + curInfo->blendWeights[i] = packet->animBlendWeights[i]; + } + } + + //TEMP + + if(!curInfo->isCapThrow) { + curInfo->capPos = packet->playerPos; + } + } /** @@ -817,24 +829,15 @@ void Client::updatePlayerInfo(PlayerInf *packet) { */ void Client::updateHackCapInfo(HackCapInf *packet) { - int puppetIndex = findPuppetID(packet->mUserID); + PuppetInfo* curInfo = findPuppetInfo(packet->mUserID, false); - if(puppetIndex >= 0) { + if (curInfo) { + curInfo->capPos = packet->capPos; + curInfo->capRot = packet->capQuat; - PuppetInfo* curInfo = mPuppetInfoArr[puppetIndex]; + curInfo->isCapThrow = packet->isCapVisible; - if (curInfo) { - curInfo->capPos = packet->capPos; - curInfo->capRot = packet->capQuat; - - curInfo->isCapThrow = packet->isCapVisible; - - if (curInfo->capAnim && packet->capAnim) { - strcpy(curInfo->capAnim, packet->capAnim); - } - } else { - Logger::log("Attempting to Access Puppet Out of Bounds! Value: %d\n", puppetIndex); - } + strcpy(curInfo->capAnim, packet->capAnim); } } @@ -843,22 +846,18 @@ void Client::updateHackCapInfo(HackCapInf *packet) { * * @param packet */ -void Client::updateCaptureInfo(CaptureInf *packet) { - int puppetIndex = findPuppetID(packet->mUserID); - if (puppetIndex >= 0) { +void Client::updateCaptureInfo(CaptureInf* packet) { + + PuppetInfo* curInfo = findPuppetInfo(packet->mUserID, false); - PuppetInfo* curInfo = mPuppetInfoArr[puppetIndex]; - - if (!curInfo) { - Logger::log("Attempting to Access Puppet Out of Bounds! Value: %d\n", puppetIndex); - return; - } + if (!curInfo) { + return; + } - curInfo->isCaptured = strlen(packet->hackName) > 0; + curInfo->isCaptured = strlen(packet->hackName) > 0; - if (curInfo->isCaptured) { - strcpy(curInfo->curHack, packet->hackName); - } + if (curInfo->isCaptured) { + strcpy(curInfo->curHack, packet->hackName); } } @@ -868,21 +867,15 @@ void Client::updateCaptureInfo(CaptureInf *packet) { * @param packet */ void Client::updateCostumeInfo(CostumeInf *packet) { - if(packet->bodyModel && packet->capModel) { - int puppetIndex = findPuppetID(packet->mUserID); - if(puppetIndex >= 0) { - PuppetInfo* curInfo = mPuppetInfoArr[puppetIndex]; - if (!curInfo) { - Logger::log("Attempting to Access Puppet Out of Bounds! Value: %d\n", puppetIndex); - return; - } + PuppetInfo* curInfo = findPuppetInfo(packet->mUserID, false); - strcpy(curInfo->costumeBody, packet->bodyModel); - strcpy(curInfo->costumeHead, packet->capModel); - - } + if (!curInfo) { + return; } + + strcpy(curInfo->costumeBody, packet->bodyModel); + strcpy(curInfo->costumeHead, packet->capModel); } /** @@ -902,18 +895,29 @@ void Client::updateShineInfo(ShineCollect* packet) { * * @param packet */ -void Client::updatePlayerConnect(PlayerConnect *packet) { - int puppetIndex = findPuppetID(packet->mUserID); - if(puppetIndex >= 0) { - PuppetInfo* curInfo = mPuppetInfoArr[puppetIndex]; +void Client::updatePlayerConnect(PlayerConnect* packet) { + + PuppetInfo* curInfo = findPuppetInfo(packet->mUserID, true); + + if (!curInfo) { + return; + } + + if (curInfo->isConnected) { + + Logger::log("Info is already being used by another connected player!\n"); + packet->mUserID.print("Connection ID"); + curInfo->playerID.print("Target Info"); + + } else { + + packet->mUserID.print("Player Connected! ID"); - if (!curInfo) { - Logger::log("Attempting to Access Puppet Out of Bounds! Value: %d\n", puppetIndex); - return; - } curInfo->playerID = packet->mUserID; curInfo->isConnected = true; strcpy(curInfo->puppetName, packet->clientName); + + mConnectCount++; } } /** @@ -922,26 +926,22 @@ void Client::updatePlayerConnect(PlayerConnect *packet) { * @param packet */ void Client::updateGameInfo(GameInf *packet) { - int puppetIndex = findPuppetID(packet->mUserID); - if(puppetIndex >= 0) { - PuppetInfo* curInfo = mPuppetInfoArr[puppetIndex]; + PuppetInfo* curInfo = findPuppetInfo(packet->mUserID, false); - if (!curInfo) { - Logger::log("Attempting to Access Puppet Out of Bounds! Value: %d\n", puppetIndex); - return; + if (!curInfo) { + return; + } + + if(curInfo->isConnected) { + + curInfo->scenarioNo = packet->scenarioNo; + + if(strcmp(packet->stageName, "") != 0 && strlen(packet->stageName) > 3) { + strcpy(curInfo->stageName, packet->stageName); } - if(curInfo->isConnected) { - - curInfo->scenarioNo = packet->scenarioNo; - - if(strcmp(packet->stageName, "") != 0 && strlen(packet->stageName) > 3) { - strcpy(curInfo->stageName, packet->stageName); - } - - curInfo->is2D = packet->is2D; - } + curInfo->is2D = packet->is2D; } } @@ -971,20 +971,15 @@ void Client::updateTagInfo(TagInf *packet) { } - int puppetIndex = findPuppetID(packet->mUserID); + PuppetInfo* curInfo = findPuppetInfo(packet->mUserID, false); - if(puppetIndex >= 0) { - PuppetInfo* curInfo = mPuppetInfoArr[puppetIndex]; - - if (!curInfo) { - Logger::log("Attempting to Access Puppet Out of Bounds! Value: %d\n", puppetIndex); - return; - } - - curInfo->isIt = packet->isIt; - curInfo->seconds = packet->seconds; - curInfo->minutes = packet->minutes; + if (!curInfo) { + return; } + + curInfo->isIt = packet->isIt; + curInfo->seconds = packet->seconds; + curInfo->minutes = packet->minutes; } /** @@ -1011,29 +1006,20 @@ void Client::sendToStage(ChangeStagePacket* packet) { * @param packet */ void Client::disconnectPlayer(PlayerDC *packet) { - int puppetIndex = findPuppetID(packet->mUserID); - if(puppetIndex >= 0) { - PuppetInfo* curInfo = mPuppetInfoArr[puppetIndex]; + PuppetInfo* curInfo = findPuppetInfo(packet->mUserID, false); - if (!curInfo) { - Logger::log("Attempting to Access Puppet Out of Bounds! Value: %d\n", puppetIndex); - return; - } - - curInfo->isConnected = false; - - curInfo->scenarioNo = -1; - strcpy(curInfo->stageName, ""); - curInfo->isInSameStage = false; - - mConnectCount--; - - if (mConnectCount < 0) { - Logger::log("Connection Count went Negative!\n"); - mConnectCount = 0; - } + if (!curInfo) { + return; } + + curInfo->isConnected = false; + + curInfo->scenarioNo = -1; + strcpy(curInfo->stageName, ""); + curInfo->isInSameStage = false; + + mConnectCount--; } /** @@ -1064,23 +1050,27 @@ bool Client::isShineCollected(int shineId) { * @param id * @return int */ -int Client::findPuppetID(const nn::account::Uid &id) { - for (size_t i = 0; i < this->puppetPlayerID.size(); i++) - { - if(this->puppetPlayerID[i].uid == id) { - return this->puppetPlayerID[i].puppetIndex; +PuppetInfo* Client::findPuppetInfo(const nn::account::Uid& id, bool isFindAvailable) { + + PuppetInfo *firstAvailable = nullptr; + + for (size_t i = 0; i < getMaxPlayerCount(); i++) { + + PuppetInfo* curInfo = mPuppetInfoArr[i]; + + if (curInfo->playerID == id) { + return curInfo; + } else if (isFindAvailable && !firstAvailable && !curInfo->isConnected) { + firstAvailable = curInfo; } } - if(this->puppetPlayerID.size() > mConnectCount) { - int newIndex = mConnectCount; - this->puppetPlayerID[newIndex].puppetIndex = newIndex; - this->puppetPlayerID[newIndex].uid = id; - mConnectCount++; - return newIndex; + if (!firstAvailable) { + Logger::log("Unable to find Assigned Puppet for Player!\n"); + id.print("User ID"); } - return -1; + return firstAvailable; } /** diff --git a/source/server/SocketClient.cpp b/source/server/SocketClient.cpp index 8dd50d8..9f84467 100644 --- a/source/server/SocketClient.cpp +++ b/source/server/SocketClient.cpp @@ -2,6 +2,7 @@ #include #include +#include "SocketBase.hpp" #include "logger.hpp" #include "nn/result.h" #include "nn/socket.h" @@ -17,8 +18,7 @@ nn::Result SocketClient::init(const char* ip, u16 port) { in_addr hostAddress = { 0 }; sockaddr serverAddress = { 0 }; - if (socket_log_state != SOCKET_LOG_UNINITIALIZED && socket_log_state != SOCKET_LOG_DISCONNECTED) - return -1; + Logger::log("SocketClient::init: %s:%d sock %s\n", ip, port, getStateChar()); nn::nifm::Initialize(); nn::nifm::SubmitNetworkRequest(); @@ -58,6 +58,7 @@ nn::Result SocketClient::init(const char* ip, u16 port) { nn::Result result; if((result = nn::socket::Connect(this->socket_log_socket, &serverAddress, sizeof(serverAddress))).isFailure()) { + Logger::log("Socket Connection Failed!\n"); this->socket_errno = nn::socket::GetLastErrno(); this->socket_log_state = SOCKET_LOG_UNAVAILABLE; return result; @@ -78,7 +79,6 @@ bool SocketClient::SEND(Packet *packet) { int valread = 0; - //Logger::log("Sending Packet Size: %d Sending Type: %s\n", packet->mPacketSize, packetNames[packet->mType]); if ((valread = nn::socket::Send(this->socket_log_socket, buffer, packet->mPacketSize + sizeof(Packet), this->sock_flags) > 0)) { return true; @@ -105,12 +105,15 @@ bool SocketClient::RECV() { // read only the size of a header while(valread < headerSize) { - int result = nn::socket::Recv(this->socket_log_socket, headerBuf + valread, headerSize - valread, this->sock_flags); + int result = nn::socket::Recv(this->socket_log_socket, headerBuf + valread, + headerSize - valread, this->sock_flags); + + this->socket_errno = nn::socket::GetLastErrno(); + if(result > 0) { valread += result; } else { Logger::log("Header Read Failed! Value: %d Total Read: %d\n", result, valread); - this->socket_errno = nn::socket::GetLastErrno(); this->closeSocket(); return false; } @@ -131,14 +134,16 @@ bool SocketClient::RECV() { while (valread < fullSize) { - int result = nn::socket::Recv(this->socket_log_socket, packetBuf + valread, fullSize - valread, this->sock_flags); + 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 { + } else { free(packetBuf); Logger::log("Packet Read Failed! Value: %d\nPacket Size: %d\nPacket Type: %s\n", result, header->mPacketSize, packetNames[header->mType]); - this->socket_errno = nn::socket::GetLastErrno(); this->closeSocket(); return false; } @@ -151,11 +156,7 @@ bool SocketClient::RECV() { } else { free(packetBuf); } - } else { - // Logger::log("Heap Allocation Failed! Returned nullptr\n"); } - } else { - // Logger::log("Recieved Unknown Packet Type! Size: %d\n", header->mPacketSize); } return true; @@ -183,3 +184,9 @@ void SocketClient::printPacket(Packet *packet) { } } +bool SocketClient::closeSocket() { + + Logger::log("Closing Socket.\n"); + + return SocketBase::closeSocket(); +} \ No newline at end of file diff --git a/source/states/StageSceneStateServerConfig.cpp b/source/states/StageSceneStateServerConfig.cpp index 230b55a..6fb959f 100644 --- a/source/states/StageSceneStateServerConfig.cpp +++ b/source/states/StageSceneStateServerConfig.cpp @@ -1,6 +1,7 @@ #include "game/StageScene/StageSceneStateServerConfig.hpp" #include #include +#include "game/SaveData/SaveDataAccessFunction.h" #include "server/Client.hpp" #include "al/util.hpp" #include "al/util/NerveUtil.h" @@ -172,7 +173,7 @@ void StageSceneStateServerConfig::exeOpenKeyboardIP() { Client::openKeyboardIP(); // anything that happens after this will be ran after the keyboard closes al::startHitReaction(mCurrentMenu, "リセット", 0); - al::setNerve(this, &nrvStageSceneStateServerConfigMainMenu); + al::setNerve(this, &nrvStageSceneStateServerConfigSaveData); } } @@ -183,23 +184,22 @@ void StageSceneStateServerConfig::exeOpenKeyboardPort() { Client::getKeyboard()->setHeaderText(u"Set a Server Port Below."); Client::getKeyboard()->setSubText(u""); - Client::openKeyboardIP(); + Client::openKeyboardPort(); // anything that happens after this will be ran after the keyboard closes - al::startHitReaction(mCurrentMenu, "リセット", 0); - al::setNerve(this, &nrvStageSceneStateServerConfigMainMenu); + al::setNerve(this, &nrvStageSceneStateServerConfigSaveData); } } void StageSceneStateServerConfig::exeRestartServer() { if (al::isFirstStep(this)) { mCurrentList->deactivate(); - Client::stopConnection(); + Client::restartConnection(); } - if (Client::isSocketActive()) { + //if (Client::isSocketActive()) { al::startHitReaction(mCurrentMenu, "リセット", 0); al::setNerve(this, &nrvStageSceneStateServerConfigMainMenu); - } + //} } void StageSceneStateServerConfig::exeGamemodeConfig() { @@ -291,6 +291,18 @@ void StageSceneStateServerConfig::subMenuUpdate() { } } +void StageSceneStateServerConfig::exeSaveData() { + + if (al::isFirstStep(this)) { + SaveDataAccessFunction::startSaveDataWrite(mGameDataHolder); + } + + if (SaveDataAccessFunction::updateSaveDataAccess(mGameDataHolder, false)) { + al::startHitReaction(mCurrentMenu, "リセット", 0); + al::setNerve(this, &nrvStageSceneStateServerConfigMainMenu); + } +} + namespace { NERVE_IMPL(StageSceneStateServerConfig, MainMenu) NERVE_IMPL(StageSceneStateServerConfig, OpenKeyboardIP) @@ -298,4 +310,5 @@ NERVE_IMPL(StageSceneStateServerConfig, OpenKeyboardPort) NERVE_IMPL(StageSceneStateServerConfig, RestartServer) NERVE_IMPL(StageSceneStateServerConfig, GamemodeConfig) NERVE_IMPL(StageSceneStateServerConfig, GamemodeSelect) +NERVE_IMPL(StageSceneStateServerConfig, SaveData) } \ No newline at end of file