/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #include "network_debugger_thread.h" #include "network_debugger.h" #include "core/engine.h" #include "metafile/nml.h" #include "log/log.h" using namespace GS::Script; //------------------------------------------------------------------------------ void NetworkDebuggerThread::OnPacketReceived(void *peer, const void *data, size_t size) { using namespace NML; Tag tag; Parser::ParseTag(tag, (char *)data, (char *)data + size); if (ctl_peer == NULL) { if (tag.name == "HelloMonitor") { Tag *client_version = tag.GetTag("Version;"); if (client_version->GetInteger() == 1) { ctl_peer = peer; SendString(peer, String::Format(">", Platform::Get().GetName().c_str(), Core::Version)); ctl.async.QueueMemberCall(&ctl, &NetworkDebugger::OnControllerConnected); connected.Set(1); } } else Disconnect(peer); } else if (ctl_peer == peer) ctl.async.QueueMemberCall(&ctl, &NetworkDebugger::OnControllerPacketReceived, Array ((uint)size, (const char *)data)); else Disconnect(peer); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void NetworkDebuggerThread::OnPeerConnection(void *peer) { if (ctl_peer == NULL) { SetPeerTimeout(peer, TimeoutVeryLong); SendString(peer, ""); } else Disconnect(peer); } void NetworkDebuggerThread::OnConnectionClosed(void *peer) { if (peer == ctl_peer) { ctl.async.QueueMemberCall(&ctl, &NetworkDebugger::OnControllerDisconnected); ctl.async.QueueMemberCall(&ctl, &NetworkDebugger::Kill); ctl_peer = NULL; } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void NetworkDebuggerThread::SendToController(const GS::String &p) { if (ctl_peer) SendString(ctl_peer, p.c_str()); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool NetworkDebuggerThread::OpenServer(const char *address, int port) { if (!Network::Enet::OpenServer(address, port)) return false; String host_address; GetHostAddress(host_address); ctl.async.QueueMemberCall(&ctl, &NetworkDebugger::OnNetworkReady, host_address, port); return true; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ GS::String NetworkDebuggerThread::GetControllerAddress() { String address; if (ctl_peer) GetPeerAddress(ctl_peer, address); return address; } void NetworkDebuggerThread::DisconnectController() { if (ctl_peer) { SendString(ctl_peer, ""); connected.Set(0); } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void NetworkDebuggerThread::Execute() { Thread::SetName("NetworkDebuggerThread"); if (!OpenServer(address, port)) return; for (state.Set(StateWaitingController); state.Get() != StateStop; ) { switch (state.Get()) { case StateWaitingController: if (ctl_peer) state.Set(StateControllerConnected); break; case StateControllerConnected: if (ctl_peer == NULL) state.Set(StateStop); break; // if controller lost, stop debugger } UpdateHost(); while (async.Execute()); Platform::Get().Sleep(1); } DisconnectController(); Close(); connected.Set(0); state.Set(StateStopped); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void NetworkDebuggerThread::Stop() { if (state.Get() != StateStopped) { state.Set(StateStop); while (state.Get() != StateStopped); // spinlock } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ NetworkDebuggerThread::NetworkDebuggerThread(NetworkDebugger &h, const char *a, int p) : ctl(h) { address = a; port = p; ctl_peer = NULL; } NetworkDebuggerThread::~NetworkDebuggerThread() { Stop(); } //------------------------------------------------------------------------------