168 lines
4.5 KiB
C++
168 lines
4.5 KiB
C++
/* -----------------------------------------------------------------------------
|
|
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("<Welcome=<Platform=\"%s\"><Version=\"%s\">>", 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 <char> ((uint)size, (const char *)data));
|
|
else
|
|
Disconnect(peer);
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
void NetworkDebuggerThread::OnPeerConnection(void *peer)
|
|
{
|
|
if (ctl_peer == NULL)
|
|
{
|
|
SetPeerTimeout(peer, TimeoutVeryLong);
|
|
SendString(peer, "<Ident>");
|
|
}
|
|
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, "<EndSession>");
|
|
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();
|
|
}
|
|
//------------------------------------------------------------------------------
|