diff --git a/include/server/Client.hpp b/include/server/Client.hpp index d3bf076..876b76d 100644 --- a/include/server/Client.hpp +++ b/include/server/Client.hpp @@ -241,10 +241,10 @@ class Client { int lastCollectedShine = -1; - PlayerInf lastPlayerInfPacket = - PlayerInf(); // Info struct for storing our currently logged player information - + // Backups for our last player/game packets, used for example to re-send them for newly connected clients + PlayerInf lastPlayerInfPacket = PlayerInf(); GameInf lastGameInfPacket = GameInf(); + CostumeInf lastCostumeInfPacket = CostumeInf(); Keyboard* mKeyboard = nullptr; // keyboard for setting server IP diff --git a/scripts/tcpServer.py b/scripts/tcpServer.py index f5eeb0d..6740768 100644 --- a/scripts/tcpServer.py +++ b/scripts/tcpServer.py @@ -6,8 +6,12 @@ import sys # Create a TCP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +port = 3080 +if len(sys.argv) == 3: + port = int(sys.argv[2]) + # Bind the socket to the port -server_address = (sys.argv[1], 3080) +server_address = (sys.argv[1], port) print(f"Starting TCP Server with IP {server_address[0]} and Port {server_address[1]}.") sock.bind(server_address) @@ -35,3 +39,4 @@ while True: finally: # Clean up the connection connection.close() + diff --git a/source/main.cpp b/source/main.cpp index 2306de1..971a735 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -346,7 +346,7 @@ bool hakoniwaSequenceHook(HakoniwaSequence* sequence) { if(debugPuppetIndex < 0) { debugPuppetIndex = playBufSize - 2; } - if (debugPuppetIndex >= playBufSize) + if (debugPuppetIndex >= playBufSize - 1) debugPuppetIndex = 0; } diff --git a/source/server/Client.cpp b/source/server/Client.cpp index a3accbd..8ae385c 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -435,15 +435,20 @@ void Client::readFunc() { break; case PacketType::PLAYERCON: updatePlayerConnect((PlayerConnect*)curPacket); - // send game info packet when client recieves connection - if (lastGameInfPacket.mUserID != mUserID) { - // assume game info packet is empty from first connection + // Send relevant info packets when another client is connected + + // Assume game packets are empty from first connection + if (lastGameInfPacket.mUserID != mUserID) lastGameInfPacket.mUserID = mUserID; - // leave rest blank - } - mSocket->SEND(&lastGameInfPacket); + + // No need to send player/costume packets if they're empty + if (lastPlayerInfPacket.mUserID == mUserID) + mSocket->SEND(&lastPlayerInfPacket); + if (lastCostumeInfPacket.mUserID == mUserID) + mSocket->SEND(&lastCostumeInfPacket); + break; case PacketType::COSTUMEINF: updateCostumeInfo((CostumeInf*)curPacket); @@ -698,6 +703,7 @@ void Client::sendCostumeInfPacket(const char* body, const char* cap) { CostumeInf packet = CostumeInf(body, cap); packet.mUserID = sInstance->mUserID; sInstance->mSocket->SEND(&packet); + sInstance->lastCostumeInfPacket = packet; } /** diff --git a/source/server/SocketClient.cpp b/source/server/SocketClient.cpp index bcf5a82..d22c89f 100644 --- a/source/server/SocketClient.cpp +++ b/source/server/SocketClient.cpp @@ -77,7 +77,8 @@ bool SocketClient::SEND(Packet *packet) { int valread = 0; - //Logger::log("Sending Packet Size: %d Sending Type: %s\n", packet->mPacketSize, packetNames[packet->mType]); + if (packet->mType != PLAYERINF && packet->mType != HACKCAPINF) + Logger::log("Sending packet: %s\n", packetNames[packet->mType]); if ((valread = nn::socket::Send(this->socket_log_socket, buffer, packet->mPacketSize + sizeof(Packet), this->sock_flags) > 0)) { return true; @@ -93,7 +94,7 @@ bool SocketClient::SEND(Packet *packet) { bool SocketClient::RECV() { if (this->socket_log_state != SOCKET_LOG_CONNECTED) { - Logger::log("Unable To Recieve! Socket Not Connected.\n"); + Logger::log("Unable To Receive! Socket Not Connected.\n"); this->socket_errno = nn::socket::GetLastErrno(); return false; } @@ -122,6 +123,10 @@ bool SocketClient::RECV() { if (header->mType != PacketType::UNKNOWN && fullSize <= MAXPACKSIZE && fullSize > 0) { + if (header->mType != PLAYERINF && header->mType != HACKCAPINF) + Logger::log("Received packet (from %02X%02X): %s\n", + header->mUserID.data[0], header->mUserID.data[1], packetNames[header->mType]); + char* packetBuf = (char*)malloc(fullSize); if (packetBuf) { diff --git a/source/server/logger.cpp b/source/server/logger.cpp index 8291219..6fa0b61 100644 --- a/source/server/logger.cpp +++ b/source/server/logger.cpp @@ -2,6 +2,10 @@ #include "helpers.hpp" #include "nn/result.h" +// If connection fails, try X ports above the specified one +// Useful for debugging multple clients on the same machine +constexpr u32 ADDITIONAL_LOG_PORT_COUNT = 2; + Logger* Logger::sInstance = nullptr; void Logger::createInstance() { @@ -15,9 +19,9 @@ void Logger::createInstance() { nn::Result Logger::init(const char* ip, u16 port) { sock_ip = ip; - + this->port = port; - + in_addr hostAddress = { 0 }; sockaddr serverAddress = { 0 }; @@ -38,12 +42,12 @@ nn::Result Logger::init(const char* ip, u16 port) { } #endif - + if ((this->socket_log_socket = nn::socket::Socket(2, 1, 0)) < 0) { this->socket_log_state = SOCKET_LOG_UNAVAILABLE; return -1; } - + nn::socket::InetAton(this->sock_ip, &hostAddress); serverAddress.address = hostAddress; @@ -51,17 +55,25 @@ nn::Result Logger::init(const char* ip, u16 port) { serverAddress.family = 2; nn::Result result; + bool connected = false; + for (u32 i = 0; i < ADDITIONAL_LOG_PORT_COUNT + 1; ++i) { + result = nn::socket::Connect(this->socket_log_socket, &serverAddress, sizeof(serverAddress)); + if (result.isSuccess()) { + connected = true; + break; + } + this->port++; + serverAddress.port = nn::socket::InetHtons(this->port); + } - if ((result = nn::socket::Connect(this->socket_log_socket, &serverAddress, sizeof(serverAddress))).isFailure()) { + if (connected) { + this->socket_log_state = SOCKET_LOG_CONNECTED; + this->isDisableName = false; + return 0; + } else { this->socket_log_state = SOCKET_LOG_UNAVAILABLE; return result; } - - this->socket_log_state = SOCKET_LOG_CONNECTED; - - this->isDisableName = false; - - return 0; } void Logger::log(const char *fmt, va_list args) { // impl for replacing seads system::print