///---------------------------------------------------------------------------------
/// Join Request
///---------------------------------------------------------------------------------
NETWORK_MESSAGE_DEFINITION_WITH_OPTIONS( MSG_TYPE_JOIN_REQUEST, MO_RELIABLE )
{
    DeveloperConsole::WriteLine( "Join request from " + sender.m_addr.GetAddrStr(), INFO_TEXT_COLOR );

    char* id = nullptr;
    msg.ReadString( id );

    AddConnectionResult result = ACR_DENIED;
    NetworkConnection* conn = sender.m_session->AddConnection( sender.m_addr, std::string( id ), result );

    if (conn && result == ACR_ACCEPTED)
    {

        NetworkMessage acceptMsg( MSG_TYPE_JOIN_ACCEPT );

        uint8_t maxConnections = (uint8_t) sender.m_session->GetMaxConnections();
        acceptMsg.WriteBytes( (void*)&maxConnections, sizeof( maxConnections ) );

        uint8_t connIdx = conn->GetConnectionIndex();
        acceptMsg.WriteBytes( (void*)&connIdx, sizeof( connIdx ) );

        uint8_t hostIdx = 0;
        acceptMsg.WriteBytes( (void*)&hostIdx, sizeof( hostIdx ) );

        std::string hostID = sender.m_session->GetHost()->GetUniqueID();
        acceptMsg.WriteString( hostID.c_str() );

        uint8_t invalidIdx = CONNECTION_INVALID_INDEX;
        acceptMsg.WriteBytes( (void*)&invalidIdx, sizeof( invalidIdx ) );

        conn->AddMessage( acceptMsg );
    }
    else
    {
        uint8_t denyReason;
        NetworkMessage* denyMsg = new NetworkMessage( MSG_TYPE_JOIN_DENY );
        switch (result)
        {
        case ACR_DENIED:
            denyReason = 0;
            break;
        case ACR_FULL:
            denyReason = 1;
            break;
        case ACR_ID_TAKEN:
            denyReason = 2;
            break;
        default:
            break;
        }

        denyMsg->WriteBytes( (void*)&denyReason, sizeof( denyReason ) );
        sender.m_session->SendDirectMessage( denyMsg, &sender.m_addr );
    }
}