diff --git a/lib/libkiwi/ap/kiwiAPServer.cpp b/lib/libkiwi/ap/kiwiAPServer.cpp new file mode 100644 index 0000000..01734e8 --- /dev/null +++ b/lib/libkiwi/ap/kiwiAPServer.cpp @@ -0,0 +1,94 @@ +#include + +namespace kiwi { +namespace ap { + +/** + * @brief Constructor + * + * @param pParser Message parser + * @param port Local port + */ +Server::Server(IMessageParser* pParser, u16 port) + : mpSocket(nullptr), mPort(0), mpConnection(nullptr), mpParser(pParser) { + + K_ASSERT_PTR(mpParser); + + mpSocket = new SyncSocket(SO_PF_INET, SO_SOCK_DGRAM); + K_ASSERT_PTR(mpSocket); + mpSocket->SetBlocking(false); + + // Variable packets only enforce an upper size bound + IPacketFactory* pPacketFactory = + new VariablePacketFactory(); + K_ASSERT_PTR(pPacketFactory); + + mpConnection = new NetServer(mpSocket, pPacketFactory); + K_ASSERT_PTR(mpConnection); + + // Bind to any available local address + SockAddr4 addr(port); + bool success = mpConnection->Bind(addr); + ASSERT_EX(success, "Can't bind server socket on port %d", addr.port); + mPort = addr.port; + + mpConnection->SetRecvCallback(PacketCallback, this); + + // Save server address + mpSocket->GetHostAddr(mServerAddr); + mServerAddr.port = mPort; +} + +/** + * @brief Destructor + */ +Server::~Server() { + delete mpConnection; + mpConnection = nullptr; + + delete mpSocket; + mpSocket = nullptr; + + delete mpParser; + mpParser = nullptr; +} + +/** + * @brief Packet receive callback + * + * @param pPacket Incoming packet + * @param pArg Callback user argument + */ +void Server::PacketCallback(PacketBase* pPacket, void* pArg) { + K_ASSERT_PTR(pPacket); + K_ASSERT_PTR(pArg); + + // Callback argument is this object + Server* p = static_cast(pArg); + K_ASSERT_PTR(p->mpParser); + + IMessage* pMessage = + p->mpParser->Parse(pPacket->GetContent(), pPacket->GetContentSize()); + + if (pMessage == nullptr) { + return; + } + + // Notify listeners + K_FOREACH (it, p->mListenerList) { + K_ASSERT_PTR(*it); + (*it)->OnReceiveMessage(pMessage); + } + + // Listener responses + K_FOREACH (it, p->mListenerList) { + K_ASSERT_PTR(*it); + (*it)->OnRespondMessage(pMessage, p->mpConnection); + } + + // Release message memory + delete pMessage; +} + +} // namespace ap +} // namespace kiwi \ No newline at end of file diff --git a/lib/libkiwi/ap/kiwiAPServer.h b/lib/libkiwi/ap/kiwiAPServer.h new file mode 100644 index 0000000..2a432f0 --- /dev/null +++ b/lib/libkiwi/ap/kiwiAPServer.h @@ -0,0 +1,132 @@ +#ifndef LIBKIWI_AP_AP_SERVER_H +#define LIBKIWI_AP_AP_SERVER_H +#include +#include +#include +#include +#include + +namespace kiwi { +//! @addtogroup libkiwi_fun +//! @{ + +// Forward declarations +class NetServer; +class PacketBase; +class SockAddrAny; +class SyncSocket; + +namespace ap { +//! @addtogroup libkiwi_fun +//! @{ + +// Forward declarations +class IMessageListener; +class IMessageParser; + +/** + * @brief Archipelago server + */ +class Server { +public: + /** + * @brief Constructor + * + * @param pParser Message parser (owned by this server) + * @param port Local port + */ + Server(IMessageParser* pParser, u16 port = port::AP_COMM); + + /** + * @brief Destructor + */ + virtual ~Server(); + + /** + * @brief Registers a new message listener + * + * @param pListener Message listener + */ + void RegistListener(IMessageListener* pListener) { + K_ASSERT_PTR(pListener); + mListenerList.PushBack(pListener); + } + + /** + * @brief Removes a message listener + * + * @param pListener Message listener + */ + void RemoveListener(IMessageListener* pListener) { + mListenerList.Remove(pListener); + } + + /** + * @brief Gets the local address of the server + */ + const SockAddr4& GetServerAddr() const { + return mServerAddr; + } + + /** + * @brief Gets the connection peer address + */ + const SockAddrAny& GetPeerAddr() const { + return mPeerAddr; + } + + /** + * @brief Sets the connection peer address + * + * @param rAddr Peer address + */ + void SetPeerAddr(const SockAddrAny& rAddr) { + K_ASSERT(rAddr.IsValid()); + mPeerAddr = rAddr; + } + + /** + * @brief Clears the connection peer address + */ + void ResetPeerAddr() { + mPeerAddr = SockAddrAny(); + } + +private: + //! Maximum datagram packet size from the PC client + static const u32 MAX_PACKET_SIZE = 512; + +private: + /** + * @brief Packet receive callback + * + * @param pPacket Incoming packet + * @param pArg Callback user argument + */ + static void PacketCallback(PacketBase* pPacket, void* pArg); + +private: + //! Server socket + SyncSocket* mpSocket; + //! Server socket port + u16 mPort; + //! Server connection + NetServer* mpConnection; + + //! Server socket address + SockAddr4 mServerAddr; + //! Client socket address + SockAddrAny mPeerAddr; + + //! Message parser (owning view) + IMessageParser* mpParser; + //! Registered message listeners + TList mListenerList; +}; + +//! @} +} // namespace ap +//! @} +} // namespace kiwi + +#endif diff --git a/lib/libkiwi/ap/kiwiIAPMessage.h b/lib/libkiwi/ap/kiwiIAPMessage.h new file mode 100644 index 0000000..ffc42ef --- /dev/null +++ b/lib/libkiwi/ap/kiwiIAPMessage.h @@ -0,0 +1,33 @@ +#ifndef LIBKIWI_AP_I_AP_MESSAGE_H +#define LIBKIWI_AP_I_AP_MESSAGE_H +#include + +namespace kiwi { +//! @addtogroup libkiwi_fun +//! @{ +namespace ap { +//! @addtogroup libkiwi_fun +//! @{ + +/** + * @brief Archipelago message interface + */ +class IMessage { +public: + /** + * @brief Destructor + */ + virtual ~IMessage() {} + + /** + * @brief Gets the type of this message + */ + virtual u32 GetType() const = 0; +}; + +//! @} +} // namespace ap +//! @} +} // namespace kiwi + +#endif diff --git a/lib/libkiwi/ap/kiwiIAPMessageListener.h b/lib/libkiwi/ap/kiwiIAPMessageListener.h new file mode 100644 index 0000000..a202c53 --- /dev/null +++ b/lib/libkiwi/ap/kiwiIAPMessageListener.h @@ -0,0 +1,51 @@ +#ifndef LIBKIWI_AP_I_AP_MESSAGE_LISTENER_H +#define LIBKIWI_AP_I_AP_MESSAGE_LISTENER_H +#include + +namespace kiwi { +//! @addtogroup libkiwi_fun +//! @{ + +// Forward declarations +class NetConnection; + +namespace ap { +//! @addtogroup libkiwi_fun +//! @{ + +// Forward declarations +class IMessage; + +/** + * @brief Archipelago message listener interface + */ +class IMessageListener { +public: + /** + * @brief Destructor + */ + virtual ~IMessageListener() {} + + /** + * @brief Callback for receiving a network message + * + * @param pMessage Network message + */ + virtual void OnReceiveMessage(IMessage* pMessage) = 0; + + /** + * @brief Callback for responding to a network message + * + * @param pMessage Network message + * @param pConnection Network connection + */ + virtual void OnRespondMessage(IMessage* pMessage, + NetConnection* pConnection) = 0; +}; + +//! @} +} // namespace ap +//! @} +} // namespace kiwi + +#endif diff --git a/lib/libkiwi/ap/kiwiIAPMessageParser.h b/lib/libkiwi/ap/kiwiIAPMessageParser.h new file mode 100644 index 0000000..0302b34 --- /dev/null +++ b/lib/libkiwi/ap/kiwiIAPMessageParser.h @@ -0,0 +1,34 @@ +#ifndef LIBKIWI_AP_I_AP_MESSAGE_PARSER_H +#define LIBKIWI_AP_I_AP_MESSAGE_PARSER_H +#include + +namespace kiwi { +//! @addtogroup libkiwi_fun +//! @{ +namespace ap { +//! @addtogroup libkiwi_fun +//! @{ + +// Forward declarations +class IMessage; + +/** + * @brief Archipelago message parser interface + */ +class IMessageParser { +public: + /** + * @brief Attempts to parse a network message + * + * @param pData Raw message data + * @param size Message data size + */ + virtual IMessage* Parse(const void* pData, u32 size) = 0; +}; + +//! @} +} // namespace ap +//! @} +} // namespace kiwi + +#endif diff --git a/lib/libkiwi/libkiwi.h b/lib/libkiwi/libkiwi.h index 6820dac..340a6dd 100644 --- a/lib/libkiwi/libkiwi.h +++ b/lib/libkiwi/libkiwi.h @@ -1,6 +1,10 @@ #ifndef LIBKIWI_LIBRARY_H #define LIBKIWI_LIBRARY_H +#include +#include +#include +#include #include #include #include diff --git a/lib/libkiwi/net/kiwiNetClient.h b/lib/libkiwi/net/kiwiNetClient.h index 110c55f..aa1d515 100644 --- a/lib/libkiwi/net/kiwiNetClient.h +++ b/lib/libkiwi/net/kiwiNetClient.h @@ -10,7 +10,7 @@ namespace kiwi { /** * @brief Network client */ -class NetClient : public detail::NetConnection { +class NetClient : public NetConnection { public: /** * @brief Constructor diff --git a/lib/libkiwi/net/kiwiNetConnection.cpp b/lib/libkiwi/net/kiwiNetConnection.cpp index ea8d0a5..d1c70ae 100644 --- a/lib/libkiwi/net/kiwiNetConnection.cpp +++ b/lib/libkiwi/net/kiwiNetConnection.cpp @@ -1,7 +1,6 @@ #include namespace kiwi { -namespace detail { /** * @brief Constructor @@ -19,14 +18,14 @@ NetConnection::NetConnection(SocketBase* pSocket, K_ASSERT_PTR(mpSocket); K_ASSERT_PTR(mpPacketFactory); - NetConnectionMgr::GetInstance().AddConnection(this); + detail::NetConnectionMgr::GetInstance().AddConnection(this); } /** * @brief Destructor */ NetConnection::~NetConnection() { - NetConnectionMgr::GetInstance().RemoveConnection(this); + detail::NetConnectionMgr::GetInstance().RemoveConnection(this); // Not owned by the connection mpSocket = nullptr; @@ -109,5 +108,4 @@ void NetConnection::Calc() { } } -} // namespace detail } // namespace kiwi \ No newline at end of file diff --git a/lib/libkiwi/net/kiwiNetConnection.h b/lib/libkiwi/net/kiwiNetConnection.h index 6d95790..0012f37 100644 --- a/lib/libkiwi/net/kiwiNetConnection.h +++ b/lib/libkiwi/net/kiwiNetConnection.h @@ -13,19 +13,17 @@ class PacketBase; class SockAddrAny; class SocketBase; -namespace detail { -//! @addtogroup libkiwi_net -//! @{ - // Forward declarations +namespace detail { class NetConnectionMgr; +} // namespace detail /** * @brief Network socket connection wrapper */ class NetConnection { // Expose Calc only to the manager - friend class NetConnectionMgr; + friend class detail::NetConnectionMgr; public: /** @@ -129,8 +127,6 @@ class NetConnection { void Calc(); }; -//! @} -} // namespace detail //! @} } // namespace kiwi diff --git a/lib/libkiwi/net/kiwiNetConnectionMgr.h b/lib/libkiwi/net/kiwiNetConnectionMgr.h index efcdff1..3d8d381 100644 --- a/lib/libkiwi/net/kiwiNetConnectionMgr.h +++ b/lib/libkiwi/net/kiwiNetConnectionMgr.h @@ -9,15 +9,13 @@ namespace kiwi { //! @{ // Forward declarations +class NetConnection; class StdThread; namespace detail { //! @addtogroup libkiwi_net //! @{ -// Forward declarations -class NetConnection; - /** * @brief Network socket connection manager */ diff --git a/lib/libkiwi/net/kiwiNetServer.h b/lib/libkiwi/net/kiwiNetServer.h index 486db54..64e3cef 100644 --- a/lib/libkiwi/net/kiwiNetServer.h +++ b/lib/libkiwi/net/kiwiNetServer.h @@ -10,7 +10,7 @@ namespace kiwi { /** * @brief Network server */ -class NetServer : public detail::NetConnection { +class NetServer : public NetConnection { public: /** * @brief Constructor diff --git a/src/Cmn/SceneHook.cpp b/src/Cmn/SceneHook.cpp new file mode 100644 index 0000000..efbafbc --- /dev/null +++ b/src/Cmn/SceneHook.cpp @@ -0,0 +1,64 @@ +#include "Cmn/SceneHook.h" + +#include "Cmn/TextDisplay.h" +#include "Net/GameMessageListener.h" + +#include + +K_DYNAMIC_SINGLETON_IMPL(AP::Cmn::SceneHook); + +namespace AP { +namespace Cmn { + +/** + * @brief Constructor + */ +SceneHook::SceneHook() : mpListener(nullptr), mpTextDisplay(nullptr) { + mpListener = new Net::GameMessageListener(); + ASSERT_PTR(mpListener); + + mpTextDisplay = new TextDisplay(); + ASSERT_PTR(mpTextDisplay); +} + +/** + * @brief Destructor + */ +SceneHook::~SceneHook() { + delete mpListener; + mpListener = nullptr; + + delete mpTextDisplay; + mpTextDisplay = nullptr; +} + +/** + * @brief Handles scene Configure event + * + * @param pScene Current scene + */ +void SceneHook::Configure(RPSysScene* pScene) { + if (pScene->getSceneID() == kiwi::SceneCreator::GetBootScene()) { + return; + } + + ASSERT_PTR(mpTextDisplay); + mpTextDisplay->Configure(); +} + +/** + * @brief Handles scene Calculate event + * + * @param pScene Current scene + */ +void SceneHook::AfterCalculate(RPSysScene* pScene) { + if (pScene->getSceneID() == kiwi::SceneCreator::GetBootScene()) { + return; + } + + ASSERT_PTR(mpTextDisplay); + mpTextDisplay->Calculate(); +} + +} // namespace Cmn +} // namespace AP \ No newline at end of file diff --git a/src/Cmn/SceneHook.h b/src/Cmn/SceneHook.h new file mode 100644 index 0000000..4352004 --- /dev/null +++ b/src/Cmn/SceneHook.h @@ -0,0 +1,62 @@ +#ifndef APCLIENT_CMN_SCENE_HOOK_H +#define APCLIENT_CMN_SCENE_HOOK_H +#include + +#include "Net/GameMessageListener.h" + +#include + +namespace AP { +namespace Cmn { + +// Forward declarations +class TextDisplay; + +/** + * @brief Common scene hook + */ +class SceneHook : public kiwi::DynamicSingleton, + public kiwi::ISceneHook { +public: + /** + * @brief Constructor + */ + SceneHook(); + + /** + * @brief Destructor + */ + virtual ~SceneHook(); + + /** + * @brief Handles scene Configure event + * + * @param pScene Current scene + */ + virtual void Configure(RPSysScene* pScene); + + /** + * @brief Handles scene Calculate event + * + * @param pScene Current scene + */ + virtual void AfterCalculate(RPSysScene* pScene); + + /** + * @brief Accesses the scene text message writer + */ + TextDisplay* GetTextDisplay() const { + return mpTextDisplay; + } + +private: + //! AP message listener + Net::GameMessageListener* mpListener; + //! AP message text writer + TextDisplay* mpTextDisplay; +}; + +} // namespace Cmn +} // namespace AP + +#endif diff --git a/src/Cmn/System.cpp b/src/Cmn/System.cpp index d65e3e4..ebe788c 100644 --- a/src/Cmn/System.cpp +++ b/src/Cmn/System.cpp @@ -3,8 +3,8 @@ #include "Cmn/CheckMgr.h" #include "Cmn/CosmeticMgr.h" #include "Cmn/ItemMgr.h" +#include "Cmn/SceneHook.h" #include "Net/NetworkMgr.h" -#include "Net/TextDisplay.h" namespace AP { namespace Cmn { @@ -25,7 +25,7 @@ void System::Initialize() { #endif Net::NetworkMgr::CreateInstance(); - Net::TextDisplay::CreateInstance(); + Cmn::SceneHook::CreateInstance(); } } // namespace Cmn diff --git a/src/Net/TextDisplay.cpp b/src/Cmn/TextDisplay.cpp similarity index 50% rename from src/Net/TextDisplay.cpp rename to src/Cmn/TextDisplay.cpp index d0f7235..72c6695 100644 --- a/src/Net/TextDisplay.cpp +++ b/src/Cmn/TextDisplay.cpp @@ -1,88 +1,75 @@ -#include "Net/TextDisplay.h" +#include "Cmn/TextDisplay.h" -#include "Net/IMessage.h" #include "Net/NetworkMgr.h" -#include "Net/msg/PrintMsg.h" #include #include -K_DYNAMIC_SINGLETON_IMPL(AP::Net::TextDisplay); +#include namespace AP { -namespace Net { +namespace Cmn { /** * @brief Constructor */ TextDisplay::TextDisplay() - : mStateMachine(this, EState_Max, EState_Wait), mTimer(0) { + : mStateMachine(this, EState_Max, EState_Offline), mTimer(0) { + mStateMachine.RegistState(EState_Offline, &TextDisplay::State_Offline_calc); mStateMachine.RegistState(EState_Wait, &TextDisplay::State_Wait_calc); mStateMachine.RegistState(EState_Show, &TextDisplay::State_Show_calc); mStateMachine.RegistState(EState_Fade, &TextDisplay::State_Fade_calc); - - NetworkMgr::GetInstance().RegistListener(this); } /** - * @brief Handles a new network message - * - * @param pMessage Network message + * @brief Handles scene Configure event */ -void TextDisplay::OnMessage(IMessage* pMessage) { - ASSERT_PTR(pMessage); - - // Only interested in Print messages - if (pMessage->GetKind() != IMessage::EKind_Print) { - return; - } - - PrintMsg* pPrintMsg = static_cast(pMessage); +void TextDisplay::Configure() { + RPGrpRenderer* pRenderer = RPGrpRenderer::GetCurrent(); - K_FOREACH (it, pPrintMsg->GetMessageList()) { - mTextQueue.PushBack(*it); + if (pRenderer != nullptr) { + pRenderer->AppendDrawObject(this); } } /** - * @brief Handles scene Configure event - * - * @param pScene Current scene + * @brief Handles scene UserDraw event */ -void TextDisplay::Configure(RPSysScene* /* pScene */) { - RPGrpRenderer* pRenderer = RPGrpRenderer::GetCurrent(); - - K_ASSERT_PTR(pRenderer); - pRenderer->AppendDrawObject(this); +void TextDisplay::UserDraw() { + if (mStateMachine.IsState(EState_Offline)) { + DrawOfflineMsg(); + } else { + DrawQueue(); + } } /** - * @brief Handles scene UserDraw event + * @brief Updates the text display in the Offline state */ -void TextDisplay::UserDraw() { - if (mTextQueue.Empty()) { +void TextDisplay::State_Offline_calc() { + if (mStateMachine.IsFirstStep()) { + mTimer = 0; return; } - u8 alpha = 255; - - if (mStateMachine.IsState(EState_Fade)) { - f32 amount = static_cast(mTimer) / FADE_TIMER; - alpha *= amount; + // Client is connected once the peer address is set + if (Net::NetworkMgr::GetInstance().GetPeerAddr().IsValid()) { + mTextQueue.PushBack(L"Connected!"); + mStateMachine.ChangeState(EState_Wait); } - kiwi::Text(mTextQueue.Front()) - .SetPosition(0.10, 0.90) - .SetTextColor(kiwi::Color::WHITE) - .SetStrokeType(kiwi::ETextStroke_Outline) - .SetAlpha(alpha); + mTimer = ++mTimer % OFFLINE_TIMER; } /** - * @brief Updates the packet in the Wait state + * @brief Updates the text display in the Wait state */ void TextDisplay::State_Wait_calc() { + if (!Net::NetworkMgr::GetInstance().GetPeerAddr().IsValid()) { + mStateMachine.ChangeState(EState_Offline); + } + // Wait for any messages to appear if (!mTextQueue.Empty()) { mStateMachine.ChangeState(EState_Show); @@ -104,7 +91,7 @@ void TextDisplay::State_Show_calc() { } /** - * @brief Updates the packet in the Fade state + * @brief Updates the text display in the Fade state */ void TextDisplay::State_Fade_calc() { if (mStateMachine.IsFirstStep()) { @@ -119,5 +106,43 @@ void TextDisplay::State_Fade_calc() { } } -} // namespace Net +/** + * @brief Displays the offline state message + */ +void TextDisplay::DrawOfflineMsg() const { + kiwi::SockAddr4 addr = Net::NetworkMgr::GetInstance().GetServerAddr(); + ASSERT(addr.IsValid()); + + f32 hue = static_cast(mTimer) / OFFLINE_TIMER; + kiwi::Color stroke = kiwi::Color::FromHsv(hue, 0.4f, 1.0f); + + kiwi::Text("Waiting for client... (%s)", kiwi::ToString(addr).CStr()) + .SetPosition(0.10, 0.90) + .SetTextColor(stroke) + .SetStrokeType(kiwi::ETextStroke_Outline); +} + +/** + * @brief Displays the current text message queue + */ +void TextDisplay::DrawQueue() const { + if (mTextQueue.Empty()) { + return; + } + + u8 alpha = 0xFF; + + if (mStateMachine.IsState(EState_Fade)) { + f32 amount = static_cast(mTimer) / FADE_TIMER; + alpha *= amount; + } + + kiwi::Text(mTextQueue.Front()) + .SetPosition(0.10, 0.90) + .SetTextColor(kiwi::Color::WHITE) + .SetStrokeType(kiwi::ETextStroke_Outline) + .SetAlpha(alpha); +} + +} // namespace Cmn } // namespace AP \ No newline at end of file diff --git a/src/Cmn/TextDisplay.h b/src/Cmn/TextDisplay.h new file mode 100644 index 0000000..201533f --- /dev/null +++ b/src/Cmn/TextDisplay.h @@ -0,0 +1,112 @@ +#ifndef APCLIENT_CMN_TEXT_DISPLAY_H +#define APCLIENT_CMN_TEXT_DISPLAY_H +#include + +#include + +#include + +namespace AP { +namespace Cmn { + +/** + * @brief Message text writer + */ +class TextDisplay : public IRPGrpDrawObject { +public: + /** + * @brief Constructor + */ + TextDisplay(); + + /** + * @brief Handles scene Configure event + */ + void Configure(); + + /** + * @brief Handles scene Calculate event + */ + void Calculate() { + mStateMachine.Calculate(); + } + + /** + * @brief Handles scene UserDraw event + */ + void UserDraw(); + + /** + * @brief Adds a text message to the queue + * + * @param rText Text message + */ + void EnqueueText(const kiwi::WString& rText) { + mTextQueue.PushBack(rText); + } + +private: + /** + * @brief State machine state + */ + enum EState { + EState_Offline, //!< Waiting for client connection + EState_Wait, //!< Waiting for message + EState_Show, //!< Show the current message + EState_Fade, //!< Fade out the current message + + EState_Max + }; + + //! Time before wrapping the hue of the offline message + static const u32 OFFLINE_TIMER = 60 * 30; + //! Time to show the current message before fading away + static const u32 SHOW_TIMER = 60 * 2; + //! Time to show the message while fading away + static const u32 FADE_TIMER = 60 * 1; + +private: + /** + * @brief Updates the text display in the Offline state + */ + K_STATE_DECL(Offline); + + /** + * @brief Updates the text display in the Wait state + */ + K_STATE_DECL(Wait); + + /** + * @brief Updates the text display in the Show state + */ + K_STATE_DECL(Show); + + /** + * @brief Updates the text display in the Fade state + */ + K_STATE_DECL(Fade); + + /** + * @brief Displays the offline state message + */ + void DrawOfflineMsg() const; + + /** + * @brief Displays the current text message queue + */ + void DrawQueue() const; + +private: + //! Logic state machine + kiwi::StateMachine mStateMachine; + //! Message display timer + s32 mTimer; + + //! Message text queue + kiwi::TList mTextQueue; +}; + +} // namespace Cmn +} // namespace AP + +#endif diff --git a/src/Net/Define.h b/src/Net/Define.h new file mode 100644 index 0000000..7796805 --- /dev/null +++ b/src/Net/Define.h @@ -0,0 +1,27 @@ +#ifndef APCLIENT_NET_DEFINE_H +#define APCLIENT_NET_DEFINE_H +#include + +namespace AP { +namespace Net { +namespace Define { + +/** + * @brief Archipelago message types + */ +enum EMessageType { + /* 0x00 */ EMessageType_Connect, + /* 0x01 */ EMessageType_Disconnect, + /* 0x02 */ EMessageType_Print, + /* 0x03 */ EMessageType_Item, + /* 0x04 */ EMessageType_Location, +}; + +//! General message acknowledgement byte +static const u8 ACK = 0xAA; + +} // namespace Define +} // namespace Net +} // namespace AP + +#endif diff --git a/src/Net/GameMessageListener.cpp b/src/Net/GameMessageListener.cpp new file mode 100644 index 0000000..ddc49b0 --- /dev/null +++ b/src/Net/GameMessageListener.cpp @@ -0,0 +1,122 @@ +#include "Net/GameMessageListener.h" + +#include "Cmn/CheckMgr.h" +#include "Cmn/ItemMgr.h" +#include "Cmn/SceneHook.h" +#include "Cmn/TextDisplay.h" +#include "Net/Define.h" +#include "Net/NetworkMgr.h" +#include "Net/msg/ConnectMsg.h" +#include "Net/msg/ItemMsg.h" +#include "Net/msg/PrintMsg.h" +#include "checks.h" + +#include + +namespace AP { +namespace Net { + +/** + * @brief Callback for receiving a network message + * + * @param pMessage Network message + */ +void GameMessageListener::OnReceiveMessage(kiwi::ap::IMessage* pMessage) { + ASSERT_PTR(pMessage); + + switch (pMessage->GetType()) { + // PC client is attempting to connect + case Define::EMessageType_Connect: { + ConnectMsg* pConnectMsg = static_cast(pMessage); + NetworkMgr::GetInstance().SetPeerAddr(pConnectMsg->GetPeerAddr()); + break; + } + + // PC client has disconnected + case Define::EMessageType_Disconnect: { + NetworkMgr::GetInstance().ResetPeerAddr(); + break; + } + + // PC client wants to display a message + case Define::EMessageType_Print: { + PrintMsg* pPrintMsg = static_cast(pMessage); + + K_FOREACH (it, pPrintMsg->GetMessageList()) { + Cmn::SceneHook::GetInstance().GetTextDisplay()->EnqueueText(*it); + } + break; + } + + // PC client wants to award an item + case Define::EMessageType_Item: { + ItemMsg* pItemMsg = static_cast(pMessage); + Cmn::ItemMgr::GetInstance().SetItemState(pItemMsg->GetItemID(), true); + break; + } + + // PC client is requesting a list of completed locations/checks + case Define::EMessageType_Location: { + break; + } + + default: { + ASSERT_EX(false, "Unknown message type: %d", pMessage->GetType()); + break; + } + } +} + +/** + * @brief Callback for responding to a network message + * + * @param pMessage Network message + * @param pConnection Network connection + */ +void GameMessageListener::OnRespondMessage(kiwi::ap::IMessage* pMessage, + kiwi::NetConnection* pConnection) { + ASSERT_PTR(pMessage); + ASSERT_PTR(pConnection); + + // We must provide the peer address, this is a UDP socket + const kiwi::SockAddrAny& rPeerAddr = + NetworkMgr::GetInstance().GetPeerAddr(); + + ASSERT(rPeerAddr.IsValid()); + + switch (pMessage->GetType()) { + // PC client is requesting a list of completed locations/checks + case Define::EMessageType_Location: { + kiwi::TVector locations; + +#define X(ID, IDENTIFIER, STR) \ + if (Cmn::CheckMgr::GetInstance().GetCheckState( \ + static_cast(ID))) { \ + \ + locations.PushBack(static_cast(ID)); \ + } + + AP_CHECKS_X_MACRO; + +#undef X + + // Can't send an empty packet, so we send a sentinel value + if (locations.Empty()) { + locations.PushBack(CHECK_INVALID); + } + + pConnection->Send(locations.Data(), locations.Size() * sizeof(u16), + &rPeerAddr); + break; + } + + // Other messages require only a simple acknowledgement + default: { + pConnection->Send(Net::Define::ACK, &rPeerAddr); + break; + } + } +} + +} // namespace Net +} // namespace AP \ No newline at end of file diff --git a/src/Net/GameMessageListener.h b/src/Net/GameMessageListener.h new file mode 100644 index 0000000..55c623f --- /dev/null +++ b/src/Net/GameMessageListener.h @@ -0,0 +1,51 @@ +#ifndef APCLIENT_NET_GAME_MESSAGE_LISTENER_H +#define APCLIENT_NET_GAME_MESSAGE_LISTENER_H +#include + +#include "Net/NetworkMgr.h" + +#include + +namespace AP { +namespace Net { + +/** + * @brief Archipelago message listener + */ +class GameMessageListener : public kiwi::ap::IMessageListener { +public: + /** + * @brief Constructor + */ + GameMessageListener() { + NetworkMgr::GetInstance().RegistListener(this); + } + + /** + * @brief Destructor + */ + virtual ~GameMessageListener() { + NetworkMgr::GetInstance().RemoveListener(this); + } + + /** + * @brief Callback for receiving a network message + * + * @param pMessage Network message + */ + virtual void OnReceiveMessage(kiwi::ap::IMessage* pMessage); + + /** + * @brief Callback for responding to a network message + * + * @param pMessage Network message + * @param pConnection Network connection + */ + virtual void OnRespondMessage(kiwi::ap::IMessage* pMessage, + kiwi::NetConnection* pConnection); +}; + +} // namespace Net +} // namespace AP + +#endif diff --git a/src/Net/GameMessageParser.cpp b/src/Net/GameMessageParser.cpp new file mode 100644 index 0000000..35a2800 --- /dev/null +++ b/src/Net/GameMessageParser.cpp @@ -0,0 +1,60 @@ +#include "Net/GameMessageParser.h" + +#include "Net/Define.h" +#include "Net/msg/ConnectMsg.h" +#include "Net/msg/DisconnectMsg.h" +#include "Net/msg/ItemMsg.h" +#include "Net/msg/LocationMsg.h" +#include "Net/msg/PrintMsg.h" + +#include + +namespace AP { +namespace Net { + +/** + * @brief Attempts to parse a network message + * + * @param pData Raw message data + * @param size Message data size + */ +kiwi::ap::IMessage* GameMessageParser::Parse(const void* pData, u32 size) { + ASSERT_PTR(pData); + ASSERT(size > 0); + + kiwi::MemStream strm(pData, size); + + // Every packet's data begins with the common fields + Define::EMessageType type = + static_cast(strm.Read_u8()); + + switch (type) { + case Define::EMessageType_Connect: { + return new ConnectMsg(strm); + } + + case Define::EMessageType_Disconnect: { + return new DisconnectMsg(strm); + } + + case Define::EMessageType_Print: { + return new PrintMsg(strm); + } + + case Define::EMessageType_Item: { + return new ItemMsg(strm); + } + + case Define::EMessageType_Location: { + return new LocationMsg(strm); + } + + default: { + K_ASSERT_EX(false, "Unknown message type: %d\n", type); + return nullptr; + } + } +} + +} // namespace Net +} // namespace AP diff --git a/src/Net/GameMessageParser.h b/src/Net/GameMessageParser.h new file mode 100644 index 0000000..4778963 --- /dev/null +++ b/src/Net/GameMessageParser.h @@ -0,0 +1,27 @@ +#ifndef APCLIENT_NET_GAME_MESSAGE_PARSER_H +#define APCLIENT_NET_GAME_MESSAGE_PARSER_H +#include + +#include + +namespace AP { +namespace Net { + +/** + * @brief Archipelago message parser + */ +class GameMessageParser : public kiwi::ap::IMessageParser { +public: + /** + * @brief Attempts to parse a network message + * + * @param pData Raw message data + * @param size Message data size + */ + virtual kiwi::ap::IMessage* Parse(const void* pData, u32 size); +}; + +} // namespace Net +} // namespace AP + +#endif diff --git a/src/Net/IMessage.h b/src/Net/IMessage.h deleted file mode 100644 index 6703c43..0000000 --- a/src/Net/IMessage.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef APCLIENT_NET_I_MESSAGE_H -#define APCLIENT_NET_I_MESSAGE_H -#include - -namespace AP { -namespace Net { - -/** - * @brief Network message interface - */ -class IMessage { -public: - /** - * @brief Command type - */ - enum EKind { - EKind_Connect, // 0 - EKind_Disconnect, // 1 - EKind_Print, // 2 - EKind_Item, // 3 - EKind_Location, // 4 - }; - -public: - /** - * @brief Destructor - */ - virtual ~IMessage() {} - - /** - * @brief Gets the type of this message - */ - virtual EKind GetKind() const = 0; -}; - -} // namespace Net -} // namespace AP - -#endif diff --git a/src/Net/IMessageListener.h b/src/Net/IMessageListener.h deleted file mode 100644 index 78df47c..0000000 --- a/src/Net/IMessageListener.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef APCLIENT_NET_I_MESSAGE_LISTENER_H -#define APCLIENT_NET_I_MESSAGE_LISTENER_H -#include - -namespace AP { -namespace Net { - -// Forward declarations -class IMessage; - -/** - * @brief Network message listener interface - */ -class IMessageListener { -public: - /** - * @brief Destructor - */ - virtual ~IMessageListener() {} - - /** - * @brief Handles a new network message - * - * @param pMessage Network message - */ - virtual void OnMessage(IMessage* pMessage) = 0; -}; - -} // namespace Net -} // namespace AP - -#endif diff --git a/src/Net/NetworkMgr.cpp b/src/Net/NetworkMgr.cpp index 6bf5b99..5e6ffda 100644 --- a/src/Net/NetworkMgr.cpp +++ b/src/Net/NetworkMgr.cpp @@ -1,13 +1,6 @@ #include "Net/NetworkMgr.h" -#include "Net/IMessage.h" -#include "Net/IMessageListener.h" -#include "Net/msg/ConnectMsg.h" -#include "Net/msg/DisconnectMsg.h" -#include "Net/msg/ItemMsg.h" -#include "Net/msg/LocationMsg.h" -#include "Net/msg/PrintMsg.h" -#include "const.h" +#include "Net/GameMessageParser.h" #include @@ -19,126 +12,12 @@ namespace Net { /** * @brief Constructor */ -NetworkMgr::NetworkMgr() { - bool success = false; +NetworkMgr::NetworkMgr() : Server(new GameMessageParser()) { + kiwi::SockAddr4 addr = GetServerAddr(); + ASSERT(addr.IsValid()); - // Create server socket - mpSocket = new kiwi::SyncSocket(SO_PF_INET, SO_SOCK_DGRAM); - ASSERT_PTR(mpSocket); - - // TODO(kiwi) Can we remove this? - mpSocket->SetBlocking(false); - - // Create server connection - mpServer = new kiwi::NetServer( - mpSocket, new kiwi::VariablePacketFactory()); - - ASSERT_PTR(mpServer); - - // Bind to any available local address - kiwi::SockAddr4 addr(kiwi::port::AP_COMM); - success = mpServer->Bind(addr); - ASSERT_EX(success, "Can't bind socket"); - - // Register callback to handle PC client packets - mpServer->SetRecvCallback(PacketCallback); - - // Show IP address in the console - u16 port = addr.port; - mpSocket->GetHostAddr(addr); - addr.port = port; - - LOG_EX("NetworkMgr listening on: %s\n", kiwi::ToString(addr).CStr()); -} - -/** - * @brief Destructor - */ -NetworkMgr::~NetworkMgr() { - delete mpServer; - mpServer = nullptr; - - delete mpSocket; - mpSocket = nullptr; -} - -/** - * @brief Packet receive callback - * - * @param pPacket Incoming packet - * @param pArg Callback user argument - */ -void NetworkMgr::PacketCallback(kiwi::PacketBase* pPacket, void* pArg) { - ASSERT_PTR(pPacket); - - IMessage* pMessage = nullptr; - NetworkMgr& r = GetInstance(); - - const void* pContent = pPacket->GetContent(); - u32 contentSize = pPacket->GetContentSize(); - kiwi::MemStream contentStrm(pContent, contentSize); - - // Every packet's data begins with the common fields - u8 kind = contentStrm.Read_u8(); - -#define HANDLE_PACKET(NAME) \ - case IMessage::EKind_##NAME: { \ - pMessage = new NAME##Msg(contentStrm); \ - break; \ - } - - switch (kind) { - HANDLE_PACKET(Connect); - HANDLE_PACKET(Disconnect); - HANDLE_PACKET(Print); - HANDLE_PACKET(Item); - HANDLE_PACKET(Location); - - default: { - ASSERT_EX(false, "Unknown packet type: %d", kind); - break; - } - } - -#undef HANDLE_PACKET - - if (pMessage == nullptr) { - return; - } - - // Save client address from connect messages - if (pMessage->GetKind() == IMessage::EKind_Connect) { - r.mPeerAddr = static_cast(pMessage)->GetPeerAddr(); - } - - // Notify listeners - K_FOREACH (it, r.mListenerList) { - ASSERT_PTR(*it); - (*it)->OnMessage(pMessage); - } - - // TODO(kiwi) Move this somewhere else - if (r.mPeerAddr.IsValid()) { - // Location message response - if (pMessage->GetKind() == IMessage::EKind_Location) { - kiwi::TVector checks = - static_cast(pMessage)->GetChecks(); - - if (checks.Empty()) { - checks.PushBack(CHECK_INVALID); - } - - r.mpServer->Send(checks.Data(), checks.Size() * sizeof(u32), - &r.mPeerAddr); - } - // Generic acknowledgement - else { - u8 ack = 0xAA; - r.mpServer->Send(ack, &r.mPeerAddr); - } - } - - delete pMessage; + LOG_EX("[NetworkMgr] Listening for client: %s\n", + kiwi::ToString(addr).CStr()); } } // namespace Net diff --git a/src/Net/NetworkMgr.h b/src/Net/NetworkMgr.h index 0735f6a..f81d06c 100644 --- a/src/Net/NetworkMgr.h +++ b/src/Net/NetworkMgr.h @@ -7,60 +7,19 @@ namespace AP { namespace Net { -// Forward declarations -class IMessageListener; - /** - * @brief Archipelago connection + * @brief Network communication manager */ -class NetworkMgr : public kiwi::DynamicSingleton { - friend class kiwi::DynamicSingleton; - -public: - /** - * @brief Registers a new message listener - * - * @param pListener Message listener - */ - void RegistListener(IMessageListener* pListener) { - ASSERT_PTR(pListener); - mListenerList.PushBack(pListener); - } +class NetworkMgr : public kiwi::ap::Server, + public kiwi::DynamicSingleton { -private: - //! Maximum datagram packet size from the PC client - static const u32 MAX_PACKET_SIZE = 512; + friend class kiwi::DynamicSingleton; private: /** * @brief Constructor */ NetworkMgr(); - - /** - * @brief Destructor - */ - ~NetworkMgr(); - - /** - * @brief Packet receive callback - * - * @param pPacket Incoming packet - * @param pArg Callback user argument - */ - static void PacketCallback(kiwi::PacketBase* pPacket, void* pArg); - -private: - //! Server socket - kiwi::SyncSocket* mpSocket; - //! Server connection - kiwi::NetServer* mpServer; - - //! PC client socket address - kiwi::SockAddrAny mPeerAddr; - - //! Registered message listeners - kiwi::TList mListenerList; }; } // namespace Net diff --git a/src/Net/TextDisplay.h b/src/Net/TextDisplay.h deleted file mode 100644 index 442eb64..0000000 --- a/src/Net/TextDisplay.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef APCLIENT_NET_TEXT_DISPLAY_H -#define APCLIENT_NET_TEXT_DISPLAY_H -#include - -#include "Net/IMessageListener.h" -#include - -#include - -namespace AP { -namespace Net { - -/** - * @brief Message text writer - */ -class TextDisplay : public IMessageListener, - public kiwi::ISceneHook, - public IRPGrpDrawObject, - public kiwi::DynamicSingleton { - - friend class kiwi::DynamicSingleton; - -private: - /** - * @brief State machine state - */ - enum EState { - EState_Wait, //!< Waiting for message - EState_Show, //!< Show the current message - EState_Fade, //!< Fade out the current message - - EState_Max - }; - - //! Time to show the current message before fading away - static const u32 SHOW_TIMER = 120; - //! Time to show the message while fading away - static const u32 FADE_TIMER = 60; - -private: - /** - * @brief Constructor - */ - TextDisplay(); - - /** - * @brief Handles a new network message - * - * @param pMessage Network message - */ - virtual void OnMessage(IMessage* pMessage); - - /** - * @brief Handles scene Configure event - * - * @param pScene Current scene - */ - virtual void Configure(RPSysScene* pScene); - - /** - * @brief Handles scene Calculate event - * - * @param pScene Current scene - */ - virtual void AfterCalculate(RPSysScene* /* pScene */) { - mStateMachine.Calculate(); - } - - /** - * @brief Handles scene UserDraw event - */ - virtual void UserDraw(); - - /** - * @brief Updates the packet in the Wait state - */ - K_STATE_DECL(Wait); - - /** - * @brief Updates the text display in the Show state - */ - K_STATE_DECL(Show); - - /** - * @brief Updates the packet in the Fade state - */ - K_STATE_DECL(Fade); - -private: - //! Logic state machine - kiwi::StateMachine mStateMachine; - - //! Message display timer - s32 mTimer; - - //! Message text queue - kiwi::TList mTextQueue; -}; - -} // namespace Net -} // namespace AP - -#endif diff --git a/src/Net/msg/ConnectMsg.h b/src/Net/msg/ConnectMsg.h index 14a1c09..ff3d9d7 100644 --- a/src/Net/msg/ConnectMsg.h +++ b/src/Net/msg/ConnectMsg.h @@ -2,7 +2,7 @@ #define APCLIENT_NET_MSG_CONNECT_MSG_H #include -#include "Net/IMessage.h" +#include "Net/Define.h" #include @@ -12,7 +12,7 @@ namespace Net { /** * @brief PC client connection message */ -class ConnectMsg : public IMessage { +class ConnectMsg : public kiwi::ap::IMessage { public: /** * @brief Constructor @@ -22,10 +22,10 @@ class ConnectMsg : public IMessage { ConnectMsg(kiwi::MemStream& rStrm); /** - * @brief Gets the type of this command + * @brief Gets the type of this message */ - virtual EKind GetKind() const { - return EKind_Connect; + virtual u32 GetType() const { + return Define::EMessageType_Connect; } /** diff --git a/src/Net/msg/DisconnectMsg.h b/src/Net/msg/DisconnectMsg.h index 0805285..53d7097 100644 --- a/src/Net/msg/DisconnectMsg.h +++ b/src/Net/msg/DisconnectMsg.h @@ -2,7 +2,7 @@ #define APCLIENT_NET_MSG_DISCONNECT_MSG_H #include -#include "Net/IMessage.h" +#include "Net/Define.h" #include @@ -12,7 +12,7 @@ namespace Net { /** * @brief PC client disconnection message */ -class DisconnectMsg : public IMessage { +class DisconnectMsg : public kiwi::ap::IMessage { public: /** * @brief Constructor @@ -22,10 +22,10 @@ class DisconnectMsg : public IMessage { DisconnectMsg(kiwi::MemStream& /* rStrm */) {} /** - * @brief Gets the type of this command + * @brief Gets the type of this message */ - virtual EKind GetKind() const { - return EKind_Disconnect; + virtual u32 GetType() const { + return Define::EMessageType_Disconnect; } }; diff --git a/src/Net/msg/ItemMsg.cpp b/src/Net/msg/ItemMsg.cpp index 694769a..2bfb709 100644 --- a/src/Net/msg/ItemMsg.cpp +++ b/src/Net/msg/ItemMsg.cpp @@ -1,5 +1,7 @@ #include "Net/msg/ItemMsg.h" + #include "Cmn/ItemMgr.h" +#include "const.h" #include @@ -8,13 +10,13 @@ namespace Net { /** * @brief Constructor - * + * * @param rStrm Stream to packet content */ ItemMsg::ItemMsg(kiwi::MemStream& rStrm) { - u16 itemId = rStrm.Read_u16(); - - Cmn::ItemMgr::GetInstance().SetItemState((ItemID)itemId, true); + mItemID = static_cast(rStrm.Read_u16()); + ASSERT(mItemID != ITEM_INVALID); } -} -} \ No newline at end of file + +} // namespace Net +} // namespace AP \ No newline at end of file diff --git a/src/Net/msg/ItemMsg.h b/src/Net/msg/ItemMsg.h index 35308ec..0064c4b 100644 --- a/src/Net/msg/ItemMsg.h +++ b/src/Net/msg/ItemMsg.h @@ -2,7 +2,8 @@ #define APCLIENT_NET_MSG_ITEM_MSG_H #include -#include "Net/IMessage.h" +#include "Net/Define.h" +#include "const.h" #include @@ -12,7 +13,7 @@ namespace Net { /** * @brief Item message */ -class ItemMsg : public IMessage { +class ItemMsg : public kiwi::ap::IMessage { public: /** * @brief Constructor @@ -22,11 +23,22 @@ class ItemMsg : public IMessage { ItemMsg(kiwi::MemStream& rStrm); /** - * @brief Gets the type of this command + * @brief Gets the type of this message */ - virtual EKind GetKind() const { - return EKind_Item; + virtual u32 GetType() const { + return Define::EMessageType_Item; } + + /** + * @brief Gets the ID of the item to award + */ + ItemID GetItemID() const { + return mItemID; + } + +private: + // ID of the item to award + ItemID mItemID; }; } // namespace Net diff --git a/src/Net/msg/LocationMsg.cpp b/src/Net/msg/LocationMsg.cpp deleted file mode 100644 index 475116e..0000000 --- a/src/Net/msg/LocationMsg.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "Net/msg/LocationMsg.h" - -#include "Cmn/CheckMgr.h" -#include "Net/NetworkMgr.h" -#include "checks.h" - -#include - -namespace AP { -namespace Net { - -/** - * @brief Constructor - * - * @param rStrm Stream to packet content - */ -LocationMsg::LocationMsg(kiwi::MemStream& rStrm) { - // mData.Clear(); -} - -kiwi::TVector LocationMsg::GetChecks() { - mData.Clear(); - -#define X(ID, IDENTIFIER, STR) \ - if (Cmn::CheckMgr::GetInstance().GetCheckState((CheckID)ID)) { \ - mData.PushBack(static_cast(ID)); \ - } - - AP_CHECKS_X_MACRO - -#undef X - - for (int i = 0; i < mData.Size(); i++) { - kiwi::cout << mData[i]; - } - - kiwi::cout << kiwi::endl; - - return mData; -} - -} // namespace Net -} // namespace AP \ No newline at end of file diff --git a/src/Net/msg/LocationMsg.h b/src/Net/msg/LocationMsg.h index a67e3f9..cb104d5 100644 --- a/src/Net/msg/LocationMsg.h +++ b/src/Net/msg/LocationMsg.h @@ -2,8 +2,7 @@ #define APCLIENT_NET_MSG_LOCATION_MSG_H #include -#include "Net/IMessage.h" -#include "Net/NetworkMgr.h" +#include "Net/Define.h" #include @@ -13,29 +12,21 @@ namespace Net { /** * @brief Location message */ -class LocationMsg : public IMessage { +class LocationMsg : public kiwi::ap::IMessage { public: /** * @brief Constructor * * @param rStrm Stream to packet content */ - LocationMsg(kiwi::MemStream& rStrm); + LocationMsg(kiwi::MemStream& /* rStrm */) {} /** - * @brief returns MemStream of all location data + * @brief Gets the type of this message */ - kiwi::TVector GetChecks(); - - /** - * @brief Gets the type of this command - */ - virtual EKind GetKind() const { - return EKind_Location; + virtual u32 GetType() const { + return Define::EMessageType_Location; } - -private: - kiwi::TVector mData; }; } // namespace Net diff --git a/src/Net/msg/PrintMsg.h b/src/Net/msg/PrintMsg.h index 4c69207..54e39c7 100644 --- a/src/Net/msg/PrintMsg.h +++ b/src/Net/msg/PrintMsg.h @@ -2,7 +2,7 @@ #define APCLIENT_NET_MSG_PRINT_MSG_H #include -#include "Net/IMessage.h" +#include "Net/Define.h" #include @@ -12,7 +12,7 @@ namespace Net { /** * @brief Print message */ -class PrintMsg : public IMessage { +class PrintMsg : public kiwi::ap::IMessage { public: /** * @brief Constructor @@ -22,10 +22,10 @@ class PrintMsg : public IMessage { PrintMsg(kiwi::MemStream& rStrm); /** - * @brief Gets the type of this command + * @brief Gets the type of this message */ - virtual EKind GetKind() const { - return EKind_Print; + virtual u32 GetType() const { + return Define::EMessageType_Print; } /**