Merge pull request #13 from VelocityRa/serverconfig-fixes

Server Config fixes
This commit is contained in:
CraftyBoss 2022-06-25 19:55:22 -07:00 committed by GitHub
commit 4b83934a47
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 63 additions and 48 deletions

View file

@ -32,9 +32,9 @@ class SocketBase {
const char *sock_ip; const char *sock_ip;
u16 port; u16 port;
u8 socket_log_state; u8 socket_log_state = SOCKET_LOG_UNINITIALIZED;
s32 socket_log_socket; s32 socket_log_socket;
int sock_flags; int sock_flags;
}; };

View file

@ -2,9 +2,9 @@
* @file server/Client.hpp * @file server/Client.hpp
* @author CraftyBoss (https://github.com/CraftyBoss) * @author CraftyBoss (https://github.com/CraftyBoss)
* @brief main class responsible for handing all client-server related communications, as well as any gamemodes. * @brief main class responsible for handing all client-server related communications, as well as any gamemodes.
* *
* @copyright Copyright (c) 2022 * @copyright Copyright (c) 2022
* *
*/ */
#pragma once #pragma once
@ -92,7 +92,7 @@ class Client {
bool isShineCollected(int shineId); bool isShineCollected(int shineId);
static void initMode(GameModeInitInfo const &initInfo); static void initMode(GameModeInitInfo const &initInfo);
static void sendHackCapInfPacket(const HackCap *hackCap); static void sendHackCapInfPacket(const HackCap *hackCap);
static void sendPlayerInfPacket(const PlayerActorHakoniwa *player); static void sendPlayerInfPacket(const PlayerActorHakoniwa *player);
static void sendGameInfPacket(const PlayerActorHakoniwa *player, GameDataHolderAccessor holder); static void sendGameInfPacket(const PlayerActorHakoniwa *player, GameDataHolderAccessor holder);
@ -191,7 +191,7 @@ class Client {
static void tryRestartCurrentMode(); static void tryRestartCurrentMode();
static bool isModeActive() { return sInstance ? sInstance->mIsModeActive : false; } static bool isModeActive() { return sInstance ? sInstance->mIsModeActive : false; }
static bool isSelectedMode(GameMode mode) { return sInstance ? sInstance->mCurMode->getMode() == mode: false; } static bool isSelectedMode(GameMode mode) { return sInstance ? sInstance->mCurMode->getMode() == mode: false; }
void resetCollectedShines(); void resetCollectedShines();
@ -224,7 +224,7 @@ class Client {
// currently, only readThread is used to recieve and update PuppetInfo, while the main game thread is used to send packets without queueing them up first, which might cause performance issues // currently, only readThread is used to recieve and update PuppetInfo, while the main game thread is used to send packets without queueing them up first, which might cause performance issues
al::AsyncFunctorThread *mReadThread = nullptr; // TODO: use this thread to send any queued packets 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 // al::AsyncFunctorThread *mRecvThread; // TODO: use this thread to recieve packets and update PuppetInfo
sead::SafeArray<UIDIndexNode, 16> puppetPlayerID; sead::SafeArray<UIDIndexNode, 16> puppetPlayerID;
int mConnectCount = 0; int mConnectCount = 0;
@ -233,10 +233,10 @@ class Client {
sead::FixedSafeString<0x20> mUsername; sead::FixedSafeString<0x20> mUsername;
// --- Server Syncing Members --- // --- Server Syncing Members ---
// array of shine IDs for checking if multiple shines have been collected in quick sucession, all moons within the players stage that match the ID will be deleted // array of shine IDs for checking if multiple shines have been collected in quick sucession, all moons within the players stage that match the ID will be deleted
sead::SafeArray<int, 128> curCollectedShines; sead::SafeArray<int, 128> curCollectedShines;
int collectedShineCount = 0; int collectedShineCount = 0;
int lastCollectedShine = -1; int lastCollectedShine = -1;
@ -252,6 +252,7 @@ class Client {
int mServerPort = 0; int mServerPort = 0;
bool waitForGameInit = true;
bool isFirstConnect = true; bool isFirstConnect = true;
// --- Game Layouts --- // --- Game Layouts ---

View file

@ -22,12 +22,16 @@ while True:
print(f'Switch Connected! IP: {client_address[0]} Port: {client_address[1]}') print(f'Switch Connected! IP: {client_address[0]} Port: {client_address[1]}')
while True: while True:
data = connection.recv(1024) data = connection.recv(1024)
if data: if data:
print(data.decode("utf-8"), end='', flush=True) print(data.decode("utf-8"), end='', flush=True)
else: else:
print(f'Connection Terminated.') print(f'Connection Terminated.')
break break
except ConnectionResetError:
print("Connection reset")
finally: finally:
# Clean up the connection # Clean up the connection
connection.close() connection.close()

View file

@ -137,6 +137,7 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead:
gTextWriter->printf("Is in Capture: %s\n", curPupInfo->isCaptured ? "True" : "False"); gTextWriter->printf("Is in Capture: %s\n", curPupInfo->isCaptured ? "True" : "False");
gTextWriter->printf("Puppet Stage: %s\n", curPupInfo->stageName); gTextWriter->printf("Puppet Stage: %s\n", curPupInfo->stageName);
gTextWriter->printf("Puppet Scenario: %u\n", curPupInfo->scenarioNo); gTextWriter->printf("Puppet Scenario: %u\n", curPupInfo->scenarioNo);
gTextWriter->printf("Puppet Costume: H: %s B: %s\n", curPupInfo->costumeHead, curPupInfo->costumeBody);
//gTextWriter->printf("Packet Coords:\nX: %f\nY: %f\nZ: %f\n", curPupInfo->playerPos.x, curPupInfo->playerPos.y, curPupInfo->playerPos.z); //gTextWriter->printf("Packet Coords:\nX: %f\nY: %f\nZ: %f\n", curPupInfo->playerPos.x, curPupInfo->playerPos.y, curPupInfo->playerPos.z);
// if (curModel) { // if (curModel) {
// sead::Vector3f* pupPos = al::getTrans(curModel); // sead::Vector3f* pupPos = al::getTrans(curModel);
@ -165,7 +166,7 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead:
if (debugPuppet && debugInfo) { if (debugPuppet && debugInfo) {
al::LiveActor *curModel = debugPuppet->getCurrentModel(); al::LiveActor *curModel = debugPuppet->getCurrentModel();
gTextWriter->printf("Is Nametag Visible: %s\n", BTOC(debugPuppet->mNameTag->isVisible())); gTextWriter->printf("Is Nametag Visible: %s\n", BTOC(debugPuppet->mNameTag->isVisible()));
gTextWriter->printf("Is Nametag Alive: %s\n", BTOC(debugPuppet->mNameTag->mIsAlive)); gTextWriter->printf("Is Nametag Alive: %s\n", BTOC(debugPuppet->mNameTag->mIsAlive));
gTextWriter->printf("Nametag Normalized Dist: %f\n", debugPuppet->mNameTag->mNormalizedDist); gTextWriter->printf("Nametag Normalized Dist: %f\n", debugPuppet->mNameTag->mNormalizedDist);
@ -178,14 +179,14 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead:
} }
break; break;
case 2: case 2:
{ {
al::PlayerHolder *pHolder = al::getScenePlayerHolder(curScene); al::PlayerHolder *pHolder = al::getScenePlayerHolder(curScene);
PlayerActorHakoniwa *p1 = pHolder->tryGetPlayer(0); PlayerActorHakoniwa *p1 = pHolder->tryGetPlayer(0);
if (p1->mHackKeeper && p1->mHackKeeper->currentHackActor) { if (p1->mHackKeeper && p1->mHackKeeper->currentHackActor) {
al::LiveActor *curHack = p1->mHackKeeper->currentHackActor; al::LiveActor *curHack = p1->mHackKeeper->currentHackActor;
gTextWriter->printf("Current Hack Animation: %s\n", al::getActionName(curHack)); gTextWriter->printf("Current Hack Animation: %s\n", al::getActionName(curHack));
gTextWriter->printf("Current Hack Name: %s\n", gTextWriter->printf("Current Hack Name: %s\n",
p1->mHackKeeper->getCurrentHackName()); p1->mHackKeeper->getCurrentHackName());
@ -209,14 +210,14 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead:
gTextWriter->printf("Cap Skew: %f\n", p1->mHackCap->mJointKeeper->mSkew); gTextWriter->printf("Cap Skew: %f\n", p1->mHackCap->mJointKeeper->mSkew);
} }
} }
} }
break; break;
default: default:
break; break;
} }
renderer->begin(); renderer->begin();
//sead::Matrix34f mat = sead::Matrix34f::ident; //sead::Matrix34f mat = sead::Matrix34f::ident;
//mat.setBase(3, sead::Vector3f::zero); // Sets the position of the matrix. //mat.setBase(3, sead::Vector3f::zero); // Sets the position of the matrix.
// For cubes, you need to put this at the location. // For cubes, you need to put this at the location.
@ -244,7 +245,7 @@ void sendShinePacket(GameDataHolderWriter thisPtr, Shine* curShine) {
if (!curShine->isGot()) { if (!curShine->isGot()) {
Client::sendShineCollectPacket(curShine->shineId); Client::sendShineCollectPacket(curShine->shineId);
} }
GameDataFunction::setGotShine(thisPtr, curShine->curShineInfo); GameDataFunction::setGotShine(thisPtr, curShine->curShineInfo);
} }
@ -252,7 +253,7 @@ void stageInitHook(al::ActorInitInfo *info, StageScene *curScene, al::PlacementI
al::initActorInitInfo(info, curScene, placement, lytInfo, factory, sceneMsgCtrl, al::initActorInitInfo(info, curScene, placement, lytInfo, factory, sceneMsgCtrl,
dataHolder); dataHolder);
Client::clearArrays(); Client::clearArrays();
Client::setSceneInfo(*info, curScene); Client::setSceneInfo(*info, curScene);
@ -264,7 +265,7 @@ void stageInitHook(al::ActorInitInfo *info, StageScene *curScene, al::PlacementI
} }
Client::sendGameInfPacket(info->mActorSceneInfo.mSceneObjHolder); Client::sendGameInfPacket(info->mActorSceneInfo.mSceneObjHolder);
} }
PlayerCostumeInfo *setPlayerModel(al::LiveActor *player, const al::ActorInitInfo &initInfo, const char *bodyModel, const char *capModel, al::AudioKeeper *keeper, bool isCloset) { PlayerCostumeInfo *setPlayerModel(al::LiveActor *player, const al::ActorInitInfo &initInfo, const char *bodyModel, const char *capModel, al::AudioKeeper *keeper, bool isCloset) {
@ -281,7 +282,7 @@ ulong constructHook() { // hook for constructing anything we need to globally b
__asm("MOV %[result], X20" __asm("MOV %[result], X20"
: [result] "=r"( : [result] "=r"(
initInfo)); // Save our scenes init info to a gloabl ptr so we can access it later initInfo)); // Save our scenes init info to a gloabl ptr so we can access it later
Client::sInstance = new Client(playBufSize); Client::sInstance = new Client(playBufSize);
return 0x20; return 0x20;
@ -311,7 +312,7 @@ bool hakoniwaSequenceHook(HakoniwaSequence* sequence) {
if (isFirstStep) { if (isFirstStep) {
Client::tryRestartCurrentMode(); Client::tryRestartCurrentMode();
} }
isInGame = !stageScene->isPause(); isInGame = !stageScene->isPause();
Client::setGameActive(!stageScene->isPause()); Client::setGameActive(!stageScene->isPause());
@ -348,7 +349,7 @@ bool hakoniwaSequenceHook(HakoniwaSequence* sequence) {
if (debugPuppetIndex >= playBufSize) if (debugPuppetIndex >= playBufSize)
debugPuppetIndex = 0; debugPuppetIndex = 0;
} }
} else if (al::isPadHoldL(-1)) { } else if (al::isPadHoldL(-1)) {
if (al::isPadTriggerLeft(-1)) Client::toggleCurrentMode(); if (al::isPadTriggerLeft(-1)) Client::toggleCurrentMode();
if (al::isPadTriggerRight(-1)) { if (al::isPadTriggerRight(-1)) {
@ -389,7 +390,7 @@ bool hakoniwaSequenceHook(HakoniwaSequence* sequence) {
} }
void seadPrintHook(const char *fmt, ...) void seadPrintHook(const char *fmt, ...)
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);

View file

@ -215,14 +215,16 @@ bool Client::startConnection() {
Client::openKeyboardPort(); Client::openKeyboardPort();
} }
bool result = mSocket->init(mServerIP.cstr(), mServerPort).isSuccess(); bool socketConnected = mSocket->isConnected();
if (!socketConnected) {
socketConnected = mSocket->init(mServerIP.cstr(), mServerPort).isSuccess();
}
if (result) { bool clientConnected = false;
if (socketConnected) {
// wait for client init packet // wait for client init packet
while (true) { while (true) {
if (mSocket->RECV()) { if (mSocket->RECV()) {
Packet* curPacket = mSocket->mPacketQueue.popFront(); Packet* curPacket = mSocket->mPacketQueue.popFront();
if (curPacket->mType == PacketType::CLIENTINIT) { if (curPacket->mType == PacketType::CLIENTINIT) {
@ -232,21 +234,20 @@ bool Client::startConnection() {
maxPuppets = initPacket->maxPlayers - 1; maxPuppets = initPacket->maxPlayers - 1;
}else { clientConnected = true;
} else {
Logger::log("First Packet was not Init!\n"); Logger::log("First Packet was not Init!\n");
result = false; clientConnected = false;
} }
free(curPacket); free(curPacket);
} }
break; break;
} }
} }
return clientConnected;
return result;
} }
/** /**
@ -317,9 +318,10 @@ void Client::openKeyboardPort() {
*/ */
void Client::readFunc() { void Client::readFunc() {
if (isFirstConnect) { if (waitForGameInit) {
nn::os::YieldThread(); // sleep the thread for the first thing we do so that game init can finish nn::os::YieldThread(); // sleep the thread for the first thing we do so that game init can finish
nn::os::SleepThread(nn::TimeSpan::FromSeconds(2)); nn::os::SleepThread(nn::TimeSpan::FromSeconds(2));
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 server
@ -398,7 +400,8 @@ void Client::readFunc() {
mSocket->SEND(&initPacket); // re-send init packet as reconnect packet mSocket->SEND(&initPacket); // re-send init packet as reconnect packet
mConnectionWait->tryEnd(); mConnectionWait->tryEnd();
continue; continue;
} else {
Logger::log("%s: not reconnected\n", __func__);
} }
nn::os::YieldThread(); // if we're currently waiting on the socket to be initialized, wait until it is nn::os::YieldThread(); // if we're currently waiting on the socket to be initialized, wait until it is
@ -449,7 +452,7 @@ void Client::readFunc() {
updateShineInfo((ShineCollect*)curPacket); updateShineInfo((ShineCollect*)curPacket);
break; break;
case PacketType::PLAYERDC: case PacketType::PLAYERDC:
Logger::log("Recieved Player Disconnect!\n"); Logger::log("Received Player Disconnect!\n");
curPacket->mUserID.print(); curPacket->mUserID.print();
disconnectPlayer((PlayerDC*)curPacket); disconnectPlayer((PlayerDC*)curPacket);
break; break;
@ -780,19 +783,19 @@ void Client::updatePlayerInfo(PlayerInf *packet) {
if (packet->actName != PlayerAnims::Type::Unknown) { if (packet->actName != PlayerAnims::Type::Unknown) {
strcpy(curInfo->curAnimStr, PlayerAnims::FindStr(packet->actName)); strcpy(curInfo->curAnimStr, PlayerAnims::FindStr(packet->actName));
if (curInfo->curAnimStr[0] == '\0')
Logger::log("[ERROR] %s: actName was out of bounds: %d\n", __func__, packet->actName);
} else { } else {
strcpy(curInfo->curAnimStr, "Wait"); strcpy(curInfo->curAnimStr, "Wait");
} }
if (strlen(curInfo->curAnimStr) == 0)
Logger::log("[ERROR] %s: actName was out of bounds: %d", __func__, packet->actName);
if(packet->subActName != PlayerAnims::Type::Unknown) { if(packet->subActName != PlayerAnims::Type::Unknown) {
strcpy(curInfo->curSubAnimStr, PlayerAnims::FindStr(packet->subActName)); strcpy(curInfo->curSubAnimStr, PlayerAnims::FindStr(packet->subActName));
if (curInfo->curSubAnimStr[0] == '\0')
Logger::log("[ERROR] %s: subActName was out of bounds: %d\n", __func__, packet->subActName);
} else { } else {
strcpy(curInfo->curSubAnimStr, ""); strcpy(curInfo->curSubAnimStr, "");
} }
if (strlen(curInfo->curSubAnimStr) == 0)
Logger::log("[ERROR] %s: subActName was out of bounds: %d", __func__, packet->subActName);
curInfo->curAnim = packet->actName; curInfo->curAnim = packet->actName;
curInfo->curSubAnim = packet->subActName; curInfo->curSubAnim = packet->subActName;

View file

@ -17,8 +17,7 @@ nn::Result SocketClient::init(const char* ip, u16 port) {
in_addr hostAddress = { 0 }; in_addr hostAddress = { 0 };
sockaddr serverAddress = { 0 }; sockaddr serverAddress = { 0 };
if (socket_log_state != SOCKET_LOG_UNINITIALIZED && socket_log_state != SOCKET_LOG_DISCONNECTED) Logger::log("SocketClient::init: %s:%d sock %s\n", ip, port, getStateChar());
return -1;
nn::nifm::Initialize(); nn::nifm::Initialize();
nn::nifm::SubmitNetworkRequest(); nn::nifm::SubmitNetworkRequest();

View file

@ -80,7 +80,7 @@ StageSceneStateServerConfig::StageSceneStateServerConfig(const char *name, al::S
mCurrentMenu = mMainOptions; mCurrentMenu = mMainOptions;
} }
void StageSceneStateServerConfig::init() { void StageSceneStateServerConfig::init() {
initNerve(&nrvStageSceneStateServerConfigMainMenu, 0); initNerve(&nrvStageSceneStateServerConfigMainMenu, 0);
} }
@ -183,7 +183,7 @@ void StageSceneStateServerConfig::exeOpenKeyboardPort() {
Client::getKeyboard()->setHeaderText(u"Set a Server Port Below."); Client::getKeyboard()->setHeaderText(u"Set a Server Port Below.");
Client::getKeyboard()->setSubText(u""); Client::getKeyboard()->setSubText(u"");
Client::openKeyboardIP(); Client::openKeyboardPort();
// anything that happens after this will be ran after the keyboard closes // anything that happens after this will be ran after the keyboard closes
al::startHitReaction(mCurrentMenu, "リセット", 0); al::startHitReaction(mCurrentMenu, "リセット", 0);
al::setNerve(this, &nrvStageSceneStateServerConfigMainMenu); al::setNerve(this, &nrvStageSceneStateServerConfigMainMenu);
@ -193,13 +193,20 @@ void StageSceneStateServerConfig::exeOpenKeyboardPort() {
void StageSceneStateServerConfig::exeRestartServer() { void StageSceneStateServerConfig::exeRestartServer() {
if (al::isFirstStep(this)) { if (al::isFirstStep(this)) {
mCurrentList->deactivate(); mCurrentList->deactivate();
Logger::log("Stopping connection\n");
Client::stopConnection(); Client::stopConnection();
} }
if (Client::isSocketActive()) { auto* client = Client::sInstance;
al::startHitReaction(mCurrentMenu, "リセット", 0);
al::setNerve(this, &nrvStageSceneStateServerConfigMainMenu); if (client) {
Logger::log("%s: Socket state: %s\n", __func__, client->mSocket->getStateChar());
client->StartThreads();
} }
al::startHitReaction(mCurrentMenu, "リセット", 0);
al::setNerve(this, &nrvStageSceneStateServerConfigMainMenu);
} }
void StageSceneStateServerConfig::exeGamemodeConfig() { void StageSceneStateServerConfig::exeGamemodeConfig() {
@ -210,7 +217,7 @@ void StageSceneStateServerConfig::exeGamemodeConfig() {
} }
subMenuUpdate(); subMenuUpdate();
if (mIsDecideConfig && mCurrentList->isDecideEnd()) { if (mIsDecideConfig && mCurrentList->isDecideEnd()) {
if (mGamemodeConfigMenu->updateMenu(mCurrentList->mCurSelected)) { if (mGamemodeConfigMenu->updateMenu(mCurrentList->mCurSelected)) {
endSubMenu(); endSubMenu();
@ -220,7 +227,7 @@ void StageSceneStateServerConfig::exeGamemodeConfig() {
void StageSceneStateServerConfig::exeGamemodeSelect() { void StageSceneStateServerConfig::exeGamemodeSelect() {
if (al::isFirstStep(this)) { if (al::isFirstStep(this)) {
mCurrentList = mModeSelectList; mCurrentList = mModeSelectList;
mCurrentMenu = mModeSelect; mCurrentMenu = mModeSelect;