142 lines
5.0 KiB
C++
142 lines
5.0 KiB
C++
#include "ClientModule.h"
|
|
|
|
ClientModule::ClientModule(Archimedes::App* a, void* h) : Archimedes::Module(a, h) {
|
|
name = "ClientModule";
|
|
}
|
|
|
|
ClientModule::~ClientModule() {
|
|
if(app) {
|
|
app->unregisterEvent(Archimedes::DataRecievedEvent());
|
|
app->unregisterEvent(Archimedes::DataSentEvent());
|
|
app->unregisterEvent(Archimedes::ConnectionStatusChangedEvent());
|
|
|
|
GameNetworkingSockets_Kill();
|
|
}
|
|
}
|
|
|
|
void ClientModule::onLoad() {
|
|
|
|
app->registerEvent(Archimedes::DataSentEvent());
|
|
app->registerEvent(Archimedes::DataRecievedEvent());
|
|
app->registerEvent(Archimedes::ConnectionStatusChangedEvent());
|
|
|
|
SteamDatagramErrMsg errMsg;
|
|
if ( !GameNetworkingSockets_Init( nullptr, errMsg ) ) {
|
|
//FatalError( "GameNetworkingSockets_Init failed. %s", errMsg );
|
|
std::cerr << "GameNetworkingSockets_Init() Failed: " << errMsg << std::endl;
|
|
}
|
|
|
|
//SteamNetworkingUtils()->SetDebugOutputFunction( k_ESteamNetworkingSocketsDebugOutputType_Msg, DebugOutput );
|
|
|
|
interface = SteamNetworkingSockets();
|
|
|
|
}
|
|
|
|
void ClientModule::startClient(SteamNetworkingIPAddr& serverAddr) {
|
|
if(!running) {
|
|
// Start connecting
|
|
char szAddr[ SteamNetworkingIPAddr::k_cchMaxString ];
|
|
serverAddr.ToString( szAddr, sizeof(szAddr), true );
|
|
std::cerr << "Connecting to chat server at " << szAddr << std::endl;
|
|
SteamNetworkingConfigValue_t opt;
|
|
opt.SetPtr( k_ESteamNetworkingConfig_Callback_ConnectionStatusChanged, (void*)SteamNetConnectionStatusChangedCallback );
|
|
connection = interface->ConnectByIPAddress( serverAddr, 1, &opt );
|
|
if ( connection == k_HSteamNetConnection_Invalid )
|
|
std::cerr << "Failed to create connection\n";
|
|
|
|
running = true;
|
|
}
|
|
}
|
|
|
|
void ClientModule::stopClient() { running = false; }
|
|
|
|
void ClientModule::run() {
|
|
|
|
if(running) {
|
|
pollIncomingData();
|
|
PollConnectionStateChanges();
|
|
}
|
|
}
|
|
|
|
bool ClientModule::onEvent(const Archimedes::Event& event) {
|
|
|
|
unsigned int type = app->getEventType(event);
|
|
|
|
if(eventsToHandle & CMEventEnum::ConnectionStatusChanged && type == app->getEventType(Archimedes::ConnectionStatusChangedEvent())) {
|
|
|
|
Archimedes::ConnectionStatusChangedEvent& e = (Archimedes::ConnectionStatusChangedEvent&) event;
|
|
|
|
switch(e.info->m_info.m_eState) {
|
|
|
|
case k_ESteamNetworkingConnectionState_None:
|
|
// NOTE: We will get callbacks here when we destroy connections. You can ignore these.
|
|
break;
|
|
|
|
case k_ESteamNetworkingConnectionState_ClosedByPeer:
|
|
case k_ESteamNetworkingConnectionState_ProblemDetectedLocally:
|
|
{
|
|
// Ignore if they were not previously connected. (If they disconnected
|
|
// before we accepted the connection.)
|
|
if ( e.info->m_eOldState == k_ESteamNetworkingConnectionState_Connected )
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
assert( e.info->m_eOldState == k_ESteamNetworkingConnectionState_Connecting );
|
|
}
|
|
|
|
// Clean up the connection. This is important!
|
|
// The connection is "closed" in the network sense, but
|
|
// it has not been destroyed. We must close it on our end, too
|
|
// to finish up. The reason information do not matter in this case,
|
|
// and we cannot linger because it's already closed on the other end,
|
|
// so we just pass 0's.
|
|
//
|
|
// OnDisconnect
|
|
interface->CloseConnection( e.info->m_hConn, 0, nullptr, false );
|
|
connection = k_HSteamNetConnection_Invalid;
|
|
stopClient();
|
|
break;
|
|
}
|
|
|
|
case k_ESteamNetworkingConnectionState_Connecting:
|
|
{
|
|
break;
|
|
}
|
|
|
|
case k_ESteamNetworkingConnectionState_Connected:
|
|
//OnConnect
|
|
break;
|
|
|
|
default:
|
|
// Silences -Wswitch
|
|
break;
|
|
}
|
|
return true;
|
|
|
|
} else if(eventsToHandle & CMEventEnum::DataRecieved && type == app->getEventType(Archimedes::DataRecievedEvent())) {
|
|
return true;
|
|
} else if(eventsToHandle & CMEventEnum::DataSent && type == app->getEventType(Archimedes::DataSentEvent())) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void ClientModule::pollIncomingData() {
|
|
|
|
while(running && connection != k_HSteamNetConnection_Invalid) {
|
|
ISteamNetworkingMessage *pIncomingMsg = nullptr;
|
|
int numMsgs = interface->ReceiveMessagesOnConnection( connection, &pIncomingMsg, 1 );
|
|
if ( numMsgs == 0 )
|
|
break;
|
|
if ( numMsgs < 0 )
|
|
std::cerr << "Error checking for messages" << std::endl;
|
|
assert( numMsgs == 1 && pIncomingMsg );
|
|
assert( pIncomingMsg->m_conn == connection );
|
|
|
|
app->emitEvent(new Archimedes::DataRecievedEvent(pIncomingMsg));
|
|
}
|
|
}
|