* add nlhomann json header

* add get scene app fn

* add get current binding and related logic

* add save binding file to settings folder

* apply binding fn added fixed uid bug

* add button logic to QML, add enable Bind Setting

* add finding logic for all custom bind

* fix minor qml issues

* fix get controllername bug, fix bug with save bind

* fix regex issue

* change webrequest for selectconfig

* change to properly urlify path to send

* fix race condition web requests

* change steamvr tab qml formatting

* change color scheme

* change colors of icons to text color

* change bind qml better for better ux

* add possible workaround for space drag issues

* add deact color to pushbutton

* increment version

* adjust button size in movecenter

* move nlhomann json

* fix PKGBUILD to include missing dependency (#606) (#613)

It turns out qt5-websockets needs to be included for a successful build.

Co-authored-by: James R <71466513+ColdIce1605@users.noreply.github.com>

* fix warning

* improved logging messages around perapp bindings

* improve getsceneappID logging

* add HMD based controller Finding

* improve logging controller name

* change logging around initial chaperone calibration

* increment version

* improve logging/error handling around sceneappid failures

* added fallback for getting scene app by pid

* update version string

* update documentation

Co-authored-by: James R <71466513+ColdIce1605@users.noreply.github.com>
This commit is contained in:
ykeara
2022-07-28 16:44:22 -05:00
committed by GitHub
co-authored by James R
parent 3be11339b9
commit 65b5aace06
102 changed files with 23168 additions and 128 deletions
+21 -3
View File
@@ -1120,9 +1120,21 @@ void MoveCenterTabController::zeroOffsets()
// finished checking if out of bounds, proceed with normal zeroing
// offsets
if ( vr::VRChaperone()->GetCalibrationState()
== vr::ChaperoneCalibrationState_OK )
auto chaperoneState = vr::VRChaperone()->GetCalibrationState();
if ( chaperoneState < vr::ChaperoneCalibrationState_Error
|| m_ignoreChaperoneState )
{
if ( !m_chaperoneInit )
{
m_chaperoneInit = true;
LOG( INFO ) << "Chaperone Initially Calibrated";
}
if ( chaperoneState > vr::ChaperoneCalibrationState_OK )
{
LOG( WARNING )
<< "Chaperone Cal State Is warning during zero offsets: "
<< chaperoneState;
}
m_oldOffsetX = 0.0f;
m_oldOffsetY = 0.0f;
m_oldOffsetZ = 0.0f;
@@ -1180,7 +1192,6 @@ void MoveCenterTabController::zeroOffsets()
}
else
{
LOG( WARNING ) << "Chaperone not calibrated?";
if ( !m_pendingZeroOffsets )
{
LOG( INFO ) << "PENDING: Chaperone Data Update and Offsets zeroing";
@@ -3088,4 +3099,11 @@ void MoveCenterTabController::eventLoopTick(
updateSpace();
}
}
void MoveCenterTabController::setIgnoreChaperoneState()
{
m_ignoreChaperoneState = true;
LOG( INFO ) << "Ignoring Chaperone State for Zero Offsets";
}
} // namespace advsettings
@@ -161,6 +161,7 @@ private:
float m_lastControllerPosition[3];
bool m_heightToggle = false;
float m_gravityFloor = 0.0f;
bool m_ignoreChaperoneState = false;
// Set lastHandQuaternion.w to -1000.0 when last hand is invalid.
vr::HmdQuaternion_t m_lastHandQuaternion
= { k_quaternionInvalidValue, 0.0, 0.0, 0.0 };
@@ -206,6 +207,8 @@ private:
unsigned m_dragComfortFrameSkipCounter = 0;
unsigned m_turnComfortFrameSkipCounter = 0;
bool m_chaperoneInit = true;
// Matrix used For Center Marker
vr::HmdMatrix34_t m_offsetmatrix = utils::k_forwardUpMatrix;
@@ -290,6 +293,7 @@ public:
void saveOffsetProfiles();
Q_INVOKABLE unsigned getOffsetProfileCount();
Q_INVOKABLE QString getOffsetProfileName( unsigned index );
Q_INVOKABLE void setIgnoreChaperoneState();
// actions:
void leftHandSpaceDrag( bool leftHandDragActive );
+347
View File
@@ -628,4 +628,351 @@ std::vector<QString>
return dongleList;
}
// Binding Functions
void SteamVRTabController::getBindingUrlReq( std::string appID )
{
m_lastAppID = appID;
std::string urls
= "http://localhost:27062/input/getactions.json?app_key=" + appID;
QUrl url = QUrl( urls.c_str() );
QNetworkRequest request;
request.setUrl( url );
// This is Important as otherwise Valve's VRWebServerWillIgnore the Request
request.setRawHeader(
QByteArray( "Referer" ),
QByteArray(
"http://localhost:27062/dashboard/controllerbinding.html" ) );
// TODO start Timeout timer?
connect( &m_networkManagerUrl,
SIGNAL( finished( QNetworkReply* ) ),
this,
SLOT( onGetBindingUrlResponse( QNetworkReply* ) ) );
m_networkManagerUrl.get( request );
return;
}
void SteamVRTabController::onGetBindingUrlResponse( QNetworkReply* reply )
{
QString data = QString::fromUtf8( reply->readAll() );
if ( data.size() < 2 )
{
return;
}
std::string controllerName = ovr_system_wrapper::getControllerName();
if ( controllerName == "" )
{
LOG( WARNING ) << "No Controller Detected Skipping Bindings";
return;
}
json jsonfull = json::parse( data.toStdString() );
// LOG( INFO ) << "URL RESPOSNE XXXXXXX";
// LOG( INFO ) << jsonfull.dump().c_str();
std::string filepath
= jsonfull["current_binding_url"][controllerName].get<std::string>();
LOG( INFO ) << "binding url at " << filepath;
// TODO perhaps some form of error checking if packet wrong?
reply->close();
getBindingDataReq( filepath, m_lastAppID, controllerName );
return;
}
void SteamVRTabController::getBindingDataReq( std::string steamURL,
std::string appID,
std::string ctrlType )
{
std::string urls = "http://localhost:27062/input/"
"loadbindingfromurl.json?binding_url="
+ steamURL + "&controller_type=" + ctrlType
+ "&app_key=" + appID;
QUrl url = QUrl( urls.c_str() );
QNetworkRequest request;
request.setUrl( url );
// This is Important as otherwise Valve's VRWebServerWillIgnore the Request
request.setRawHeader(
QByteArray( "Referer" ),
QByteArray(
"http://localhost:27062/dashboard/controllerbinding.html" ) );
// TODO start Timeout timer?
connect( &m_networkManagerBind,
SIGNAL( finished( QNetworkReply* ) ),
this,
SLOT( onGetBindingDataResponse( QNetworkReply* ) ) );
m_networkManagerBind.get( request );
return;
}
void SteamVRTabController::onGetBindingDataResponse( QNetworkReply* reply )
{
json output = "";
QString data = QString::fromUtf8( reply->readAll() );
if ( data.size() < 2 )
{
return;
}
// LOG( WARNING ) << "DATA RESPONSE";
// LOG( WARNING ) << data.toStdString();
json jsonfull = json::parse( data.toStdString() );
if ( !jsonfull.contains( "success" ) )
{
LOG( ERROR ) << "Binding Data Packet Mal-Formed?";
}
if ( !jsonfull["success"].get<bool>() )
{
// TODO better error handling?
LOG( ERROR ) << "Binding Data Request Failed";
}
reply->close();
output = jsonfull["binding_config"];
std::string sceneAppID = ovr_application_wrapper::getSceneAppID();
if ( sceneAppID == "error" )
{
LOG( ERROR ) << "aborting bind save, could not find scene app ID";
return;
}
std::string ctrl = ovr_system_wrapper::getControllerName();
saveBind( m_lastAppID, sceneAppID, ctrl, output, m_setDefault );
return;
}
bool SteamVRTabController::saveBind( std::string appID,
std::string sceneAppID,
std::string ctrlType,
json binds,
bool def )
{
m_setDefault = false;
QFileInfo fi(
QString::fromStdString( settings::initializeAndGetSettingsPath() ) );
QDir directory = fi.absolutePath();
QString Fn;
if ( def )
{
Fn = QString::fromStdString( "defovl" + appID + "ctrl" + ctrlType
+ ".json" );
}
else
{
Fn = QString::fromStdString( "ovl" + appID + "scene" + sceneAppID
+ "ctrl" + ctrlType + ".json" );
}
QString absPath = directory.absolutePath() + "/" + Fn;
QFile bindFile( absPath );
bindFile.open( QIODevice::ReadWrite | QIODevice::Truncate
| QIODevice::Text );
QByteArray qba = binds.dump().c_str();
bindFile.write( qba );
bindFile.flush();
bindFile.close();
if ( bindFile.exists() )
{
LOG( INFO ) << ( def ? "Default " : ( sceneAppID + " " ) )
+ "Binding File saved at:"
<< absPath.toStdString();
std::string jsonstring = binds.dump().c_str();
LOG( INFO ) << jsonstring;
return true;
}
return false;
}
bool SteamVRTabController::customBindExists( std::string appID,
std::string sceneAppID,
std::string ctrl )
{
if ( appID == "" )
{
appID = m_lastAppID;
}
if ( sceneAppID == "" )
{
sceneAppID = ovr_application_wrapper::getSceneAppID();
}
if ( ctrl == "" )
{
ctrl = ovr_system_wrapper::getControllerName();
}
QFileInfo fi( QString::fromStdString(
settings::initializeAndGetSettingsPath() + "ovl" + appID + "scene"
+ sceneAppID + "ctrl" + ctrl + ".json" ) );
if ( fi.exists() )
{
return true;
}
return false;
}
bool SteamVRTabController::defBindExists( std::string appID, std::string ctrl )
{
if ( appID == "" )
{
appID = m_lastAppID;
}
if ( ctrl == "" )
{
ctrl = ovr_system_wrapper::getControllerName();
}
QFileInfo fi( QString::fromStdString(
settings::initializeAndGetSettingsPath() + "defovl" + appID + "ctrl"
+ ctrl + ".json" ) );
if ( fi.exists() )
{
return true;
}
return false;
}
void SteamVRTabController::applyBindingReq( std::string appID )
{
std::string ctrlType = ovr_system_wrapper::getControllerName();
QFileInfo fi(
QString::fromStdString( settings::initializeAndGetSettingsPath() ) );
QDir directory = fi.absolutePath();
QString Fn;
std::string sceneAppID = ovr_application_wrapper::getSceneAppID();
if ( sceneAppID == "" )
{
LOG( ERROR ) << "NO Scene App Detected unable to apply bindings";
return;
}
// TODO check forward slash compatibility with linux
Fn = QString::fromStdString( "ovl" + appID + "scene" + sceneAppID + "ctrl"
+ ctrlType + ".json" );
if ( !QFileInfo::exists( fi.absolutePath() + QString( "/" ) + Fn ) )
{
LOG( INFO ) << "No Specific Binding Detected for: " + appID
+ "for Scene: " + sceneAppID + " Checking Default";
Fn = QString::fromStdString( "defovl" + appID + "ctrl" + ctrlType
+ ".json" );
if ( !QFileInfo::exists( fi.absolutePath() + QString( "/" ) + Fn ) )
{
LOG( INFO ) << "No Def Binding Detected for: " + appID
+ " Not Adjusting Bindings";
return;
}
}
// TODO possible linux compatibility issue
QString absPath = directory.absolutePath() + "/" + Fn;
QUrl urlized = QUrl::fromLocalFile( absPath );
// std::string filePath = "file:///" + absPath.toStdString();
std::string url = "http://localhost:27062/input/selectconfig.action";
// LOG( INFO ) << urlized.toEncoded().toStdString();
QUrl urls = QUrl( url.c_str() );
QNetworkRequest request;
request.setUrl( urls );
LOG( INFO ) << "Attempting to Apply Binding at: "
<< urlized
.toEncoded( QUrl::EncodeSpaces | QUrl::EncodeReserved )
.toStdString();
// This is Important as otherwise Valve's VRWebServerWillIgnore the Request
// If referrer is wrong
request.setHeader( QNetworkRequest::ContentTypeHeader,
"application/x-www-form-urlencoded" );
request.setRawHeader(
QByteArray( "Referer" ),
QByteArray(
"http://localhost:27062/dashboard/controllerbinding.html" ) );
QByteArray data
= ( "{\"app_key\":\"" + appID + "\",\"controller_type\":\"" + ctrlType
+ "\",\"url\":\""
+ urlized.toEncoded( QUrl::EncodeSpaces | QUrl::EncodeReserved )
.toStdString()
+ "\"}" )
.c_str();
// LOG( INFO ) << "Sending Binding Set Request";
// LOG( INFO ) << data.toStdString();
connect( &m_networkManagerApply,
SIGNAL( finished( QNetworkReply* ) ),
this,
SLOT( onApplyBindingResponse( QNetworkReply* ) ) );
m_networkManagerApply.post( request, data );
}
void SteamVRTabController::onApplyBindingResponse( QNetworkReply* reply )
{
json output = "";
QString data = QString::fromUtf8( reply->readAll() );
if ( data.size() < 2 )
{
return;
}
// LOG( INFO ) << "APPLY RESPONSE";
// LOG( INFO ) << data.toStdString();
reply->close();
json jsonfull = json::parse( data.toStdString() );
if ( !jsonfull.contains( "success" ) )
{
LOG( ERROR ) << "Apply Binding Packet Mal-Formed?";
return;
}
if ( !jsonfull["success"].get<bool>() )
{
// TODO better error handling?
LOG( ERROR ) << "Binding Failed To Apply";
}
LOG( INFO ) << "New Binding Applied";
return;
}
void SteamVRTabController::setBindingQMLWrapper( QString appID, bool def )
{
m_setDefault = def;
std::string aID = appID.toStdString();
getBindingUrlReq( aID );
}
bool SteamVRTabController::perAppBindEnabled() const
{
return settings::getSetting(
settings::BoolSetting::STEAMVR_perappBindEnabled );
}
void SteamVRTabController::setPerAppBindEnabled( bool value, bool notify )
{
settings::setSetting( settings::BoolSetting::STEAMVR_perappBindEnabled,
value );
if ( notify )
{
emit perAppBindEnabledChanged( value );
}
}
void SteamVRTabController::applyAllCustomBindings()
{
QFileInfo fi(
QString::fromStdString( settings::initializeAndGetSettingsPath() ) );
QDir directory = fi.absolutePath();
QStringList bindings = directory.entryList( QStringList() << "*.json"
<< "*.JSON",
QDir::Files );
std::set<std::string> appIDs;
std::regex r1( "ovl(.*)scene" );
std::regex r2( "defovl(.*)ctrl" );
foreach ( QString filename, bindings )
{
std::smatch m;
std::string s = filename.toStdString();
if ( regex_search( s, m, r1 ) )
{
if ( m.size() == 2 )
{
appIDs.insert( m[1].str() );
continue;
}
}
if ( regex_search( s, m, r2 ) )
{
if ( m.size() == 2 )
{
appIDs.insert( m[1].str() );
continue;
}
}
}
foreach ( std::string appID, appIDs )
{
applyBindingReq( appID );
}
}
} // namespace advsettings
+46
View File
@@ -4,6 +4,7 @@
#include <QObject>
#include "../utils/FrameRateUtils.h"
#include "../openvr/ovr_settings_wrapper.h"
#include "../openvr/ovr_application_wrapper.h"
#include "../openvr/lh_console_util.h"
#include <QStringListModel>
#include <QTableWidget>
@@ -14,7 +15,13 @@
#include <QtWebSockets/QWebSocket>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include "../../third-party/nlhomann/json.hpp"
#include <QNetworkReply>
#include <set>
#include <regex>
using namespace nlohmann;
class QQuickWindow;
// application namespace
namespace advsettings
@@ -58,6 +65,8 @@ class SteamVRTabController : public QObject
cameraRoomChanged )
Q_PROPERTY( bool cameraDashboard READ cameraDashboard WRITE
setCameraDashboard NOTIFY cameraDashboardChanged )
Q_PROPERTY( bool perAppBindEnabled READ perAppBindEnabled WRITE
setPerAppBindEnabled NOTIFY perAppBindEnabledChanged )
private:
OverlayController* parent;
@@ -67,6 +76,11 @@ private:
bool m_noFadeToGridToggle = false;
bool m_multipleDriverToggle = false;
bool m_dnd = false;
QNetworkAccessManager m_networkManagerApply;
QNetworkAccessManager m_networkManagerUrl;
QNetworkAccessManager m_networkManagerBind;
QNetworkRequest m_networkRequest;
// QNetworkReply* m_networkReply;
bool m_cameraActive = false;
bool m_cameraBounds = false;
@@ -77,6 +91,8 @@ private:
int m_dongleCountMax = 0;
QString m_unparsedDongleString = "";
QString m_last_pair_sn = "";
std::string m_lastAppID = "steam.overlay.1009850";
bool m_setDefault = false;
std::vector<DeviceInfo> m_deviceList;
@@ -85,6 +101,7 @@ private:
void synchSteamVR();
std::vector<QString> getDongleSerialList( std::string deviceString );
bool isSteamVRTracked( QString sn );
void applyBindingReq( std::string appID );
public:
void initStage1();
@@ -106,6 +123,27 @@ public:
QNetworkProxy m_proxy;
QWebSocket m_webSocket;
bool m_adjustBinding = true;
void getBindingUrlReq( std::string appID );
void getBindingDataReq( std::string steamURL,
std::string appID,
std::string ctrlType );
bool customBindExists( std::string appID = "",
std::string sceneAppID = "",
std::string ctrl = "" );
bool defBindExists( std::string appID = "", std::string ctrl = "" );
// void setCustomBind( std::string appID,
// std::string sceneAppID = "",
// std::string ctrl = "" );
bool saveBind( std::string appID,
std::string sceneAppID,
std::string ctrlType,
json binds,
bool def = false );
bool perAppBindEnabled() const;
void applyAllCustomBindings();
Q_INVOKABLE void searchRXTX();
Q_INVOKABLE void launchBindingUI();
@@ -118,6 +156,7 @@ public:
Q_INVOKABLE QString getDongleUsage();
Q_INVOKABLE void pairDevice( QString sn );
Q_INVOKABLE void updateRXTXList();
Q_INVOKABLE void setBindingQMLWrapper( QString appID, bool def = false );
public slots:
void onConnected();
@@ -134,7 +173,12 @@ public slots:
void setCameraRoom( bool value, bool notify = true );
void setCameraDashboard( bool value, bool notify = true );
void setPerAppBindEnabled( bool value, bool notify = true );
void restartSteamVR();
void onGetBindingUrlResponse( QNetworkReply* reply );
void onApplyBindingResponse( QNetworkReply* reply );
void onGetBindingDataResponse( QNetworkReply* reply );
signals:
@@ -151,6 +195,8 @@ signals:
void pairStatusChanged( QString value );
void updateRXTX( bool value );
void perAppBindEnabledChanged( bool value );
};
} // namespace advsettings