mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Merge branch 'master' of github.com:highfidelity/hifi into loginscreen-error-page
This commit is contained in:
commit
77a49cb04b
38 changed files with 1733 additions and 1416 deletions
|
@ -74,7 +74,8 @@
|
|||
* avatar. <em>Read-only.</em>
|
||||
* @property {number} sensorToWorldScale - The scale that transforms dimensions in the user's real world to the avatar's
|
||||
* size in the virtual world. <em>Read-only.</em>
|
||||
* @property {boolean} hasPriority - is the avatar in a Hero zone? <em>Read-only.</em>
|
||||
* @property {boolean} hasPriority - <code>true</code> if the avatar is in a "hero" zone, <code>false</code> if it isn't.
|
||||
* <em>Read-only.</em>
|
||||
*
|
||||
* @example <caption>Create a scriptable avatar.</caption>
|
||||
* (function () {
|
||||
|
@ -138,6 +139,9 @@ public:
|
|||
/// Returns the index of the joint with the specified name, or -1 if not found/unknown.
|
||||
Q_INVOKABLE virtual int getJointIndex(const QString& name) const override;
|
||||
|
||||
/**jsdoc
|
||||
* @comment Uses the base class's JSDoc.
|
||||
*/
|
||||
Q_INVOKABLE virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
|
||||
|
||||
/**jsdoc
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1463,7 +1463,7 @@
|
|||
"data": {
|
||||
"alpha": 0.0,
|
||||
"desiredSpeed": 1.4,
|
||||
"characteristicSpeeds": [0.5, 1.8, 2.3, 3.2, 4.5],
|
||||
"characteristicSpeeds": [0.5, 1.8, 2.3, 3.0, 5.0],
|
||||
"alphaVar": "moveForwardAlpha",
|
||||
"desiredSpeedVar": "moveForwardSpeed"
|
||||
},
|
||||
|
@ -1509,8 +1509,8 @@
|
|||
"type": "clip",
|
||||
"data": {
|
||||
"url": "qrc:///avatar/animations/jog_fwd.fbx",
|
||||
"startFrame": 0.0,
|
||||
"endFrame": 25.0,
|
||||
"startFrame": 1.0,
|
||||
"endFrame": 22.0,
|
||||
"timeScale": 1.0,
|
||||
"loopFlag": true
|
||||
},
|
||||
|
@ -1522,7 +1522,7 @@
|
|||
"data": {
|
||||
"url": "qrc:///avatar/animations/run_fwd.fbx",
|
||||
"startFrame": 1.0,
|
||||
"endFrame": 22.0,
|
||||
"endFrame": 23.0,
|
||||
"timeScale": 1.0,
|
||||
"loopFlag": true
|
||||
},
|
||||
|
@ -2099,4 +2099,4 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,16 +14,41 @@ import stylesUit 1.0 as HifiStylesUit
|
|||
import "./audio" as AudioSettings
|
||||
import "./general" as GeneralSettings
|
||||
import "./vr" as VrSettings
|
||||
import "./dev" as DevSettings
|
||||
|
||||
Rectangle {
|
||||
property string activeTabView: "generalTabView"
|
||||
id: root
|
||||
color: simplifiedUI.colors.darkBackground
|
||||
anchors.fill: parent
|
||||
property bool developerModeEnabled: Settings.getValue("simplifiedUI/developerModeEnabled", false)
|
||||
|
||||
SimplifiedConstants.SimplifiedConstants {
|
||||
id: simplifiedUI
|
||||
}
|
||||
|
||||
focus: true
|
||||
Keys.onPressed: {
|
||||
if ((event.key == Qt.Key_D) && (event.modifiers & Qt.ControlModifier && event.modifiers & Qt.AltModifier && event.modifiers & Qt.ShiftModifier)) {
|
||||
var currentSetting = Settings.getValue("simplifiedUI/developerModeEnabled", false);
|
||||
var newSetting = !currentSetting;
|
||||
Settings.setValue("simplifiedUI/developerModeEnabled", newSetting);
|
||||
root.developerModeEnabled = newSetting;
|
||||
if (newSetting) {
|
||||
console.log("Developer mode ON. You are now a developer!");
|
||||
} else {
|
||||
console.log("Developer mode OFF.");
|
||||
if (root.activeTabView === "devTabView") {
|
||||
tabListView.currentIndex = 2;
|
||||
root.activeTabView = "vrTabView";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.forceActiveFocus();
|
||||
}
|
||||
|
||||
|
||||
Rectangle {
|
||||
|
@ -49,6 +74,10 @@ Rectangle {
|
|||
tabTitle: "VR"
|
||||
tabViewName: "vrTabView"
|
||||
}
|
||||
ListElement {
|
||||
tabTitle: "Dev"
|
||||
tabViewName: "devTabView"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,6 +99,8 @@ Rectangle {
|
|||
highlight: highlightBar
|
||||
interactive: contentItem.width > width
|
||||
delegate: Item {
|
||||
visible: model.tabTitle !== "Dev" || (model.tabTitle === "Dev" && root.developerModeEnabled)
|
||||
|
||||
width: tabTitleText.paintedWidth + 64
|
||||
height: parent.height
|
||||
|
||||
|
@ -125,6 +156,12 @@ Rectangle {
|
|||
visible: activeTabView === "vrTabView"
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
DevSettings.Dev {
|
||||
id: devTabViewContainer
|
||||
visible: activeTabView === "devTabView"
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
//
|
||||
// Dev.qml
|
||||
//
|
||||
// Created by Zach Fox on 2019-06-11
|
||||
// Copyright 2019 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
import "../../simplifiedConstants" as SimplifiedConstants
|
||||
import "../../simplifiedControls" as SimplifiedControls
|
||||
import stylesUit 1.0 as HifiStylesUit
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
Flickable {
|
||||
id: root
|
||||
contentWidth: parent.width
|
||||
contentHeight: devColumnLayout.height
|
||||
topMargin: 24
|
||||
bottomMargin: 24
|
||||
clip: true
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
root.contentX = 0;
|
||||
root.contentY = -root.topMargin;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SimplifiedConstants.SimplifiedConstants {
|
||||
id: simplifiedUI
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: devColumnLayout
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
spacing: simplifiedUI.margins.settings.spacingBetweenSettings
|
||||
|
||||
ColumnLayout {
|
||||
id: uiControlsContainer
|
||||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
id: uiControlsTitle
|
||||
text: "User Interface"
|
||||
Layout.maximumWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 22
|
||||
color: simplifiedUI.colors.text.white
|
||||
}
|
||||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
id: uiControlsSubtitle
|
||||
text: "You'll have to restart Interface after changing either of these settings. If you don't get any Toolbar apps back after restarting, run defaultScripts.js manually."
|
||||
Layout.maximumWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 16
|
||||
color: simplifiedUI.colors.text.white
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: uiControlsSwitchGroup
|
||||
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
|
||||
|
||||
SimplifiedControls.Switch {
|
||||
id: keepMenusSwitch
|
||||
width: parent.width
|
||||
height: 18
|
||||
labelTextOn: "Keep Old Menus (File, Edit, etc)"
|
||||
checked: Settings.getValue("simplifiedUI/keepMenus", false);
|
||||
onClicked: {
|
||||
Settings.setValue("simplifiedUI/keepMenus", !Settings.getValue("simplifiedUI/keepMenus", false));
|
||||
}
|
||||
}
|
||||
|
||||
SimplifiedControls.Switch {
|
||||
id: keepOldUIAndScriptsSwitch
|
||||
width: parent.width
|
||||
height: 18
|
||||
labelTextOn: "Keep Old UI and Scripts"
|
||||
checked: Settings.getValue("simplifiedUI/keepExistingUIAndScripts", false);
|
||||
onClicked: {
|
||||
Settings.setValue("simplifiedUI/keepExistingUIAndScripts", !Settings.getValue("simplifiedUI/keepExistingUIAndScripts", false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -101,7 +101,7 @@ Flickable {
|
|||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
id: performanceTitle
|
||||
text: "Graphics Preset"
|
||||
text: "Graphics Settings"
|
||||
Layout.maximumWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 22
|
||||
|
@ -115,7 +115,7 @@ Flickable {
|
|||
|
||||
SimplifiedControls.RadioButton {
|
||||
id: performanceLow
|
||||
text: "Low"
|
||||
text: "Low Quality" + (PlatformInfo.getTierProfiled() === PerformanceEnums.LOW ? " (Recommended)" : "")
|
||||
checked: Performance.getPerformancePreset() === PerformanceEnums.LOW
|
||||
onClicked: {
|
||||
Performance.setPerformancePreset(PerformanceEnums.LOW);
|
||||
|
@ -124,7 +124,7 @@ Flickable {
|
|||
|
||||
SimplifiedControls.RadioButton {
|
||||
id: performanceMedium
|
||||
text: "Medium"
|
||||
text: "Medium Quality" + (PlatformInfo.getTierProfiled() === PerformanceEnums.MID ? " (Recommended)" : "")
|
||||
checked: Performance.getPerformancePreset() === PerformanceEnums.MID
|
||||
onClicked: {
|
||||
Performance.setPerformancePreset(PerformanceEnums.MID);
|
||||
|
@ -133,7 +133,7 @@ Flickable {
|
|||
|
||||
SimplifiedControls.RadioButton {
|
||||
id: performanceHigh
|
||||
text: "High"
|
||||
text: "High Quality" + (PlatformInfo.getTierProfiled() === PerformanceEnums.HIGH ? " (Recommended)" : "")
|
||||
checked: Performance.getPerformancePreset() === PerformanceEnums.HIGH
|
||||
onClicked: {
|
||||
Performance.setPerformancePreset(PerformanceEnums.HIGH);
|
||||
|
|
|
@ -18,6 +18,16 @@ import "qrc:////qml//hifi//models" as HifiModels // Absolute path so the same c
|
|||
|
||||
Rectangle {
|
||||
id: root
|
||||
focus: true
|
||||
|
||||
signal keyPressEvent(int key, int modifiers)
|
||||
Keys.onPressed: {
|
||||
keyPressEvent(event.key, event.modifiers);
|
||||
}
|
||||
signal keyReleaseEvent(int key, int modifiers)
|
||||
Keys.onReleased: {
|
||||
keyReleaseEvent(event.key, event.modifiers);
|
||||
}
|
||||
|
||||
SimplifiedConstants.SimplifiedConstants {
|
||||
id: simplifiedUI
|
||||
|
@ -83,6 +93,12 @@ Rectangle {
|
|||
topBarInventoryModel.getNextPage();
|
||||
} else {
|
||||
inventoryFullyReceived = true;
|
||||
|
||||
// If we have an avatar in our inventory AND we haven't already auto-selected an avatar...
|
||||
if (!Settings.getValue("simplifiedUI/alreadyAutoSelectedAvatar", false) && topBarInventoryModel.count > 0) {
|
||||
Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatar", true);
|
||||
MyAvatar.skeletonModelURL = topBarInventoryModel.get(0).download_url;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -455,5 +471,5 @@ Rectangle {
|
|||
break;
|
||||
}
|
||||
}
|
||||
signal sendToScript(var message);
|
||||
signal sendToScript(var message)
|
||||
}
|
||||
|
|
|
@ -950,6 +950,19 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
|||
DependencyManager::set<GrabManager>();
|
||||
DependencyManager::set<AvatarPackager>();
|
||||
|
||||
QString setBookmarkValue = getCmdOption(argc, constArgv, "--setBookmark");
|
||||
if (!setBookmarkValue.isEmpty()) {
|
||||
// Bookmarks are expected to be in a name=url form.
|
||||
// An `=` character in the name or url is unsupported.
|
||||
auto parts = setBookmarkValue.split("=");
|
||||
if (parts.length() != 2) {
|
||||
qWarning() << "Malformed setBookmark argument: " << setBookmarkValue;
|
||||
} else {
|
||||
qDebug() << "Setting bookmark" << parts[0] << "to" << parts[1];
|
||||
DependencyManager::get<LocationBookmarks>()->insert(parts[0], parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return previousSessionCrashed;
|
||||
}
|
||||
|
||||
|
@ -5611,7 +5624,7 @@ void Application::resumeAfterLoginDialogActionTaken() {
|
|||
scriptEngines->reloadLocalFiles();
|
||||
|
||||
// if the --scripts command-line argument was used.
|
||||
if (!_defaultScriptsLocation.exists() && (arguments().indexOf(QString("--").append(SCRIPTS_SWITCH))) != -1) {
|
||||
if (_defaultScriptsLocation.exists() && (arguments().indexOf(QString("--").append(SCRIPTS_SWITCH))) != -1) {
|
||||
scriptEngines->loadDefaultScripts();
|
||||
scriptEngines->defaultScriptsLocationOverridden(true);
|
||||
} else {
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
Bookmarks();
|
||||
|
||||
virtual void setupMenus(Menu* menubar, MenuWrapper* menu) = 0;
|
||||
void insert(const QString& name, const QVariant& address); // Overwrites any existing entry with same name.
|
||||
QString addressForBookmark(const QString& name) const;
|
||||
|
||||
protected:
|
||||
|
@ -37,7 +38,6 @@ protected:
|
|||
virtual void addBookmarkToMenu(Menu* menubar, const QString& name, const QVariant& bookmark) = 0;
|
||||
void enableMenuItems(bool enabled);
|
||||
virtual void readFromFile();
|
||||
void insert(const QString& name, const QVariant& address); // Overwrites any existing entry with same name.
|
||||
void sortActions(Menu* menubar, MenuWrapper* menu);
|
||||
int getMenuItemLocation(QList<QAction*> actions, const QString& name) const;
|
||||
void removeBookmarkFromMenu(Menu* menubar, const QString& name);
|
||||
|
|
|
@ -67,6 +67,10 @@ QString LocationBookmarks::getHomeLocationAddress() {
|
|||
return addressForBookmark(HOME_BOOKMARK);
|
||||
}
|
||||
|
||||
QString LocationBookmarks::getAddress(const QString& bookmarkName) {
|
||||
return addressForBookmark(bookmarkName);
|
||||
}
|
||||
|
||||
void LocationBookmarks::teleportToBookmark() {
|
||||
QAction* action = qobject_cast<QAction*>(sender());
|
||||
QString address = action->data().toString();
|
||||
|
|
|
@ -34,6 +34,13 @@ public:
|
|||
void setupMenus(Menu* menubar, MenuWrapper* menu) override;
|
||||
static const QString HOME_BOOKMARK;
|
||||
|
||||
/**jsdoc
|
||||
* @function LocationBookmarks.getAddress
|
||||
* @param {string} bookmarkName Name of the bookmark to get the address for.
|
||||
* @returns {string} The url for the specified bookmark. If the bookmark does not exist, the empty string will be returned.
|
||||
*/
|
||||
Q_INVOKABLE QString getAddress(const QString& bookmarkName);
|
||||
|
||||
public slots:
|
||||
|
||||
/**jsdoc
|
||||
|
@ -48,7 +55,7 @@ public slots:
|
|||
void setHomeLocationToAddress(const QVariant& address);
|
||||
|
||||
/**jsdoc
|
||||
* @function LocationBookmarksgetHomeLocationAddress
|
||||
* @function LocationBookmarks.getHomeLocationAddress
|
||||
* @returns {string} The url for the home location bookmark
|
||||
*/
|
||||
QString getHomeLocationAddress();
|
||||
|
|
|
@ -2488,12 +2488,12 @@ QVariantList MyAvatar::getAvatarEntitiesVariant() {
|
|||
QVariantMap avatarEntityData;
|
||||
avatarEntityData["id"] = entityID;
|
||||
EntityItemProperties entityProperties = entity->getProperties(desiredProperties);
|
||||
QScriptValue scriptProperties;
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(_scriptEngineLock);
|
||||
QScriptValue scriptProperties;
|
||||
scriptProperties = EntityItemPropertiesToScriptValue(_scriptEngine, entityProperties);
|
||||
avatarEntityData["properties"] = scriptProperties.toVariant();
|
||||
}
|
||||
avatarEntityData["properties"] = scriptProperties.toVariant();
|
||||
avatarEntitiesData.append(QVariant(avatarEntityData));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,23 @@ class ModelItemID;
|
|||
class MyHead;
|
||||
class DetailedMotionState;
|
||||
|
||||
/**jsdoc
|
||||
* <p>Locomotion control types.</p>
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Value</th><th>Name</th><th>Description</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><td><code>0</code></td><td>Default</td><td>Your walking speed is constant; it doesn't change depending on how far
|
||||
* forward you push your controller's joystick. Fully pushing your joystick forward makes your avatar run.</td></tr>
|
||||
* <tr><td><code>1</code></td><td>Analog</td><td>Your walking speed changes in steps based on how far forward you push your
|
||||
* controller's joystick. Fully pushing your joystick forward makes your avatar run.</td></tr>
|
||||
* <tr><td><code>2</code></td><td>AnalogPlus</td><td>Your walking speed changes proportionally to how far forward you push
|
||||
* your controller's joystick. Fully pushing your joystick forward makes your avatar run.</td></tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* @typedef {number} MyAvatar.LocomotionControlsMode
|
||||
*/
|
||||
enum LocomotionControlsMode {
|
||||
CONTROLS_DEFAULT = 0,
|
||||
CONTROLS_ANALOG,
|
||||
|
@ -128,6 +145,8 @@ class MyAvatar : public Avatar {
|
|||
* avatar. <em>Read-only.</em>
|
||||
* @property {number} sensorToWorldScale - The scale that transforms dimensions in the user's real world to the avatar's
|
||||
* size in the virtual world. <em>Read-only.</em>
|
||||
* @property {boolean} hasPriority - <code>true</code> if the avatar is in a "hero" zone, <code>false</code> if it isn't.
|
||||
* <em>Read-only.</em>
|
||||
*
|
||||
* @comment IMPORTANT: This group of properties is copied from Avatar.h; they should NOT be edited here.
|
||||
* @property {Vec3} skeletonOffset - Can be used to apply a translation offset between the avatar's position and the
|
||||
|
@ -239,9 +258,16 @@ class MyAvatar : public Avatar {
|
|||
* where MyAvatar.sessionUUID is not available (e.g., if not connected to a domain). Note: Likely to be deprecated.
|
||||
* <em>Read-only.</em>
|
||||
*
|
||||
* @property {number} walkSpeed - The walk speed of your avatar.
|
||||
* @property {number} walkBackwardSpeed - The walk backward speed of your avatar.
|
||||
* @property {number} sprintSpeed - The sprint speed of your avatar.
|
||||
* @property {number} walkSpeed - The walk speed of your avatar for the current control scheme (see
|
||||
* {@link MyAvatar.getControlScheme|getControlScheme}).
|
||||
* @property {number} walkBackwardSpeed - The walk backward speed of your avatar for the current control scheme (see
|
||||
* {@link MyAvatar.getControlScheme|getControlScheme}).
|
||||
* @property {number} sprintSpeed - The sprint (run) speed of your avatar for the current control scheme (see
|
||||
* {@link MyAvatar.getControlScheme|getControlScheme}).
|
||||
* @property {number} analogPlusWalkSpeed - The walk speed of your avatar for the "AnalogPlus" control scheme.
|
||||
* <p><strong>Warning:</strong> Setting this value also sets the value of <code>analogPlusSprintSpeed</code> to twice
|
||||
* the value.</p>
|
||||
* @property {number} analogPlusSprintSpeed - The sprint speed of your avatar for the "AnalogPlus" control scheme.
|
||||
* @property {MyAvatar.SitStandModelType} userRecenterModel - Controls avatar leaning and recentering behavior.
|
||||
* @property {number} isInSittingState - <code>true</code> if your avatar is sitting (avatar leaning is disabled,
|
||||
* recenntering is enabled), <code>false</code> if it is standing (avatar leaning is enabled, and avatar recenters if it
|
||||
|
@ -281,6 +307,7 @@ class MyAvatar : public Avatar {
|
|||
* @borrows Avatar.updateAvatarEntity as updateAvatarEntity
|
||||
* @borrows Avatar.clearAvatarEntity as clearAvatarEntity
|
||||
* @borrows Avatar.setForceFaceTrackerConnected as setForceFaceTrackerConnected
|
||||
* @borrows Avatar.setSkeletonModelURL as setSkeletonModelURL
|
||||
* @borrows Avatar.getAttachmentData as getAttachmentData
|
||||
* @borrows Avatar.setAttachmentData as setAttachmentData
|
||||
* @borrows Avatar.attach as attach
|
||||
|
@ -308,7 +335,6 @@ class MyAvatar : public Avatar {
|
|||
* @comment Avatar.setAbsoluteJointTranslationInObjectFrame as setAbsoluteJointTranslationInObjectFrame - Don't borrow because implementation is different.
|
||||
* @borrows Avatar.getTargetScale as getTargetScale
|
||||
* @borrows Avatar.resetLastSent as resetLastSent
|
||||
* @borrows Avatar.hasPriority as hasPriority
|
||||
*/
|
||||
// FIXME: `glm::vec3 position` is not accessible from QML, so this exposes position in a QML-native type
|
||||
Q_PROPERTY(QVector3D qmlPosition READ getQmlPosition)
|
||||
|
@ -583,14 +609,13 @@ public:
|
|||
* the avatar will move in unpredictable ways. For more information about avatar joint orientation standards, see
|
||||
* <a href="https://docs.highfidelity.com/create/avatars/avatar-standards">Avatar Standards</a>.</p>
|
||||
* @function MyAvatar.overrideAnimation
|
||||
* @param url {string} The URL to the animation file. Animation files need to be FBX format, but only need to contain the
|
||||
* @param {string} url - The URL to the animation file. Animation files need to be FBX format, but only need to contain the
|
||||
* avatar skeleton and animation data.
|
||||
* @param fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
|
||||
* @param loop {boolean} Set to true if the animation should loop.
|
||||
* @param firstFrame {number} The frame the animation should start at.
|
||||
* @param lastFrame {number} The frame the animation should end at.
|
||||
* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
|
||||
* @param {boolean} loop - <code>true</code> if the animation should loop, <code>false</code> if it shouldn't.
|
||||
* @param {number} firstFrame - The frame to start the animation at.
|
||||
* @param {number} lastFrame - The frame to end the animation at.
|
||||
* @example <caption> Play a clapping animation on your avatar for three seconds. </caption>
|
||||
* // Clap your hands for 3 seconds then restore animation back to the avatar.
|
||||
* var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
|
||||
* MyAvatar.overrideAnimation(ANIM_URL, 30, true, 0, 53);
|
||||
* Script.setTimeout(function () {
|
||||
|
@ -601,18 +626,18 @@ public:
|
|||
Q_INVOKABLE void overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
|
||||
|
||||
/**jsdoc
|
||||
* <code>overrideHandAnimation()</code> Gets the overrides the default hand poses that are triggered with controller buttons.
|
||||
* use {@link MyAvatar.restoreHandAnimation}.</p> to restore the default poses.
|
||||
* Overrides the default hand poses that are triggered with controller buttons.
|
||||
* Use {@link MyAvatar.restoreHandAnimation} to restore the default poses.
|
||||
* @function MyAvatar.overrideHandAnimation
|
||||
* @param isLeft {boolean} Set true if using the left hand
|
||||
* @param url {string} The URL to the animation file. Animation files need to be FBX format, but only need to contain the
|
||||
* @param isLeft {boolean} <code>true</code> to override the left hand, <code>false</code> to override the right hand.
|
||||
* @param {string} url - The URL of the animation file. Animation files need to be FBX format, but only need to contain the
|
||||
* avatar skeleton and animation data.
|
||||
* @param fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
|
||||
* @param loop {boolean} Set to true if the animation should loop.
|
||||
* @param firstFrame {number} The frame the animation should start at.
|
||||
* @param lastFrame {number} The frame the animation should end at
|
||||
* @example <caption> Override left hand animation for three seconds. </caption>
|
||||
* // Override the left hand pose then restore the default pose.
|
||||
* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
|
||||
* @param {boolean} loop - <code>true</code> if the animation should loop, <code>false</code> if it shouldn't.
|
||||
* @param {number} firstFrame - The frame to start the animation at.
|
||||
* @param {number} lastFrame - The frame to end the animation at.
|
||||
* @example <caption> Override left hand animation for three seconds.</caption>
|
||||
* var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
|
||||
* MyAvatar.overrideHandAnimation(isLeft, ANIM_URL, 30, true, 0, 53);
|
||||
* Script.setTimeout(function () {
|
||||
* MyAvatar.restoreHandAnimation();
|
||||
|
@ -629,7 +654,6 @@ public:
|
|||
* animation, this function has no effect.</p>
|
||||
* @function MyAvatar.restoreAnimation
|
||||
* @example <caption> Play a clapping animation on your avatar for three seconds. </caption>
|
||||
* // Clap your hands for 3 seconds then restore animation back to the avatar.
|
||||
* var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
|
||||
* MyAvatar.overrideAnimation(ANIM_URL, 30, true, 0, 53);
|
||||
* Script.setTimeout(function () {
|
||||
|
@ -639,16 +663,15 @@ public:
|
|||
Q_INVOKABLE void restoreAnimation();
|
||||
|
||||
/**jsdoc
|
||||
* Restores the default hand animation state machine that is driven by the state machine in the avatar-animation json.
|
||||
* Restores the default hand animation state machine that is driven by the state machine in the avatar-animation JSON.
|
||||
* <p>The avatar animation system includes a set of default animations along with rules for how those animations are blended
|
||||
* together with procedural data (such as look at vectors, hand sensors etc.). Playing your own custom animations will
|
||||
* override the default animations. <code>restoreHandAnimation()</code> is used to restore the default hand poses
|
||||
* If you aren't currently playing an override hand
|
||||
* animation, this function has no effect.</p>
|
||||
* override the default animations. <code>restoreHandAnimation()</code> is used to restore the default hand poses.
|
||||
* If you aren't currently playing an override hand animation, this function has no effect.</p>
|
||||
* @function MyAvatar.restoreHandAnimation
|
||||
* @param isLeft {boolean} Set to true if using the left hand
|
||||
* @example <caption> Override left hand animation for three seconds. </caption>
|
||||
* // Override the left hand pose then restore the default pose.
|
||||
* var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
|
||||
* MyAvatar.overrideHandAnimation(isLeft, ANIM_URL, 30, true, 0, 53);
|
||||
* Script.setTimeout(function () {
|
||||
* MyAvatar.restoreHandAnimation();
|
||||
|
@ -689,12 +712,13 @@ public:
|
|||
* the avatar will move in unpredictable ways. For more information about avatar joint orientation standards, see
|
||||
* <a href="https://docs.highfidelity.com/create/avatars/avatar-standards">Avatar Standards</a>.
|
||||
* @function MyAvatar.overrideRoleAnimation
|
||||
* @param role {string} The animation role to override
|
||||
* @param url {string} The URL to the animation file. Animation files need to be in FBX format, but only need to contain the avatar skeleton and animation data.
|
||||
* @param fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
|
||||
* @param loop {boolean} Set to true if the animation should loop
|
||||
* @param firstFrame {number} The frame the animation should start at
|
||||
* @param lastFrame {number} The frame the animation should end at
|
||||
* @param {string} role - The animation role to override
|
||||
* @param {string} url - The URL to the animation file. Animation files need to be in FBX format, but only need to contain
|
||||
* the avatar skeleton and animation data.
|
||||
* @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
|
||||
* @param {boolean} loop - <code>true</code> if the animation should loop, <code>false</code> if it shouldn't.
|
||||
* @param {number} firstFrame - The frame the animation should start at.
|
||||
* @param {number} lastFrame - The frame the animation should end at.
|
||||
* @example <caption>The default avatar-animation.json defines an "idleStand" animation role. This role specifies that when the avatar is not moving,
|
||||
* an animation clip of the avatar idling with hands hanging at its side will be used. It also specifies that when the avatar moves, the animation
|
||||
* will smoothly blend to the walking animation used by the "walkFwd" animation role.
|
||||
|
@ -782,33 +806,42 @@ public:
|
|||
* mode.
|
||||
*/
|
||||
Q_INVOKABLE bool getSnapTurn() const { return _useSnapTurn; }
|
||||
|
||||
/**jsdoc
|
||||
* Sets whether your should do snap turns or smooth turns in HMD mode.
|
||||
* Sets whether you do snap turns or smooth turns in HMD mode.
|
||||
* @function MyAvatar.setSnapTurn
|
||||
* @param {boolean} on - <code>true</code> to do snap turns in HMD mode; <code>false</code> to do smooth turns in HMD mode.
|
||||
*/
|
||||
Q_INVOKABLE void setSnapTurn(bool on) { _useSnapTurn = on; }
|
||||
|
||||
/**
|
||||
/**jsdoc
|
||||
* Gets the control scheme that is in use.
|
||||
* @function MyAvatar.getControlScheme
|
||||
* @returns {number}
|
||||
*/
|
||||
* @returns {MyAvatar.LocomotionControlsMode} The control scheme that is in use.
|
||||
*/
|
||||
Q_INVOKABLE int getControlScheme() const { return _controlSchemeIndex; }
|
||||
|
||||
/**
|
||||
/**jsdoc
|
||||
* Sets the control scheme to use.
|
||||
* @function MyAvatar.setControlScheme
|
||||
* @param {number} index
|
||||
*/
|
||||
* @param {MyAvatar.LocomotionControlsMode} controlScheme - The control scheme to use.
|
||||
*/
|
||||
Q_INVOKABLE void setControlScheme(int index) { _controlSchemeIndex = (index >= 0 && index <= 2) ? index : 0; }
|
||||
|
||||
/**jsdoc
|
||||
* Gets whether your avatar hovers when its feet are not on the ground.
|
||||
* @function MyAvatar.hoverWhenUnsupported
|
||||
* @returns {boolean}
|
||||
* @returns {boolean} <code>true</code> if your avatar hovers when its feet are not on the ground, <code>false</code> if it
|
||||
* falls.
|
||||
*/
|
||||
// FIXME: Should be named, getHoverWhenUnsupported().
|
||||
Q_INVOKABLE bool hoverWhenUnsupported() const { return _hoverWhenUnsupported; }
|
||||
|
||||
/**jsdoc
|
||||
* Sets whether your avatar hovers when its feet are not on the ground.
|
||||
* @function MyAvatar.setHoverWhenUnsupported
|
||||
* @param {boolean} on
|
||||
* @param {boolean} hover - <code>true</code> if your avatar hovers when its feet are not on the ground, <code>false</code>
|
||||
* if it falls.
|
||||
*/
|
||||
Q_INVOKABLE void setHoverWhenUnsupported(bool on) { _hoverWhenUnsupported = on; }
|
||||
|
||||
|
@ -826,26 +859,31 @@ public:
|
|||
* @returns {string} <code>"left"</code> for the left hand, <code>"right"</code> for the right hand.
|
||||
*/
|
||||
Q_INVOKABLE QString getDominantHand() const;
|
||||
|
||||
/**jsdoc
|
||||
* @function MyAVatar.setStrafeEnabled
|
||||
* @param {bool} enabled
|
||||
*/
|
||||
* Sets whether strafing is enabled.
|
||||
* @function MyAvatar.setStrafeEnabled
|
||||
* @param {boolean} enabled - <code>true</code> if strafing is enabled, <code>false</code> if it isn't.
|
||||
*/
|
||||
Q_INVOKABLE void setStrafeEnabled(bool enabled);
|
||||
|
||||
/**jsdoc
|
||||
* @function MyAvatar.getStrafeEnabled
|
||||
* @returns {bool}
|
||||
*/
|
||||
* Gets whether strafing is enabled.
|
||||
* @function MyAvatar.getStrafeEnabled
|
||||
* @returns {boolean} <code>true</code> if strafing is enabled, <code>false</code> if it isn't.
|
||||
*/
|
||||
Q_INVOKABLE bool getStrafeEnabled() const;
|
||||
|
||||
/**jsdoc
|
||||
* Sets the HMD alignment relative to your avatar.
|
||||
* @function MyAvatar.setHmdAvatarAlignmentType
|
||||
* @param {string} type - <code>"head"</code> to align your head and your avatar's head, <code>"eyes"</code> to align your
|
||||
* eyes and your avatar's eyes.
|
||||
*
|
||||
*/
|
||||
Q_INVOKABLE void setHmdAvatarAlignmentType(const QString& type);
|
||||
|
||||
/**jsdoc
|
||||
* Gets the HMD alignment for your avatar.
|
||||
* Gets the HMD alignment relative to your avatar.
|
||||
* @function MyAvatar.getHmdAvatarAlignmentType
|
||||
* @returns {string} <code>"head"</code> if aligning your head and your avatar's head, <code>"eyes"</code> if aligning your
|
||||
* eyes and your avatar's eyes.
|
||||
|
@ -1495,18 +1533,8 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE float getDriveGear5();
|
||||
|
||||
/**jsdoc
|
||||
* Choose the control scheme.
|
||||
* @function MyAvatar.setControlSchemeIndex
|
||||
* @param {number} Choose the control scheme to be used.
|
||||
*/
|
||||
void setControlSchemeIndex(int index);
|
||||
|
||||
/**jsdoc
|
||||
* Check what control scheme is in use.
|
||||
* @function MyAvatar.getControlSchemeIndex
|
||||
* @returns {number} Returns the index associated with a given control scheme.
|
||||
*/
|
||||
int getControlSchemeIndex();
|
||||
|
||||
/**jsdoc
|
||||
|
@ -1584,8 +1612,8 @@ public:
|
|||
Q_INVOKABLE bool getCharacterControllerEnabled(); // deprecated
|
||||
|
||||
/**jsdoc
|
||||
* @comment Different behavior to the Avatar version of this method.
|
||||
* Gets the rotation of a joint relative to the avatar.
|
||||
* @comment Different behavior to the Avatar version of this method.
|
||||
* @function MyAvatar.getAbsoluteJointRotationInObjectFrame
|
||||
* @param {number} index - The index of the joint.
|
||||
* @returns {Quat} The rotation of the joint relative to the avatar.
|
||||
|
@ -1597,8 +1625,8 @@ public:
|
|||
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override;
|
||||
|
||||
/**jsdoc
|
||||
* @comment Different behavior to the Avatar version of this method.
|
||||
* Gets the translation of a joint relative to the avatar.
|
||||
* @comment Different behavior to the Avatar version of this method.
|
||||
* @function MyAvatar.getAbsoluteJointTranslationInObjectFrame
|
||||
* @param {number} index - The index of the joint.
|
||||
* @returns {Vec3} The translation of the joint relative to the avatar.
|
||||
|
@ -2441,6 +2469,9 @@ private:
|
|||
void updateEyeContactTarget(float deltaTime);
|
||||
|
||||
// These are made private for MyAvatar so that you will use the "use" methods instead
|
||||
/**jsdoc
|
||||
* @comment Borrows the base class's JSDoc.
|
||||
*/
|
||||
Q_INVOKABLE virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
|
||||
|
||||
virtual void updatePalms() override {}
|
||||
|
|
|
@ -132,6 +132,10 @@ static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SI
|
|||
|
||||
bool GraphicsEngine::shouldPaint() const {
|
||||
auto displayPlugin = qApp->getActiveDisplayPlugin();
|
||||
if (!displayPlugin) {
|
||||
// We're shutting down
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PAINT_DELAY
|
||||
static uint64_t paintDelaySamples{ 0 };
|
||||
|
@ -175,6 +179,10 @@ void GraphicsEngine::render_performFrame() {
|
|||
{
|
||||
PROFILE_RANGE(render, "/getActiveDisplayPlugin");
|
||||
displayPlugin = qApp->getActiveDisplayPlugin();
|
||||
if (!displayPlugin) {
|
||||
// We're shutting down
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -85,6 +85,7 @@ int main(int argc, const char* argv[]) {
|
|||
QCommandLineOption overrideScriptsPathOption(SCRIPTS_SWITCH, "set scripts <path>", "path");
|
||||
QCommandLineOption responseTokensOption("tokens", "set response tokens <json>", "json");
|
||||
QCommandLineOption displayNameOption("displayName", "set user display name <string>", "string");
|
||||
QCommandLineOption setBookmarkOption("setBookmark", "set bookmark key=value pair", "string");
|
||||
|
||||
parser.addOption(urlOption);
|
||||
parser.addOption(noLauncherOption);
|
||||
|
@ -97,6 +98,7 @@ int main(int argc, const char* argv[]) {
|
|||
parser.addOption(allowMultipleInstancesOption);
|
||||
parser.addOption(responseTokensOption);
|
||||
parser.addOption(displayNameOption);
|
||||
parser.addOption(setBookmarkOption);
|
||||
|
||||
if (!parser.parse(arguments)) {
|
||||
std::cout << parser.errorText().toStdString() << std::endl; // Avoid Qt log spam
|
||||
|
|
|
@ -68,6 +68,16 @@ void interactiveWindowPointerFromScriptValue(const QScriptValue& object, Interac
|
|||
}
|
||||
}
|
||||
|
||||
void InteractiveWindow::forwardKeyPressEvent(int key, int modifiers) {
|
||||
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, static_cast<Qt::KeyboardModifiers>(modifiers));
|
||||
QCoreApplication::postEvent(QCoreApplication::instance(), event);
|
||||
}
|
||||
|
||||
void InteractiveWindow::forwardKeyReleaseEvent(int key, int modifiers) {
|
||||
QKeyEvent* event = new QKeyEvent(QEvent::KeyRelease, key, static_cast<Qt::KeyboardModifiers>(modifiers));
|
||||
QCoreApplication::postEvent(QCoreApplication::instance(), event);
|
||||
}
|
||||
|
||||
/**jsdoc
|
||||
* A set of properties used when creating an <code>InteractiveWindow</code>.
|
||||
* @typedef {object} InteractiveWindow.Properties
|
||||
|
@ -152,12 +162,16 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
|
|||
_dockWidget->getQuickView()->rootContext()->setContextProperty(EVENT_BRIDGE_PROPERTY, this);
|
||||
QObject::connect(rootItem, SIGNAL(sendToScript(QVariant)), this, SLOT(qmlToScript(const QVariant&)),
|
||||
Qt::QueuedConnection);
|
||||
QObject::connect(rootItem, SIGNAL(keyPressEvent(int, int)), this, SLOT(forwardKeyPressEvent(int, int)),
|
||||
Qt::QueuedConnection);
|
||||
QObject::connect(rootItem, SIGNAL(keyReleaseEvent(int, int)), this, SLOT(forwardKeyReleaseEvent(int, int)),
|
||||
Qt::QueuedConnection);
|
||||
emit mainWindow->windowGeometryChanged(qApp->getWindow()->geometry());
|
||||
}
|
||||
});
|
||||
|
||||
_dockWidget->setSource(QUrl(sourceUrl));
|
||||
|
||||
|
||||
mainWindow->addDockWidget(dockArea, _dockWidget.get());
|
||||
} else {
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
|
|
|
@ -287,6 +287,9 @@ protected slots:
|
|||
*/
|
||||
void qmlToScript(const QVariant& message);
|
||||
|
||||
void forwardKeyPressEvent(int key, int modifiers);
|
||||
void forwardKeyReleaseEvent(int key, int modifiers);
|
||||
|
||||
private:
|
||||
QPointer<QObject> _qmlWindow;
|
||||
std::shared_ptr<DockWidget> _dockWidget { nullptr };
|
||||
|
|
|
@ -66,6 +66,10 @@ endfunction()
|
|||
add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${src_files})
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${APP_NAME})
|
||||
set_from_env(LAUNCHER_HMAC_SECRET LAUNCHER_HMAC_SECRET "")
|
||||
if (LAUNCHER_HMAC_SECRET STREQUAL "")
|
||||
message(FATAL_ERROR "LAUNCHER_HMAC_SECRET is not set")
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE LAUNCHER_HMAC_SECRET="${LAUNCHER_HMAC_SECRET}")
|
||||
|
||||
file(GLOB NIB_FILES "nib/*.xib")
|
||||
|
|
|
@ -343,14 +343,14 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
|
|||
@"--tokens", userToken,
|
||||
@"--cache", contentPath,
|
||||
@"--displayName", displayName,
|
||||
@"--script", scriptsPath,
|
||||
@"--scripts", scriptsPath,
|
||||
@"--no-updater",
|
||||
@"--no-launcher", nil];
|
||||
} else {
|
||||
arguments = [NSArray arrayWithObjects:
|
||||
@"--url" , domainUrl,
|
||||
@"--cache", contentPath,
|
||||
@"--script", scriptsPath,
|
||||
@"--scripts", scriptsPath,
|
||||
@"--no-updater",
|
||||
@"--no-launcher", nil];
|
||||
}
|
||||
|
|
|
@ -50,6 +50,11 @@ function(set_from_env _RESULT_NAME _ENV_VAR_NAME _DEFAULT_VALUE)
|
|||
endfunction()
|
||||
|
||||
set_from_env(LAUNCHER_HMAC_SECRET LAUNCHER_HMAC_SECRET "")
|
||||
|
||||
if (LAUNCHER_HMAC_SECRET STREQUAL "")
|
||||
message(FATAL_ERROR "LAUNCHER_HMAC_SECRET is not set")
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE LAUNCHER_HMAC_SECRET="${LAUNCHER_HMAC_SECRET}")
|
||||
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
// CLauncherApp
|
||||
|
||||
BEGIN_MESSAGE_MAP(CLauncherApp, CWinApp)
|
||||
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
|
||||
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CLauncherApp::CLauncherApp(){}
|
||||
|
@ -32,60 +32,60 @@ CLauncherApp theApp;
|
|||
// CLauncherApp initialization
|
||||
|
||||
BOOL CLauncherApp::InitInstance() {
|
||||
// don't launch if already running
|
||||
CreateMutex(NULL, TRUE, _T("HQ_Launcher_Mutex"));
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS) {
|
||||
return FALSE;
|
||||
}
|
||||
int iNumOfArgs;
|
||||
LPWSTR* pArgs = CommandLineToArgvW(GetCommandLine(), &iNumOfArgs);
|
||||
if (iNumOfArgs > 1 && CString(pArgs[1]).Compare(_T("--uninstall")) == 0) {
|
||||
_manager.uninstall();
|
||||
} else {
|
||||
_manager.init();
|
||||
}
|
||||
if (!_manager.installLauncher()) {
|
||||
return FALSE;
|
||||
}
|
||||
installFont(IDR_FONT_REGULAR);
|
||||
installFont(IDR_FONT_BOLD);
|
||||
CWinApp::InitInstance();
|
||||
// don't launch if already running
|
||||
CreateMutex(NULL, TRUE, _T("HQ_Launcher_Mutex"));
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS) {
|
||||
return FALSE;
|
||||
}
|
||||
int iNumOfArgs;
|
||||
LPWSTR* pArgs = CommandLineToArgvW(GetCommandLine(), &iNumOfArgs);
|
||||
if (iNumOfArgs > 1 && CString(pArgs[1]).Compare(_T("--uninstall")) == 0) {
|
||||
_manager.uninstall();
|
||||
} else {
|
||||
_manager.init();
|
||||
}
|
||||
if (!_manager.installLauncher()) {
|
||||
return FALSE;
|
||||
}
|
||||
installFont(IDR_FONT_REGULAR);
|
||||
installFont(IDR_FONT_BOLD);
|
||||
CWinApp::InitInstance();
|
||||
|
||||
SetRegistryKey(_T("HQ High Fidelity"));
|
||||
SetRegistryKey(_T("HQ High Fidelity"));
|
||||
|
||||
CLauncherDlg dlg;
|
||||
m_pMainWnd = &dlg;
|
||||
INT_PTR nResponse = dlg.DoModal();
|
||||
CLauncherDlg dlg;
|
||||
m_pMainWnd = &dlg;
|
||||
INT_PTR nResponse = dlg.DoModal();
|
||||
|
||||
#if !defined(_AFXDLL) && !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS)
|
||||
ControlBarCleanUp();
|
||||
ControlBarCleanUp();
|
||||
#endif
|
||||
|
||||
// Since the dialog has been closed, return FALSE so that we exit the
|
||||
// application, rather than start the application's message pump.
|
||||
return FALSE;
|
||||
|
||||
// Since the dialog has been closed, return FALSE so that we exit the
|
||||
// application, rather than start the application's message pump.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL CLauncherApp::installFont(int fontID) {
|
||||
HINSTANCE hResInstance = AfxGetResourceHandle();
|
||||
HRSRC res = FindResource(hResInstance,
|
||||
MAKEINTRESOURCE(fontID), L"BINARY");
|
||||
if (res) {
|
||||
HGLOBAL mem = LoadResource(hResInstance, res);
|
||||
void *data = LockResource(mem);
|
||||
DWORD len = (DWORD)SizeofResource(hResInstance, res);
|
||||
HINSTANCE hResInstance = AfxGetResourceHandle();
|
||||
HRSRC res = FindResource(hResInstance,
|
||||
MAKEINTRESOURCE(fontID), L"BINARY");
|
||||
if (res) {
|
||||
HGLOBAL mem = LoadResource(hResInstance, res);
|
||||
void *data = LockResource(mem);
|
||||
DWORD len = (DWORD)SizeofResource(hResInstance, res);
|
||||
|
||||
DWORD nFonts;
|
||||
auto m_fonthandle = AddFontMemResourceEx(
|
||||
data, // font resource
|
||||
len, // number of bytes in font resource
|
||||
NULL, // Reserved. Must be 0.
|
||||
&nFonts // number of fonts installed
|
||||
);
|
||||
DWORD nFonts;
|
||||
auto m_fonthandle = AddFontMemResourceEx(
|
||||
data, // font resource
|
||||
len, // number of bytes in font resource
|
||||
NULL, // Reserved. Must be 0.
|
||||
&nFonts // number of fonts installed
|
||||
);
|
||||
|
||||
return (m_fonthandle != 0);
|
||||
}
|
||||
return FALSE;
|
||||
return (m_fonthandle != 0);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -11,22 +11,22 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef __AFXWIN_H__
|
||||
#error "include 'stdafx.h' before including this file for PCH"
|
||||
#error "include 'stdafx.h' before including this file for PCH"
|
||||
#endif
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
#include "resource.h" // main symbols
|
||||
#include "LauncherManager.h"
|
||||
|
||||
class CLauncherApp : public CWinApp
|
||||
{
|
||||
public:
|
||||
CLauncherApp();
|
||||
virtual BOOL InitInstance();
|
||||
void setDialogOnFront() { SetWindowPos(m_pMainWnd->GetSafeHwnd(), HWND_TOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE); }
|
||||
LauncherManager _manager;
|
||||
CLauncherApp();
|
||||
virtual BOOL InitInstance();
|
||||
void setDialogOnFront() { SetWindowPos(m_pMainWnd->GetSafeHwnd(), HWND_TOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE); }
|
||||
LauncherManager _manager;
|
||||
private:
|
||||
BOOL installFont(int fontID);
|
||||
DECLARE_MESSAGE_MAP()
|
||||
BOOL installFont(int fontID);
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
extern CLauncherApp theApp;
|
||||
|
|
|
@ -40,10 +40,10 @@ static CString TROUBLE_URL = _T("https://www.highfidelity.com/hq-support");
|
|||
|
||||
|
||||
CLauncherDlg::CLauncherDlg(CWnd* pParent)
|
||||
: CDialog(IDD_LAUNCHER_DIALOG, pParent)
|
||||
: CDialog(IDD_LAUNCHER_DIALOG, pParent)
|
||||
{
|
||||
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
||||
EnableD2DSupport();
|
||||
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
||||
EnableD2DSupport();
|
||||
}
|
||||
|
||||
CLauncherDlg::~CLauncherDlg() {
|
||||
|
@ -52,109 +52,109 @@ CLauncherDlg::~CLauncherDlg() {
|
|||
|
||||
void CLauncherDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
DDX_Control(pDX, IDC_BUTTON_NEXT, m_btnNext);
|
||||
DDX_Control(pDX, IDC_TROUBLE_LINK, m_trouble_link);
|
||||
DDX_Control(pDX, IDC_ORGNAME, m_orgname);
|
||||
DDX_Control(pDX, IDC_USERNAME, m_username);
|
||||
DDX_Control(pDX, IDC_PASSWORD, m_password);
|
||||
CDialog::DoDataExchange(pDX);
|
||||
DDX_Control(pDX, IDC_BUTTON_NEXT, m_btnNext);
|
||||
DDX_Control(pDX, IDC_TROUBLE_LINK, m_trouble_link);
|
||||
DDX_Control(pDX, IDC_ORGNAME, m_orgname);
|
||||
DDX_Control(pDX, IDC_USERNAME, m_username);
|
||||
DDX_Control(pDX, IDC_PASSWORD, m_password);
|
||||
CDialog::DoDataExchange(pDX);
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CLauncherDlg, CDialog)
|
||||
ON_WM_PAINT()
|
||||
ON_WM_QUERYDRAGICON()
|
||||
ON_WM_TIMER()
|
||||
ON_EN_SETFOCUS(IDC_ORGNAME, &CLauncherDlg::OnOrgEditChangeFocus)
|
||||
ON_EN_SETFOCUS(IDC_USERNAME, &CLauncherDlg::OnUserEditChangeFocus)
|
||||
ON_EN_SETFOCUS(IDC_PASSWORD, &CLauncherDlg::OnPassEditChangeFocus)
|
||||
ON_BN_CLICKED(IDC_BUTTON_NEXT, &CLauncherDlg::OnNextClicked)
|
||||
ON_BN_CLICKED(IDC_TROUBLE_LINK, &CLauncherDlg::OnTroubleClicked)
|
||||
ON_WM_CTLCOLOR()
|
||||
ON_WM_DRAWITEM()
|
||||
ON_WM_SETCURSOR()
|
||||
ON_WM_PAINT()
|
||||
ON_WM_QUERYDRAGICON()
|
||||
ON_WM_TIMER()
|
||||
ON_EN_SETFOCUS(IDC_ORGNAME, &CLauncherDlg::OnOrgEditChangeFocus)
|
||||
ON_EN_SETFOCUS(IDC_USERNAME, &CLauncherDlg::OnUserEditChangeFocus)
|
||||
ON_EN_SETFOCUS(IDC_PASSWORD, &CLauncherDlg::OnPassEditChangeFocus)
|
||||
ON_BN_CLICKED(IDC_BUTTON_NEXT, &CLauncherDlg::OnNextClicked)
|
||||
ON_BN_CLICKED(IDC_TROUBLE_LINK, &CLauncherDlg::OnTroubleClicked)
|
||||
ON_WM_CTLCOLOR()
|
||||
ON_WM_DRAWITEM()
|
||||
ON_WM_SETCURSOR()
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
// CLauncherDlg message handlers
|
||||
|
||||
BOOL CLauncherDlg::OnInitDialog() {
|
||||
CDialog::OnInitDialog();
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
SetIcon(m_hIcon, TRUE); // Set big icon
|
||||
SetIcon(m_hIcon, FALSE); // Set small icon
|
||||
SetIcon(m_hIcon, TRUE); // Set big icon
|
||||
SetIcon(m_hIcon, FALSE); // Set small icon
|
||||
|
||||
CFont editFont;
|
||||
if (LauncherUtils::getFont(GRAPHIK_REGULAR, FIELDS_FONT_SIZE, true, editFont)) {
|
||||
m_orgname.SetFont(&editFont);
|
||||
m_username.SetFont(&editFont);
|
||||
m_password.SetFont(&editFont);
|
||||
}
|
||||
CFont buttonFont;
|
||||
if (LauncherUtils::getFont(_T("Graphik-Bold"), BUTTON_FONT_SIZE, true, buttonFont)) {
|
||||
m_btnNext.SetFont(&editFont);
|
||||
}
|
||||
CFont editFont;
|
||||
if (LauncherUtils::getFont(GRAPHIK_REGULAR, FIELDS_FONT_SIZE, true, editFont)) {
|
||||
m_orgname.SetFont(&editFont);
|
||||
m_username.SetFont(&editFont);
|
||||
m_password.SetFont(&editFont);
|
||||
}
|
||||
CFont buttonFont;
|
||||
if (LauncherUtils::getFont(_T("Graphik-Bold"), BUTTON_FONT_SIZE, true, buttonFont)) {
|
||||
m_btnNext.SetFont(&editFont);
|
||||
}
|
||||
|
||||
m_message_label = (CStatic *)GetDlgItem(IDC_MESSAGE_LABEL);
|
||||
m_action_label = (CStatic *)GetDlgItem(IDC_ACTION_LABEL);
|
||||
m_message2_label = (CStatic *)GetDlgItem(IDC_MESSAGE2_LABEL);
|
||||
m_action2_label = (CStatic *)GetDlgItem(IDC_ACTION2_LABEL);
|
||||
m_message_label = (CStatic *)GetDlgItem(IDC_MESSAGE_LABEL);
|
||||
m_action_label = (CStatic *)GetDlgItem(IDC_ACTION_LABEL);
|
||||
m_message2_label = (CStatic *)GetDlgItem(IDC_MESSAGE2_LABEL);
|
||||
m_action2_label = (CStatic *)GetDlgItem(IDC_ACTION2_LABEL);
|
||||
|
||||
m_orgname_banner = (CStatic *)GetDlgItem(IDC_ORGNAME_BANNER);
|
||||
m_username_banner = (CStatic *)GetDlgItem(IDC_USERNAME_BANNER);
|
||||
m_password_banner = (CStatic *)GetDlgItem(IDC_PASSWORD_BANNER);
|
||||
m_orgname_banner = (CStatic *)GetDlgItem(IDC_ORGNAME_BANNER);
|
||||
m_username_banner = (CStatic *)GetDlgItem(IDC_USERNAME_BANNER);
|
||||
m_password_banner = (CStatic *)GetDlgItem(IDC_PASSWORD_BANNER);
|
||||
|
||||
m_terms = (CStatic *)GetDlgItem(IDC_TERMS);
|
||||
m_terms2 = (CStatic *)GetDlgItem(IDC_TERMS2);
|
||||
m_trouble = (CStatic *)GetDlgItem(IDC_TROUBLE);
|
||||
m_terms = (CStatic *)GetDlgItem(IDC_TERMS);
|
||||
m_terms2 = (CStatic *)GetDlgItem(IDC_TERMS2);
|
||||
m_trouble = (CStatic *)GetDlgItem(IDC_TROUBLE);
|
||||
|
||||
m_voxel = (CStatic *)GetDlgItem(IDC_VOXEL);
|
||||
m_voxel = (CStatic *)GetDlgItem(IDC_VOXEL);
|
||||
|
||||
m_voxel->EnableD2DSupport();
|
||||
m_voxel->EnableD2DSupport();
|
||||
|
||||
m_pRenderTarget = GetRenderTarget();
|
||||
m_pRenderTarget = GetRenderTarget();
|
||||
|
||||
SetTimer(1, 2, NULL);
|
||||
|
||||
return TRUE;
|
||||
SetTimer(1, 2, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CLauncherDlg::PreTranslateMessage(MSG* pMsg) {
|
||||
if ((pMsg->message == WM_KEYDOWN))
|
||||
{
|
||||
if (pMsg->wParam == VK_RETURN)
|
||||
{
|
||||
OnNextClicked();
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return CDialog::PreTranslateMessage(pMsg);
|
||||
if ((pMsg->message == WM_KEYDOWN))
|
||||
{
|
||||
if (pMsg->wParam == VK_RETURN)
|
||||
{
|
||||
OnNextClicked();
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return CDialog::PreTranslateMessage(pMsg);
|
||||
}
|
||||
|
||||
void CLauncherDlg::setCustomDialog() {
|
||||
|
||||
LONG lStyle = GetWindowLong(GetSafeHwnd(), GWL_STYLE);
|
||||
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
|
||||
SetWindowLong(GetSafeHwnd(), GWL_STYLE, lStyle);
|
||||
|
||||
LONG lStyle = GetWindowLong(GetSafeHwnd(), GWL_STYLE);
|
||||
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
|
||||
SetWindowLong(GetSafeHwnd(), GWL_STYLE, lStyle);
|
||||
|
||||
LONG lExStyle = GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
|
||||
lExStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
|
||||
SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, lExStyle);
|
||||
LONG lExStyle = GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
|
||||
lExStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
|
||||
SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, lExStyle);
|
||||
|
||||
SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
||||
// theApp.setDialogOnFront();
|
||||
SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
||||
// theApp.setDialogOnFront();
|
||||
}
|
||||
|
||||
void CLauncherDlg::OnPaint()
|
||||
{
|
||||
CPaintDC dc(this);
|
||||
setCustomDialog();
|
||||
CDialog::OnPaint();
|
||||
CPaintDC dc(this);
|
||||
setCustomDialog();
|
||||
CDialog::OnPaint();
|
||||
}
|
||||
|
||||
// The system calls this function to obtain the cursor to display while the user drags
|
||||
// the minimized window.
|
||||
HCURSOR CLauncherDlg::OnQueryDragIcon()
|
||||
{
|
||||
return static_cast<HCURSOR>(m_hIcon);
|
||||
return static_cast<HCURSOR>(m_hIcon);
|
||||
}
|
||||
|
||||
void CLauncherDlg::startProcess() {
|
||||
|
@ -202,15 +202,15 @@ void CLauncherDlg::startProcess() {
|
|||
}
|
||||
|
||||
BOOL CLauncherDlg::getHQInfo(const CString& orgname) {
|
||||
CString hash;
|
||||
CString hash;
|
||||
CString lowerOrgName = orgname;
|
||||
lowerOrgName.MakeLower();
|
||||
LauncherUtils::hMac256(lowerOrgName, LAUNCHER_HMAC_SECRET, hash);
|
||||
return theApp._manager.readOrganizationJSON(hash) == LauncherUtils::ResponseError::NoError;
|
||||
return theApp._manager.readOrganizationJSON(hash) == LauncherUtils::ResponseError::NoError;
|
||||
}
|
||||
|
||||
afx_msg void CLauncherDlg::OnTroubleClicked() {
|
||||
ShellExecute(0, NULL, TROUBLE_URL, NULL, NULL, SW_SHOWDEFAULT);
|
||||
ShellExecute(0, NULL, TROUBLE_URL, NULL, NULL, SW_SHOWDEFAULT);
|
||||
}
|
||||
|
||||
afx_msg void CLauncherDlg::OnNextClicked() {
|
||||
|
@ -255,414 +255,414 @@ afx_msg void CLauncherDlg::OnNextClicked() {
|
|||
}
|
||||
|
||||
void CLauncherDlg::drawBackground(CHwndRenderTarget* pRenderTarget) {
|
||||
CD2DBitmap m_pBitmamBackground(pRenderTarget, IDB_PNG1, _T("PNG"));
|
||||
auto size = pRenderTarget->GetSize();
|
||||
CD2DRectF backRec(0.0f, 0.0f, size.width, size.height);
|
||||
pRenderTarget->DrawBitmap(&m_pBitmamBackground, backRec);
|
||||
CD2DBitmap m_pBitmamBackground(pRenderTarget, IDB_PNG1, _T("PNG"));
|
||||
auto size = pRenderTarget->GetSize();
|
||||
CD2DRectF backRec(0.0f, 0.0f, size.width, size.height);
|
||||
pRenderTarget->DrawBitmap(&m_pBitmamBackground, backRec);
|
||||
}
|
||||
|
||||
void CLauncherDlg::drawLogo(CHwndRenderTarget* pRenderTarget) {
|
||||
CD2DBitmap m_pBitmamLogo(pRenderTarget, IDB_PNG2, _T("PNG"));
|
||||
auto size = pRenderTarget->GetSize();
|
||||
int logoWidth = 231;
|
||||
int logoHeight = 181;
|
||||
float logoPosX = 0.5f * (size.width - logoWidth);
|
||||
float logoPosY = 0.95f * (size.height - logoHeight);
|
||||
CD2DRectF logoRec(logoPosX, logoPosY, logoPosX + logoWidth, logoPosY + logoHeight);
|
||||
pRenderTarget->DrawBitmap(&m_pBitmamLogo, logoRec);
|
||||
CD2DBitmap m_pBitmamLogo(pRenderTarget, IDB_PNG2, _T("PNG"));
|
||||
auto size = pRenderTarget->GetSize();
|
||||
int logoWidth = 231;
|
||||
int logoHeight = 181;
|
||||
float logoPosX = 0.5f * (size.width - logoWidth);
|
||||
float logoPosY = 0.95f * (size.height - logoHeight);
|
||||
CD2DRectF logoRec(logoPosX, logoPosY, logoPosX + logoWidth, logoPosY + logoHeight);
|
||||
pRenderTarget->DrawBitmap(&m_pBitmamLogo, logoRec);
|
||||
}
|
||||
|
||||
void CLauncherDlg::drawSmallLogo(CHwndRenderTarget* pRenderTarget) {
|
||||
CD2DBitmap m_pBitmamLogo(pRenderTarget, IDB_PNG5, _T("PNG"));
|
||||
auto size = pRenderTarget->GetSize();
|
||||
int padding = 6;
|
||||
int logoWidth = 100;
|
||||
int logoHeight = 18;
|
||||
float logoPosX = size.width - logoWidth - padding;
|
||||
float logoPosY = size.height - logoHeight - padding;
|
||||
CD2DRectF logoRec(logoPosX, logoPosY, logoPosX + logoWidth, logoPosY + logoHeight);
|
||||
pRenderTarget->DrawBitmap(&m_pBitmamLogo, logoRec);
|
||||
CD2DBitmap m_pBitmamLogo(pRenderTarget, IDB_PNG5, _T("PNG"));
|
||||
auto size = pRenderTarget->GetSize();
|
||||
int padding = 6;
|
||||
int logoWidth = 100;
|
||||
int logoHeight = 18;
|
||||
float logoPosX = size.width - logoWidth - padding;
|
||||
float logoPosY = size.height - logoHeight - padding;
|
||||
CD2DRectF logoRec(logoPosX, logoPosY, logoPosX + logoWidth, logoPosY + logoHeight);
|
||||
pRenderTarget->DrawBitmap(&m_pBitmamLogo, logoRec);
|
||||
}
|
||||
|
||||
void CLauncherDlg::drawVoxel(CHwndRenderTarget* pRenderTarget) {
|
||||
CD2DBitmap m_pBitmamVoxel(pRenderTarget, IDB_PNG4, _T("PNG"));
|
||||
auto size = pRenderTarget->GetSize();
|
||||
int logoWidth = 132;
|
||||
int logoHeight = 134;
|
||||
float voxelPosX = 0.5f * (size.width - logoWidth);
|
||||
float voxelPosY = 0.5f * (size.height - logoHeight);
|
||||
CD2DRectF voxelRec(voxelPosX, voxelPosY, voxelPosX + logoWidth, voxelPosY + logoHeight);
|
||||
auto midPoint = D2D1::Point2F(0.5f * size.width, 0.5f * size.height);
|
||||
_logoRotation += 2.0f;
|
||||
CD2DSolidColorBrush brush(pRenderTarget, D2D1::ColorF(0.0f, 0.0f, 0.0f));
|
||||
pRenderTarget->SetTransform(D2D1::Matrix3x2F::Rotation(_logoRotation - 2.0f, midPoint));
|
||||
pRenderTarget->FillRectangle(voxelRec, &brush);
|
||||
pRenderTarget->SetTransform(D2D1::Matrix3x2F::Rotation(_logoRotation, midPoint));
|
||||
pRenderTarget->DrawBitmap(&m_pBitmamVoxel, voxelRec);
|
||||
pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||
CD2DBitmap m_pBitmamVoxel(pRenderTarget, IDB_PNG4, _T("PNG"));
|
||||
auto size = pRenderTarget->GetSize();
|
||||
int logoWidth = 132;
|
||||
int logoHeight = 134;
|
||||
float voxelPosX = 0.5f * (size.width - logoWidth);
|
||||
float voxelPosY = 0.5f * (size.height - logoHeight);
|
||||
CD2DRectF voxelRec(voxelPosX, voxelPosY, voxelPosX + logoWidth, voxelPosY + logoHeight);
|
||||
auto midPoint = D2D1::Point2F(0.5f * size.width, 0.5f * size.height);
|
||||
_logoRotation += 2.0f;
|
||||
CD2DSolidColorBrush brush(pRenderTarget, D2D1::ColorF(0.0f, 0.0f, 0.0f));
|
||||
pRenderTarget->SetTransform(D2D1::Matrix3x2F::Rotation(_logoRotation - 2.0f, midPoint));
|
||||
pRenderTarget->FillRectangle(voxelRec, &brush);
|
||||
pRenderTarget->SetTransform(D2D1::Matrix3x2F::Rotation(_logoRotation, midPoint));
|
||||
pRenderTarget->DrawBitmap(&m_pBitmamVoxel, voxelRec);
|
||||
pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||
}
|
||||
|
||||
|
||||
void CLauncherDlg::showWindows(std::vector<CStatic*> windows, bool show) {
|
||||
for (auto window : windows) {
|
||||
window->ShowWindow(show ? SW_SHOW : SW_HIDE);
|
||||
}
|
||||
for (auto window : windows) {
|
||||
window->ShowWindow(show ? SW_SHOW : SW_HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
void CLauncherDlg::prepareLogin(DrawStep step) {
|
||||
m_voxel->ShowWindow(SW_HIDE);
|
||||
m_orgname_banner->SetWindowTextW(_T("Organization Name"));
|
||||
m_username_banner->SetWindowTextW(_T("Username"));
|
||||
m_password_banner->SetWindowTextW(_T("Password"));
|
||||
CString editText;
|
||||
m_orgname.GetWindowTextW(editText);
|
||||
m_orgname_banner->ShowWindow(editText.GetLength() == 0 ? SW_SHOW : SW_HIDE);
|
||||
m_username.GetWindowTextW(editText);
|
||||
m_username_banner->ShowWindow(editText.GetLength() == 0 ? SW_SHOW : SW_HIDE);
|
||||
m_password.GetWindowTextW(editText);
|
||||
m_password_banner->ShowWindow(editText.GetLength() == 0 ? SW_SHOW : SW_HIDE);
|
||||
m_orgname.ShowWindow(SW_SHOW);
|
||||
m_username.ShowWindow(SW_SHOW);
|
||||
m_password.ShowWindow(SW_SHOW);
|
||||
CString actionText = step == DrawStep::DrawLoginLogin ? _T("Please log in") : _T("Uh-oh, we have a problem");
|
||||
CString messageText = step == DrawStep::DrawLoginLogin ? _T("Be sure you've uploaded your Avatar before signing in.") :
|
||||
step == DrawStep::DrawLoginErrorCred ? _T("There is a problem with your credentials\n please try again.") : _T("There is a problem with your Organization name\n please try again.");
|
||||
m_action_label->SetWindowTextW(actionText);
|
||||
m_message_label->SetWindowTextW(messageText);
|
||||
m_action_label->ShowWindow(SW_SHOW);
|
||||
m_message_label->ShowWindow(SW_SHOW);
|
||||
m_btnNext.ShowWindow(SW_SHOW);
|
||||
m_trouble->SetWindowTextW(_T("Having Trouble?"));
|
||||
m_trouble->ShowWindow(SW_SHOW);
|
||||
m_trouble_link.ShowWindow(SW_SHOW);
|
||||
|
||||
m_voxel->ShowWindow(SW_HIDE);
|
||||
m_orgname_banner->SetWindowTextW(_T("Organization Name"));
|
||||
m_username_banner->SetWindowTextW(_T("Username"));
|
||||
m_password_banner->SetWindowTextW(_T("Password"));
|
||||
CString editText;
|
||||
m_orgname.GetWindowTextW(editText);
|
||||
m_orgname_banner->ShowWindow(editText.GetLength() == 0 ? SW_SHOW : SW_HIDE);
|
||||
m_username.GetWindowTextW(editText);
|
||||
m_username_banner->ShowWindow(editText.GetLength() == 0 ? SW_SHOW : SW_HIDE);
|
||||
m_password.GetWindowTextW(editText);
|
||||
m_password_banner->ShowWindow(editText.GetLength() == 0 ? SW_SHOW : SW_HIDE);
|
||||
m_orgname.ShowWindow(SW_SHOW);
|
||||
m_username.ShowWindow(SW_SHOW);
|
||||
m_password.ShowWindow(SW_SHOW);
|
||||
CString actionText = step == DrawStep::DrawLoginLogin ? _T("Please log in") : _T("Uh-oh, we have a problem");
|
||||
CString messageText = step == DrawStep::DrawLoginLogin ? _T("Be sure you've uploaded your Avatar before signing in.") :
|
||||
step == DrawStep::DrawLoginErrorCred ? _T("There is a problem with your credentials\n please try again.") : _T("There is a problem with your Organization name\n please try again.");
|
||||
m_action_label->SetWindowTextW(actionText);
|
||||
m_message_label->SetWindowTextW(messageText);
|
||||
m_action_label->ShowWindow(SW_SHOW);
|
||||
m_message_label->ShowWindow(SW_SHOW);
|
||||
m_btnNext.ShowWindow(SW_SHOW);
|
||||
m_trouble->SetWindowTextW(_T("Having Trouble?"));
|
||||
m_trouble->ShowWindow(SW_SHOW);
|
||||
m_trouble_link.ShowWindow(SW_SHOW);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CLauncherDlg::prepareChoose() {
|
||||
m_orgname.ShowWindow(SW_HIDE);
|
||||
m_username.SetWindowTextW(_T(""));
|
||||
m_username_banner->SetWindowTextW(_T("Display Name"));
|
||||
CString editText;
|
||||
m_username.GetWindowTextW(editText);
|
||||
m_username_banner->ShowWindow(editText.GetLength() == 0 ? SW_SHOW : SW_HIDE);
|
||||
m_password.ShowWindow(SW_HIDE);
|
||||
m_orgname_banner->ShowWindow(SW_HIDE);
|
||||
m_password_banner->ShowWindow(SW_HIDE);
|
||||
m_action_label->SetWindowTextW(_T("Choose a display name"));
|
||||
m_message_label->SetWindowTextW(_T("This is the name that your teammates will see."));
|
||||
m_terms->ShowWindow(SW_SHOW);
|
||||
m_terms2->ShowWindow(SW_SHOW);
|
||||
m_terms->SetWindowTextW(_T("By signing in, you agree to the High Fidelity"));
|
||||
m_terms2->SetWindowTextW(_T("Terms of Service"));
|
||||
CRect rec;
|
||||
m_btnNext.GetWindowRect(&rec);
|
||||
ScreenToClient(&rec);
|
||||
if (rec.top > 281) {
|
||||
rec.bottom -= 35;
|
||||
rec.top -= 35;
|
||||
m_btnNext.MoveWindow(rec, FALSE);
|
||||
}
|
||||
m_btnNext.ShowWindow(SW_SHOW);
|
||||
m_orgname.ShowWindow(SW_HIDE);
|
||||
m_username.SetWindowTextW(_T(""));
|
||||
m_username_banner->SetWindowTextW(_T("Display Name"));
|
||||
CString editText;
|
||||
m_username.GetWindowTextW(editText);
|
||||
m_username_banner->ShowWindow(editText.GetLength() == 0 ? SW_SHOW : SW_HIDE);
|
||||
m_password.ShowWindow(SW_HIDE);
|
||||
m_orgname_banner->ShowWindow(SW_HIDE);
|
||||
m_password_banner->ShowWindow(SW_HIDE);
|
||||
m_action_label->SetWindowTextW(_T("Choose a display name"));
|
||||
m_message_label->SetWindowTextW(_T("This is the name that your teammates will see."));
|
||||
m_terms->ShowWindow(SW_SHOW);
|
||||
m_terms2->ShowWindow(SW_SHOW);
|
||||
m_terms->SetWindowTextW(_T("By signing in, you agree to the High Fidelity"));
|
||||
m_terms2->SetWindowTextW(_T("Terms of Service"));
|
||||
CRect rec;
|
||||
m_btnNext.GetWindowRect(&rec);
|
||||
ScreenToClient(&rec);
|
||||
if (rec.top > 281) {
|
||||
rec.bottom -= 35;
|
||||
rec.top -= 35;
|
||||
m_btnNext.MoveWindow(rec, FALSE);
|
||||
}
|
||||
m_btnNext.ShowWindow(SW_SHOW);
|
||||
}
|
||||
|
||||
void CLauncherDlg::prepareProcess(DrawStep step) {
|
||||
m_trouble->ShowWindow(SW_HIDE);
|
||||
m_trouble_link.ShowWindow(SW_HIDE);
|
||||
m_terms->ShowWindow(SW_HIDE);
|
||||
m_terms2->ShowWindow(SW_HIDE);
|
||||
m_orgname_banner->ShowWindow(SW_HIDE);
|
||||
m_username_banner->ShowWindow(SW_HIDE);
|
||||
m_password_banner->ShowWindow(SW_HIDE);
|
||||
m_orgname.ShowWindow(SW_HIDE);
|
||||
m_username.ShowWindow(SW_HIDE);
|
||||
m_password.ShowWindow(SW_HIDE);
|
||||
m_action_label->SetWindowTextW(_T(""));
|
||||
m_message_label->SetWindowTextW(_T(""));
|
||||
m_btnNext.ShowWindow(SW_HIDE);
|
||||
m_action_label->ShowWindow(SW_HIDE);
|
||||
m_message_label->ShowWindow(SW_HIDE);
|
||||
m_voxel->ShowWindow(SW_SHOW);
|
||||
CString actionText = _T("");
|
||||
CString messageText = _T("");
|
||||
switch (step) {
|
||||
case DrawStep::DrawProcessSetup:
|
||||
actionText = _T("We're building your virtual HQ");
|
||||
messageText = _T("Set up may take several minutes.");
|
||||
break;
|
||||
case DrawStep::DrawProcessUpdate:
|
||||
actionText = _T("Getting updates...");
|
||||
messageText = _T("We're getting the latest and greatest for you, one sec.");
|
||||
break;
|
||||
case DrawStep::DrawProcessFinishHq:
|
||||
actionText = _T("Your new HQ is all setup");
|
||||
messageText = _T("Thanks for being patient.");
|
||||
break;
|
||||
case DrawStep::DrawProcessFinishUpdate:
|
||||
actionText = _T("You're good to go!");
|
||||
messageText = _T("Thanks for being patient.");
|
||||
break;
|
||||
case DrawStep::DrawProcessUninstall:
|
||||
actionText = _T("Uninstalling...");
|
||||
messageText = _T("It'll take one sec.");
|
||||
break;
|
||||
}
|
||||
m_action2_label->SetWindowTextW(actionText);
|
||||
m_message2_label->SetWindowTextW(messageText);
|
||||
m_action2_label->ShowWindow(SW_SHOW);
|
||||
m_message2_label->ShowWindow(SW_SHOW);
|
||||
m_trouble->ShowWindow(SW_HIDE);
|
||||
m_trouble_link.ShowWindow(SW_HIDE);
|
||||
m_terms->ShowWindow(SW_HIDE);
|
||||
m_terms2->ShowWindow(SW_HIDE);
|
||||
m_orgname_banner->ShowWindow(SW_HIDE);
|
||||
m_username_banner->ShowWindow(SW_HIDE);
|
||||
m_password_banner->ShowWindow(SW_HIDE);
|
||||
m_orgname.ShowWindow(SW_HIDE);
|
||||
m_username.ShowWindow(SW_HIDE);
|
||||
m_password.ShowWindow(SW_HIDE);
|
||||
m_action_label->SetWindowTextW(_T(""));
|
||||
m_message_label->SetWindowTextW(_T(""));
|
||||
m_btnNext.ShowWindow(SW_HIDE);
|
||||
m_action_label->ShowWindow(SW_HIDE);
|
||||
m_message_label->ShowWindow(SW_HIDE);
|
||||
m_voxel->ShowWindow(SW_SHOW);
|
||||
CString actionText = _T("");
|
||||
CString messageText = _T("");
|
||||
switch (step) {
|
||||
case DrawStep::DrawProcessSetup:
|
||||
actionText = _T("We're building your virtual HQ");
|
||||
messageText = _T("Set up may take several minutes.");
|
||||
break;
|
||||
case DrawStep::DrawProcessUpdate:
|
||||
actionText = _T("Getting updates...");
|
||||
messageText = _T("We're getting the latest and greatest for you, one sec.");
|
||||
break;
|
||||
case DrawStep::DrawProcessFinishHq:
|
||||
actionText = _T("Your new HQ is all setup");
|
||||
messageText = _T("Thanks for being patient.");
|
||||
break;
|
||||
case DrawStep::DrawProcessFinishUpdate:
|
||||
actionText = _T("You're good to go!");
|
||||
messageText = _T("Thanks for being patient.");
|
||||
break;
|
||||
case DrawStep::DrawProcessUninstall:
|
||||
actionText = _T("Uninstalling...");
|
||||
messageText = _T("It'll take one sec.");
|
||||
break;
|
||||
}
|
||||
m_action2_label->SetWindowTextW(actionText);
|
||||
m_message2_label->SetWindowTextW(messageText);
|
||||
m_action2_label->ShowWindow(SW_SHOW);
|
||||
m_message2_label->ShowWindow(SW_SHOW);
|
||||
}
|
||||
|
||||
void CLauncherDlg::prepareError() {
|
||||
}
|
||||
|
||||
BOOL CLauncherDlg::getTextFormat(int resID, TextFormat& formatOut) {
|
||||
// Set default values for message
|
||||
BOOL isText = TRUE;
|
||||
formatOut.color = COLOR_LIGHT_GREY;
|
||||
formatOut.isBold = false;
|
||||
formatOut.isButton = false;
|
||||
formatOut.size = MESSAGE_FONT_SIZE;
|
||||
formatOut.underlined = false;
|
||||
|
||||
switch (resID) {
|
||||
case IDC_VOXEL:
|
||||
case IDD_LAUNCHER_DIALOG:
|
||||
isText = FALSE;
|
||||
case IDC_MESSAGE_LABEL:
|
||||
case IDC_MESSAGE2_LABEL:
|
||||
// Default values
|
||||
break;
|
||||
case IDC_ACTION_LABEL:
|
||||
case IDC_ACTION2_LABEL:
|
||||
formatOut.size = ACTION_FONT_SIZE;
|
||||
formatOut.isBold = true;
|
||||
formatOut.color = COLOR_LIGHTER_GREY;
|
||||
break;
|
||||
case IDC_USERNAME:
|
||||
case IDC_PASSWORD:
|
||||
case IDC_ORGNAME:
|
||||
formatOut.color = COLOR_WHITE;
|
||||
formatOut.size = FIELDS_FONT_SIZE;
|
||||
formatOut.underlined = true;
|
||||
break;
|
||||
case IDC_USERNAME_BANNER:
|
||||
case IDC_PASSWORD_BANNER:
|
||||
case IDC_ORGNAME_BANNER:
|
||||
formatOut.size = FIELDS_FONT_SIZE;
|
||||
formatOut.color = COLOR_GREY;
|
||||
break;
|
||||
case IDC_TERMS:
|
||||
formatOut.size = TERMS_FONT_SIZE;
|
||||
break;
|
||||
case IDC_TERMS2:
|
||||
formatOut.size = TERMS_FONT_SIZE;
|
||||
formatOut.isBold = true;
|
||||
break;
|
||||
case IDC_TROUBLE:
|
||||
formatOut.size = TROUBLE_FONT_SIZE;
|
||||
formatOut.color = COLOR_BLUE;
|
||||
break;
|
||||
}
|
||||
return isText;
|
||||
// Set default values for message
|
||||
BOOL isText = TRUE;
|
||||
formatOut.color = COLOR_LIGHT_GREY;
|
||||
formatOut.isBold = false;
|
||||
formatOut.isButton = false;
|
||||
formatOut.size = MESSAGE_FONT_SIZE;
|
||||
formatOut.underlined = false;
|
||||
|
||||
switch (resID) {
|
||||
case IDC_VOXEL:
|
||||
case IDD_LAUNCHER_DIALOG:
|
||||
isText = FALSE;
|
||||
case IDC_MESSAGE_LABEL:
|
||||
case IDC_MESSAGE2_LABEL:
|
||||
// Default values
|
||||
break;
|
||||
case IDC_ACTION_LABEL:
|
||||
case IDC_ACTION2_LABEL:
|
||||
formatOut.size = ACTION_FONT_SIZE;
|
||||
formatOut.isBold = true;
|
||||
formatOut.color = COLOR_LIGHTER_GREY;
|
||||
break;
|
||||
case IDC_USERNAME:
|
||||
case IDC_PASSWORD:
|
||||
case IDC_ORGNAME:
|
||||
formatOut.color = COLOR_WHITE;
|
||||
formatOut.size = FIELDS_FONT_SIZE;
|
||||
formatOut.underlined = true;
|
||||
break;
|
||||
case IDC_USERNAME_BANNER:
|
||||
case IDC_PASSWORD_BANNER:
|
||||
case IDC_ORGNAME_BANNER:
|
||||
formatOut.size = FIELDS_FONT_SIZE;
|
||||
formatOut.color = COLOR_GREY;
|
||||
break;
|
||||
case IDC_TERMS:
|
||||
formatOut.size = TERMS_FONT_SIZE;
|
||||
break;
|
||||
case IDC_TERMS2:
|
||||
formatOut.size = TERMS_FONT_SIZE;
|
||||
formatOut.isBold = true;
|
||||
break;
|
||||
case IDC_TROUBLE:
|
||||
formatOut.size = TROUBLE_FONT_SIZE;
|
||||
formatOut.color = COLOR_BLUE;
|
||||
break;
|
||||
}
|
||||
return isText;
|
||||
}
|
||||
|
||||
HBRUSH CLauncherDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
|
||||
{
|
||||
|
||||
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
|
||||
TextFormat textFormat;
|
||||
int resId = pWnd->GetDlgCtrlID();
|
||||
if (getTextFormat(resId, textFormat)) {
|
||||
pDC->SetTextColor(textFormat.color);
|
||||
pDC->SetBkMode(TRANSPARENT);
|
||||
CFont textFont;
|
||||
CString fontFamily = textFormat.isBold ? GRAPHIK_SEMIBOLD : GRAPHIK_REGULAR;
|
||||
if (LauncherUtils::getFont(fontFamily, textFormat.size, textFormat.isBold, textFont)) {
|
||||
pDC->SelectObject(&textFont);
|
||||
}
|
||||
if (textFormat.underlined) {
|
||||
CRect rect;
|
||||
pWnd->GetClientRect(&rect);
|
||||
int borderThick = 1;
|
||||
int padding = 4;
|
||||
CRect lineRect = CRect(rect.left + padding, rect.bottom, rect.right - padding, rect.bottom + borderThick);
|
||||
lineRect.MoveToY(lineRect.bottom + 1);
|
||||
pDC->FillSolidRect(lineRect, COLOR_GREY);
|
||||
}
|
||||
}
|
||||
return (HBRUSH)GetStockObject(BLACK_BRUSH);
|
||||
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
|
||||
TextFormat textFormat;
|
||||
int resId = pWnd->GetDlgCtrlID();
|
||||
if (getTextFormat(resId, textFormat)) {
|
||||
pDC->SetTextColor(textFormat.color);
|
||||
pDC->SetBkMode(TRANSPARENT);
|
||||
CFont textFont;
|
||||
CString fontFamily = textFormat.isBold ? GRAPHIK_SEMIBOLD : GRAPHIK_REGULAR;
|
||||
if (LauncherUtils::getFont(fontFamily, textFormat.size, textFormat.isBold, textFont)) {
|
||||
pDC->SelectObject(&textFont);
|
||||
}
|
||||
if (textFormat.underlined) {
|
||||
CRect rect;
|
||||
pWnd->GetClientRect(&rect);
|
||||
int borderThick = 1;
|
||||
int padding = 4;
|
||||
CRect lineRect = CRect(rect.left + padding, rect.bottom, rect.right - padding, rect.bottom + borderThick);
|
||||
lineRect.MoveToY(lineRect.bottom + 1);
|
||||
pDC->FillSolidRect(lineRect, COLOR_GREY);
|
||||
}
|
||||
}
|
||||
return (HBRUSH)GetStockObject(BLACK_BRUSH);
|
||||
}
|
||||
|
||||
void CLauncherDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
CDC dc;
|
||||
dc.Attach(lpDrawItemStruct->hDC);
|
||||
CRect rect = lpDrawItemStruct->rcItem;
|
||||
CRect defrect = rect;
|
||||
CString btnName = _T("");
|
||||
int xpan = 0;
|
||||
if (nIDCtl == IDC_BUTTON_NEXT) {
|
||||
if (_drawStep == DrawStep::DrawChoose || _drawStep == DrawStep::DrawLoginLogin) {
|
||||
btnName += _drawStep == DrawStep::DrawLoginLogin ? _T("NEXT") : _T("LOG IN");
|
||||
int xpan = -20;
|
||||
defrect = CRect(rect.left - xpan, rect.top, rect.right + xpan, rect.bottom);
|
||||
} else {
|
||||
btnName += _T("TRY AGAIN");
|
||||
}
|
||||
int borderThick = 2;
|
||||
dc.FillSolidRect(rect, COLOR_BLACK);
|
||||
dc.FillSolidRect(defrect, COLOR_WHITE);
|
||||
defrect.DeflateRect(borderThick, borderThick, borderThick, borderThick);
|
||||
dc.FillSolidRect(defrect, COLOR_BLACK);
|
||||
UINT state = lpDrawItemStruct->itemState;
|
||||
dc.SetTextColor(COLOR_WHITE);
|
||||
CDC dc;
|
||||
dc.Attach(lpDrawItemStruct->hDC);
|
||||
CRect rect = lpDrawItemStruct->rcItem;
|
||||
CRect defrect = rect;
|
||||
CString btnName = _T("");
|
||||
int xpan = 0;
|
||||
if (nIDCtl == IDC_BUTTON_NEXT) {
|
||||
if (_drawStep == DrawStep::DrawChoose || _drawStep == DrawStep::DrawLoginLogin) {
|
||||
btnName += _drawStep == DrawStep::DrawLoginLogin ? _T("NEXT") : _T("LOG IN");
|
||||
int xpan = -20;
|
||||
defrect = CRect(rect.left - xpan, rect.top, rect.right + xpan, rect.bottom);
|
||||
} else {
|
||||
btnName += _T("TRY AGAIN");
|
||||
}
|
||||
int borderThick = 2;
|
||||
dc.FillSolidRect(rect, COLOR_BLACK);
|
||||
dc.FillSolidRect(defrect, COLOR_WHITE);
|
||||
defrect.DeflateRect(borderThick, borderThick, borderThick, borderThick);
|
||||
dc.FillSolidRect(defrect, COLOR_BLACK);
|
||||
UINT state = lpDrawItemStruct->itemState;
|
||||
dc.SetTextColor(COLOR_WHITE);
|
||||
|
||||
CFont buttonFont;
|
||||
if (LauncherUtils::getFont(GRAPHIK_SEMIBOLD, BUTTON_FONT_SIZE, true, buttonFont)) {
|
||||
dc.SelectObject(buttonFont);
|
||||
}
|
||||
dc.DrawText(btnName, CRect(rect.left, rect.top + 4, rect.right, rect.bottom - 8), DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
dc.Detach();
|
||||
} else if (nIDCtl == IDC_TROUBLE_LINK) {
|
||||
dc.FillSolidRect(rect, COLOR_BLACK);
|
||||
dc.SetTextColor(COLOR_BLUE);
|
||||
CFont buttonFont;
|
||||
if (LauncherUtils::getFont(GRAPHIK_SEMIBOLD, TROUBLE_FONT_SIZE, true, buttonFont)) {
|
||||
dc.SelectObject(buttonFont);
|
||||
}
|
||||
dc.DrawText(_T("Having Trouble"), CRect(rect.left, rect.top, rect.right, rect.bottom), DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
CFont buttonFont;
|
||||
if (LauncherUtils::getFont(GRAPHIK_SEMIBOLD, BUTTON_FONT_SIZE, true, buttonFont)) {
|
||||
dc.SelectObject(buttonFont);
|
||||
}
|
||||
dc.DrawText(btnName, CRect(rect.left, rect.top + 4, rect.right, rect.bottom - 8), DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
dc.Detach();
|
||||
} else if (nIDCtl == IDC_TROUBLE_LINK) {
|
||||
dc.FillSolidRect(rect, COLOR_BLACK);
|
||||
dc.SetTextColor(COLOR_BLUE);
|
||||
CFont buttonFont;
|
||||
if (LauncherUtils::getFont(GRAPHIK_SEMIBOLD, TROUBLE_FONT_SIZE, true, buttonFont)) {
|
||||
dc.SelectObject(buttonFont);
|
||||
}
|
||||
dc.DrawText(_T("Having Trouble"), CRect(rect.left, rect.top, rect.right, rect.bottom), DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CLauncherDlg::redrawBanner(const CEdit& edit, CStatic* banner) {
|
||||
CString editText;
|
||||
edit.GetWindowTextW(editText);
|
||||
if (editText.GetLength() == 0) {
|
||||
banner->Invalidate();
|
||||
}
|
||||
CString editText;
|
||||
edit.GetWindowTextW(editText);
|
||||
if (editText.GetLength() == 0) {
|
||||
banner->Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void CLauncherDlg::OnOrgEditChangeFocus() {
|
||||
redrawBanner(m_username, m_username_banner);
|
||||
redrawBanner(m_password, m_password_banner);
|
||||
redrawBanner(m_username, m_username_banner);
|
||||
redrawBanner(m_password, m_password_banner);
|
||||
}
|
||||
|
||||
void CLauncherDlg::OnUserEditChangeFocus() {
|
||||
redrawBanner(m_orgname, m_orgname_banner);
|
||||
redrawBanner(m_password, m_password_banner);
|
||||
redrawBanner(m_orgname, m_orgname_banner);
|
||||
redrawBanner(m_password, m_password_banner);
|
||||
}
|
||||
|
||||
void CLauncherDlg::OnPassEditChangeFocus() {
|
||||
redrawBanner(m_orgname, m_orgname_banner);
|
||||
redrawBanner(m_username, m_username_banner);
|
||||
redrawBanner(m_orgname, m_orgname_banner);
|
||||
redrawBanner(m_username, m_username_banner);
|
||||
}
|
||||
BOOL CLauncherDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
||||
{
|
||||
if (pWnd->IsKindOf(RUNTIME_CLASS(CButton))) {
|
||||
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_HAND));
|
||||
return TRUE;
|
||||
}
|
||||
return CDialog::OnSetCursor(pWnd, nHitTest, message);
|
||||
if (pWnd->IsKindOf(RUNTIME_CLASS(CButton))) {
|
||||
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_HAND));
|
||||
return TRUE;
|
||||
}
|
||||
return CDialog::OnSetCursor(pWnd, nHitTest, message);
|
||||
}
|
||||
|
||||
void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) {
|
||||
const int CONSOLE_MAX_SHUTDOWN_TRY_COUNT = 10;
|
||||
const int CONSOLE_DELTATIME_BETWEEN_TRYS = 10;
|
||||
if (_drawStep == DrawStep::DrawProcessSetup ||
|
||||
_drawStep == DrawStep::DrawProcessUpdate ||
|
||||
_drawStep == DrawStep::DrawProcessUninstall) {
|
||||
// Refresh
|
||||
setDrawDialog(_drawStep, true);
|
||||
}
|
||||
if (_showSplash) {
|
||||
if (_splashStep == 0){
|
||||
const int CONSOLE_MAX_SHUTDOWN_TRY_COUNT = 10;
|
||||
const int CONSOLE_DELTATIME_BETWEEN_TRYS = 10;
|
||||
if (_drawStep == DrawStep::DrawProcessSetup ||
|
||||
_drawStep == DrawStep::DrawProcessUpdate ||
|
||||
_drawStep == DrawStep::DrawProcessUninstall) {
|
||||
// Refresh
|
||||
setDrawDialog(_drawStep, true);
|
||||
}
|
||||
if (_showSplash) {
|
||||
if (_splashStep == 0){
|
||||
if (theApp._manager.needsUninstall()) {
|
||||
theApp._manager.addToLog(_T("Waiting to uninstall"));
|
||||
setDrawDialog(DrawStep::DrawProcessUninstall);
|
||||
} else {
|
||||
theApp._manager.addToLog(_T("Start splash screen"));
|
||||
setDrawDialog(DrawStep::DrawLogo);
|
||||
}
|
||||
} else if (_splashStep > 100) {
|
||||
_showSplash = false;
|
||||
if (theApp._manager.shouldShutDown()) {
|
||||
if (LauncherUtils::IsProcessRunning(L"interface.exe")) {
|
||||
exit(0);
|
||||
}
|
||||
} else if (theApp._manager.needsUpdate()) {
|
||||
startProcess();
|
||||
} else if (theApp._manager.needsUninstall()) {
|
||||
theApp._manager.uninstallApplication();
|
||||
exit(0);
|
||||
} else {
|
||||
}
|
||||
} else if (_splashStep > 100) {
|
||||
_showSplash = false;
|
||||
if (theApp._manager.shouldShutDown()) {
|
||||
if (LauncherUtils::IsProcessRunning(L"interface.exe")) {
|
||||
exit(0);
|
||||
}
|
||||
} else if (theApp._manager.needsUpdate()) {
|
||||
startProcess();
|
||||
} else if (theApp._manager.needsUninstall()) {
|
||||
theApp._manager.uninstallApplication();
|
||||
exit(0);
|
||||
} else {
|
||||
theApp._manager.addToLog(_T("Starting login"));
|
||||
setDrawDialog(DrawStep::DrawLoginLogin);
|
||||
}
|
||||
}
|
||||
_splashStep++;
|
||||
} else if (theApp._manager.shouldShutDown()) {
|
||||
if (LauncherUtils::IsProcessRunning(L"interface.exe")) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
setDrawDialog(DrawStep::DrawLoginLogin);
|
||||
}
|
||||
}
|
||||
_splashStep++;
|
||||
} else if (theApp._manager.shouldShutDown()) {
|
||||
if (LauncherUtils::IsProcessRunning(L"interface.exe")) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLauncherDlg::setDrawDialog(DrawStep step, BOOL isUpdate) {
|
||||
_drawStep = step;
|
||||
auto m_pRenderTarget = GetRenderTarget();
|
||||
auto m_voxelRenderTarget = m_voxel->GetRenderTarget();
|
||||
switch (_drawStep) {
|
||||
case DrawStep::DrawLogo:
|
||||
m_pRenderTarget->BeginDraw();
|
||||
drawBackground(m_pRenderTarget);
|
||||
m_pRenderTarget->EndDraw();
|
||||
m_voxelRenderTarget->BeginDraw();
|
||||
drawLogo(m_voxelRenderTarget);
|
||||
m_voxelRenderTarget->EndDraw();
|
||||
break;
|
||||
case DrawStep::DrawLoginLogin:
|
||||
case DrawStep::DrawLoginErrorOrg:
|
||||
case DrawStep::DrawLoginErrorCred:
|
||||
prepareLogin(_drawStep);
|
||||
m_pRenderTarget->BeginDraw();
|
||||
drawBackground(m_pRenderTarget);
|
||||
drawSmallLogo(m_pRenderTarget);
|
||||
m_pRenderTarget->EndDraw();
|
||||
RedrawWindow();
|
||||
break;
|
||||
case DrawStep::DrawChoose:
|
||||
prepareChoose();
|
||||
m_pRenderTarget->BeginDraw();
|
||||
drawBackground(m_pRenderTarget);
|
||||
drawSmallLogo(m_pRenderTarget);
|
||||
m_pRenderTarget->EndDraw();
|
||||
RedrawWindow();
|
||||
break;
|
||||
case DrawStep::DrawProcessFinishHq:
|
||||
case DrawStep::DrawProcessFinishUpdate:
|
||||
case DrawStep::DrawProcessUpdate:
|
||||
case DrawStep::DrawProcessUninstall:
|
||||
case DrawStep::DrawProcessSetup:
|
||||
if (!isUpdate) {
|
||||
m_voxelRenderTarget->BeginDraw();
|
||||
m_voxelRenderTarget->Clear(D2D1::ColorF(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
m_voxelRenderTarget->EndDraw();
|
||||
m_pRenderTarget->BeginDraw();
|
||||
prepareProcess(_drawStep);
|
||||
drawBackground(m_pRenderTarget);
|
||||
drawSmallLogo(m_pRenderTarget);
|
||||
m_pRenderTarget->EndDraw();
|
||||
RedrawWindow();
|
||||
}
|
||||
m_voxelRenderTarget->BeginDraw();
|
||||
drawVoxel(m_voxelRenderTarget);
|
||||
m_voxelRenderTarget->EndDraw();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_drawStep = step;
|
||||
auto m_pRenderTarget = GetRenderTarget();
|
||||
auto m_voxelRenderTarget = m_voxel->GetRenderTarget();
|
||||
switch (_drawStep) {
|
||||
case DrawStep::DrawLogo:
|
||||
m_pRenderTarget->BeginDraw();
|
||||
drawBackground(m_pRenderTarget);
|
||||
m_pRenderTarget->EndDraw();
|
||||
m_voxelRenderTarget->BeginDraw();
|
||||
drawLogo(m_voxelRenderTarget);
|
||||
m_voxelRenderTarget->EndDraw();
|
||||
break;
|
||||
case DrawStep::DrawLoginLogin:
|
||||
case DrawStep::DrawLoginErrorOrg:
|
||||
case DrawStep::DrawLoginErrorCred:
|
||||
prepareLogin(_drawStep);
|
||||
m_pRenderTarget->BeginDraw();
|
||||
drawBackground(m_pRenderTarget);
|
||||
drawSmallLogo(m_pRenderTarget);
|
||||
m_pRenderTarget->EndDraw();
|
||||
RedrawWindow();
|
||||
break;
|
||||
case DrawStep::DrawChoose:
|
||||
prepareChoose();
|
||||
m_pRenderTarget->BeginDraw();
|
||||
drawBackground(m_pRenderTarget);
|
||||
drawSmallLogo(m_pRenderTarget);
|
||||
m_pRenderTarget->EndDraw();
|
||||
RedrawWindow();
|
||||
break;
|
||||
case DrawStep::DrawProcessFinishHq:
|
||||
case DrawStep::DrawProcessFinishUpdate:
|
||||
case DrawStep::DrawProcessUpdate:
|
||||
case DrawStep::DrawProcessUninstall:
|
||||
case DrawStep::DrawProcessSetup:
|
||||
if (!isUpdate) {
|
||||
m_voxelRenderTarget->BeginDraw();
|
||||
m_voxelRenderTarget->Clear(D2D1::ColorF(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
m_voxelRenderTarget->EndDraw();
|
||||
m_pRenderTarget->BeginDraw();
|
||||
prepareProcess(_drawStep);
|
||||
drawBackground(m_pRenderTarget);
|
||||
drawSmallLogo(m_pRenderTarget);
|
||||
m_pRenderTarget->EndDraw();
|
||||
RedrawWindow();
|
||||
}
|
||||
m_voxelRenderTarget->BeginDraw();
|
||||
drawVoxel(m_voxelRenderTarget);
|
||||
m_voxelRenderTarget->EndDraw();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,109 +13,109 @@
|
|||
// CLauncherDlg dialog
|
||||
class CLauncherDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
// Construction
|
||||
public:
|
||||
enum DrawStep {
|
||||
DrawLogo = 0,
|
||||
DrawLoginLogin,
|
||||
DrawLoginErrorOrg,
|
||||
DrawLoginErrorCred,
|
||||
DrawChoose,
|
||||
DrawProcessSetup,
|
||||
DrawProcessUpdate,
|
||||
DrawProcessFinishHq,
|
||||
DrawProcessFinishUpdate,
|
||||
DrawProcessUninstall,
|
||||
DrawError
|
||||
};
|
||||
enum DrawStep {
|
||||
DrawLogo = 0,
|
||||
DrawLoginLogin,
|
||||
DrawLoginErrorOrg,
|
||||
DrawLoginErrorCred,
|
||||
DrawChoose,
|
||||
DrawProcessSetup,
|
||||
DrawProcessUpdate,
|
||||
DrawProcessFinishHq,
|
||||
DrawProcessFinishUpdate,
|
||||
DrawProcessUninstall,
|
||||
DrawError
|
||||
};
|
||||
|
||||
struct TextFormat {
|
||||
int size;
|
||||
COLORREF color;
|
||||
bool isButton;
|
||||
bool isBold;
|
||||
bool underlined;
|
||||
};
|
||||
struct TextFormat {
|
||||
int size;
|
||||
COLORREF color;
|
||||
bool isButton;
|
||||
bool isBold;
|
||||
bool underlined;
|
||||
};
|
||||
|
||||
CLauncherDlg(CWnd* pParent = nullptr);
|
||||
CLauncherDlg(CWnd* pParent = nullptr);
|
||||
~CLauncherDlg();
|
||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||
|
||||
void setDrawDialog(DrawStep step, BOOL isUpdate = FALSE);
|
||||
void setDrawDialog(DrawStep step, BOOL isUpdate = FALSE);
|
||||
|
||||
|
||||
// Dialog Data
|
||||
#ifdef AFX_DESIGN_TIME
|
||||
enum { IDD = IDD_LAUNCHER_DIALOG };
|
||||
enum { IDD = IDD_LAUNCHER_DIALOG };
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
void startProcess();
|
||||
void setCustomDialog();
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
void startProcess();
|
||||
void setCustomDialog();
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
BOOL getHQInfo(const CString& orgname);
|
||||
DrawStep _drawStep { DrawStep::DrawLogo };
|
||||
BOOL getTextFormat(int ResID, TextFormat& formatOut);
|
||||
void showWindows(std::vector<CStatic*> windows, bool show);
|
||||
BOOL getHQInfo(const CString& orgname);
|
||||
DrawStep _drawStep { DrawStep::DrawLogo };
|
||||
BOOL getTextFormat(int ResID, TextFormat& formatOut);
|
||||
void showWindows(std::vector<CStatic*> windows, bool show);
|
||||
|
||||
bool _isConsoleRunning{ false };
|
||||
bool _isInstalling{ false };
|
||||
bool _isFirstDraw{ false };
|
||||
bool _showSplash{ true };
|
||||
int _splashStep{ 0 };
|
||||
float _logoRotation { 0.0f };
|
||||
bool _isConsoleRunning{ false };
|
||||
bool _isInstalling{ false };
|
||||
bool _isFirstDraw{ false };
|
||||
bool _showSplash{ true };
|
||||
int _splashStep{ 0 };
|
||||
float _logoRotation { 0.0f };
|
||||
|
||||
HICON m_hIcon;
|
||||
CButton m_btnNext;
|
||||
CButton m_trouble_link;
|
||||
|
||||
CStatic* m_message_label;
|
||||
CStatic* m_action_label;
|
||||
CStatic* m_message2_label;
|
||||
CStatic* m_action2_label;
|
||||
CStatic* m_terms;
|
||||
CStatic* m_terms2;
|
||||
CStatic* m_trouble;
|
||||
CStatic* m_voxel;
|
||||
HICON m_hIcon;
|
||||
CButton m_btnNext;
|
||||
CButton m_trouble_link;
|
||||
|
||||
CStatic* m_message_label;
|
||||
CStatic* m_action_label;
|
||||
CStatic* m_message2_label;
|
||||
CStatic* m_action2_label;
|
||||
CStatic* m_terms;
|
||||
CStatic* m_terms2;
|
||||
CStatic* m_trouble;
|
||||
CStatic* m_voxel;
|
||||
|
||||
CEdit m_orgname;
|
||||
CEdit m_username;
|
||||
CEdit m_password;
|
||||
CEdit m_orgname;
|
||||
CEdit m_username;
|
||||
CEdit m_password;
|
||||
|
||||
CStatic* m_orgname_banner;
|
||||
CStatic* m_username_banner;
|
||||
CStatic* m_password_banner;
|
||||
CStatic* m_orgname_banner;
|
||||
CStatic* m_username_banner;
|
||||
CStatic* m_password_banner;
|
||||
|
||||
void drawBackground(CHwndRenderTarget* pRenderTarget);
|
||||
void drawLogo(CHwndRenderTarget* pRenderTarget);
|
||||
void drawSmallLogo(CHwndRenderTarget* pRenderTarget);
|
||||
void drawVoxel(CHwndRenderTarget* pRenderTarget);
|
||||
void drawBackground(CHwndRenderTarget* pRenderTarget);
|
||||
void drawLogo(CHwndRenderTarget* pRenderTarget);
|
||||
void drawSmallLogo(CHwndRenderTarget* pRenderTarget);
|
||||
void drawVoxel(CHwndRenderTarget* pRenderTarget);
|
||||
|
||||
void prepareLogin(DrawStep step);
|
||||
void prepareProcess(DrawStep step);
|
||||
void prepareChoose();
|
||||
void prepareError();
|
||||
void prepareLogin(DrawStep step);
|
||||
void prepareProcess(DrawStep step);
|
||||
void prepareChoose();
|
||||
void prepareError();
|
||||
|
||||
void redrawBanner(const CEdit& edit, CStatic* banner);
|
||||
void redrawBanner(const CEdit& edit, CStatic* banner);
|
||||
|
||||
// Generated message map functions
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
|
||||
afx_msg void OnPaint();
|
||||
afx_msg HCURSOR OnQueryDragIcon();
|
||||
afx_msg void OnNextClicked();
|
||||
afx_msg void OnTroubleClicked();
|
||||
afx_msg void OnOrgEditChangeFocus();
|
||||
afx_msg void OnUserEditChangeFocus();
|
||||
afx_msg void OnPassEditChangeFocus();
|
||||
afx_msg void OnTimer(UINT_PTR nIDEvent);
|
||||
DECLARE_MESSAGE_MAP()
|
||||
// Generated message map functions
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
|
||||
afx_msg void OnPaint();
|
||||
afx_msg HCURSOR OnQueryDragIcon();
|
||||
afx_msg void OnNextClicked();
|
||||
afx_msg void OnTroubleClicked();
|
||||
afx_msg void OnOrgEditChangeFocus();
|
||||
afx_msg void OnUserEditChangeFocus();
|
||||
afx_msg void OnPassEditChangeFocus();
|
||||
afx_msg void OnTimer(UINT_PTR nIDEvent);
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
|
||||
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
|
||||
};
|
||||
|
|
|
@ -76,396 +76,399 @@ void LauncherManager::closeLog() {
|
|||
|
||||
BOOL LauncherManager::installLauncher() {
|
||||
addToLog(_T("Installing Launcher."));
|
||||
CString appPath;
|
||||
BOOL result = getAndCreatePaths(PathType::Running_Path, appPath);
|
||||
if (!result) {
|
||||
MessageBox(NULL, L"Error getting app directory", L"Path Error", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
CString installDirectory;
|
||||
CString appDirectory = appPath.Left(appPath.ReverseFind('\\') + 1);
|
||||
result = getAndCreatePaths(PathType::Launcher_Directory, installDirectory);
|
||||
if (!result) {
|
||||
MessageBox(NULL, L"Error getting app desired directory", L"Path Error", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
CString appPath;
|
||||
BOOL result = getAndCreatePaths(PathType::Running_Path, appPath);
|
||||
if (!result) {
|
||||
MessageBox(NULL, L"Error getting app directory", L"Path Error", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
CString installDirectory;
|
||||
CString appDirectory = appPath.Left(appPath.ReverseFind('\\') + 1);
|
||||
result = getAndCreatePaths(PathType::Launcher_Directory, installDirectory);
|
||||
if (!result) {
|
||||
MessageBox(NULL, L"Error getting app desired directory", L"Path Error", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
|
||||
CString instalationPath = installDirectory + LAUNCHER_EXE_FILENAME;
|
||||
if (!installDirectory.Compare(appDirectory) == 0) {
|
||||
if (!_shouldUninstall) {
|
||||
// The installer is not running on the desired location and has to be installed
|
||||
// Kill of running before self-copy
|
||||
if (LauncherUtils::IsProcessRunning(LAUNCHER_EXE_FILENAME)) {
|
||||
::ShellExecute(NULL, NULL, L"taskkill", L"/F /T /IM " + LAUNCHER_EXE_FILENAME, NULL, SW_HIDE);
|
||||
}
|
||||
CopyFile(appPath, instalationPath, FALSE);
|
||||
}
|
||||
} else if (_shouldUninstall) {
|
||||
CString instalationPath = installDirectory + LAUNCHER_EXE_FILENAME;
|
||||
if (!installDirectory.Compare(appDirectory) == 0) {
|
||||
if (!_shouldUninstall) {
|
||||
// The installer is not running on the desired location and has to be installed
|
||||
// Kill of running before self-copy
|
||||
if (LauncherUtils::IsProcessRunning(LAUNCHER_EXE_FILENAME)) {
|
||||
::ShellExecute(NULL, NULL, L"taskkill", L"/F /T /IM " + LAUNCHER_EXE_FILENAME, NULL, SW_HIDE);
|
||||
}
|
||||
CopyFile(appPath, instalationPath, FALSE);
|
||||
}
|
||||
} else if (_shouldUninstall) {
|
||||
addToLog(_T("Launching uninstall mode."));
|
||||
CString tempPath;
|
||||
if (getAndCreatePaths(PathType::Temp_Directory, tempPath)) {
|
||||
tempPath += _T("\\HQ_uninstaller_tmp.exe");
|
||||
CopyFile(instalationPath, tempPath, false);
|
||||
LauncherUtils::launchApplication(tempPath, _T(" --uninstall"));
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
CString tempPath;
|
||||
if (getAndCreatePaths(PathType::Temp_Directory, tempPath)) {
|
||||
tempPath += _T("\\HQ_uninstaller_tmp.exe");
|
||||
CopyFile(instalationPath, tempPath, false);
|
||||
LauncherUtils::launchApplication(tempPath, _T(" --uninstall"));
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LauncherManager::createShortcuts() {
|
||||
CString desktopLnkPath;
|
||||
CString desktopLnkPath;
|
||||
addToLog(_T("Creating shortcuts."));
|
||||
getAndCreatePaths(PathType::Desktop_Directory, desktopLnkPath);
|
||||
desktopLnkPath += _T("\\HQ Launcher.lnk");
|
||||
CString installDir;
|
||||
getAndCreatePaths(PathType::Launcher_Directory, installDir);
|
||||
CString installPath = installDir + LAUNCHER_EXE_FILENAME;
|
||||
if (!LauncherUtils::CreateLink(installPath, (LPCSTR)CStringA(desktopLnkPath), _T("CLick to Setup and Launch HQ."))) {
|
||||
return FALSE;
|
||||
}
|
||||
CString startLinkPath;
|
||||
getAndCreatePaths(PathType::StartMenu_Directory, startLinkPath);
|
||||
CString appStartLinkPath = startLinkPath + _T("HQ Launcher.lnk");
|
||||
CString uniStartLinkPath = startLinkPath + _T("Uninstall HQ.lnk");
|
||||
CString uniLinkPath = installDir + _T("Uninstall HQ.lnk");
|
||||
if (!LauncherUtils::CreateLink(installPath, (LPCSTR)CStringA(appStartLinkPath), _T("CLick to Setup and Launch HQ."))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!LauncherUtils::CreateLink(installPath, (LPCSTR)CStringA(uniStartLinkPath), _T("CLick to Uninstall HQ."), _T("--uninstall"))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!LauncherUtils::CreateLink(installPath, (LPCSTR)CStringA(uniLinkPath), _T("CLick to Uninstall HQ."), _T("--uninstall"))) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
getAndCreatePaths(PathType::Desktop_Directory, desktopLnkPath);
|
||||
desktopLnkPath += _T("\\HQ Launcher.lnk");
|
||||
CString installDir;
|
||||
getAndCreatePaths(PathType::Launcher_Directory, installDir);
|
||||
CString installPath = installDir + LAUNCHER_EXE_FILENAME;
|
||||
if (!LauncherUtils::CreateLink(installPath, (LPCSTR)CStringA(desktopLnkPath), _T("CLick to Setup and Launch HQ."))) {
|
||||
return FALSE;
|
||||
}
|
||||
CString startLinkPath;
|
||||
getAndCreatePaths(PathType::StartMenu_Directory, startLinkPath);
|
||||
CString appStartLinkPath = startLinkPath + _T("HQ Launcher.lnk");
|
||||
CString uniStartLinkPath = startLinkPath + _T("Uninstall HQ.lnk");
|
||||
CString uniLinkPath = installDir + _T("Uninstall HQ.lnk");
|
||||
if (!LauncherUtils::CreateLink(installPath, (LPCSTR)CStringA(appStartLinkPath), _T("CLick to Setup and Launch HQ."))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!LauncherUtils::CreateLink(installPath, (LPCSTR)CStringA(uniStartLinkPath), _T("CLick to Uninstall HQ."), _T("--uninstall"))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!LauncherUtils::CreateLink(installPath, (LPCSTR)CStringA(uniLinkPath), _T("CLick to Uninstall HQ."), _T("--uninstall"))) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LauncherManager::deleteShortcuts() {
|
||||
CString desktopLnkPath;
|
||||
CString desktopLnkPath;
|
||||
addToLog(_T("Deleting shortcuts."));
|
||||
getAndCreatePaths(PathType::Desktop_Directory, desktopLnkPath);
|
||||
desktopLnkPath += _T("\\HQ Launcher.lnk");
|
||||
BOOL success = LauncherUtils::deleteFileOrDirectory(desktopLnkPath);
|
||||
CString startLinkPath;
|
||||
getAndCreatePaths(PathType::StartMenu_Directory, startLinkPath);
|
||||
return success && LauncherUtils::deleteFileOrDirectory(startLinkPath);
|
||||
getAndCreatePaths(PathType::Desktop_Directory, desktopLnkPath);
|
||||
desktopLnkPath += _T("\\HQ Launcher.lnk");
|
||||
BOOL success = LauncherUtils::deleteFileOrDirectory(desktopLnkPath);
|
||||
CString startLinkPath;
|
||||
getAndCreatePaths(PathType::StartMenu_Directory, startLinkPath);
|
||||
return success && LauncherUtils::deleteFileOrDirectory(startLinkPath);
|
||||
}
|
||||
|
||||
BOOL LauncherManager::isApplicationInstalled(CString& version, CString& domain,
|
||||
CString& content, bool& loggedIn) {
|
||||
CString applicationDir;
|
||||
getAndCreatePaths(PathType::Launcher_Directory, applicationDir);
|
||||
CString applicationPath = applicationDir + "interface\\interface.exe";
|
||||
BOOL isApplicationInstalled = PathFileExistsW(applicationPath);
|
||||
BOOL configFileExist = PathFileExistsW(applicationDir + _T("interface\\config.json"));
|
||||
if (isApplicationInstalled && configFileExist) {
|
||||
LauncherUtils::ResponseError status = readConfigJSON(version, domain, content, loggedIn);
|
||||
return status == LauncherUtils::ResponseError::NoError;
|
||||
}
|
||||
return FALSE;
|
||||
CString& content, bool& loggedIn) {
|
||||
CString applicationDir;
|
||||
getAndCreatePaths(PathType::Launcher_Directory, applicationDir);
|
||||
CString applicationPath = applicationDir + "interface\\interface.exe";
|
||||
BOOL isApplicationInstalled = PathFileExistsW(applicationPath);
|
||||
BOOL configFileExist = PathFileExistsW(applicationDir + _T("interface\\config.json"));
|
||||
if (isApplicationInstalled && configFileExist) {
|
||||
LauncherUtils::ResponseError status = readConfigJSON(version, domain, content, loggedIn);
|
||||
return status == LauncherUtils::ResponseError::NoError;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LauncherManager::getAndCreatePaths(PathType type, CString& outPath) {
|
||||
|
||||
if (type == PathType::Running_Path) {
|
||||
char appPath[MAX_PATH];
|
||||
DWORD size = GetModuleFileNameA(NULL, appPath, MAX_PATH);
|
||||
if (size) {
|
||||
outPath = CString(appPath);
|
||||
return TRUE;
|
||||
}
|
||||
} else if (type == PathType::Desktop_Directory) {
|
||||
TCHAR desktopPath[MAX_PATH];
|
||||
auto success = SUCCEEDED(SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, desktopPath));
|
||||
outPath = CString(desktopPath);
|
||||
return success;
|
||||
} else if (type == PathType::Temp_Directory) {
|
||||
TCHAR tempPath[MAX_PATH];
|
||||
auto success = GetTempPath(MAX_PATH, tempPath);
|
||||
outPath = CString(tempPath);
|
||||
return success;
|
||||
} else {
|
||||
TCHAR localDataPath[MAX_PATH];
|
||||
if (type == PathType::StartMenu_Directory) {
|
||||
TCHAR startMenuPath[MAX_PATH];
|
||||
auto success = SUCCEEDED(SHGetFolderPath(NULL, CSIDL_STARTMENU, NULL, 0, startMenuPath));
|
||||
outPath = CString(startMenuPath) + _T("\\Programs\\HQ\\");
|
||||
success = SHCreateDirectoryEx(NULL, outPath, NULL) || ERROR_ALREADY_EXISTS == GetLastError();
|
||||
return success;
|
||||
} else if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, localDataPath))) {
|
||||
_tcscat_s(localDataPath, _T("\\") + DIRECTORY_NAME_APP + _T("\\"));
|
||||
outPath = CString(localDataPath);
|
||||
if (type == PathType::Download_Directory) {
|
||||
outPath += DIRECTORY_NAME_DOWNLOADS + _T("\\");
|
||||
} else if (type == PathType::Interface_Directory) {
|
||||
outPath += DIRECTORY_NAME_INTERFACE;
|
||||
} else if (type == PathType::Content_Directory) {
|
||||
outPath += DIRECTORY_NAME_CONTENT;
|
||||
}
|
||||
return (CreateDirectory(outPath, NULL) || ERROR_ALREADY_EXISTS == GetLastError());
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
if (type == PathType::Running_Path) {
|
||||
char appPath[MAX_PATH];
|
||||
DWORD size = GetModuleFileNameA(NULL, appPath, MAX_PATH);
|
||||
if (size) {
|
||||
outPath = CString(appPath);
|
||||
return TRUE;
|
||||
}
|
||||
} else if (type == PathType::Desktop_Directory) {
|
||||
TCHAR desktopPath[MAX_PATH];
|
||||
auto success = SUCCEEDED(SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, desktopPath));
|
||||
outPath = CString(desktopPath);
|
||||
return success;
|
||||
} else if (type == PathType::Temp_Directory) {
|
||||
TCHAR tempPath[MAX_PATH];
|
||||
auto success = GetTempPath(MAX_PATH, tempPath);
|
||||
outPath = CString(tempPath);
|
||||
return success;
|
||||
} else {
|
||||
TCHAR localDataPath[MAX_PATH];
|
||||
if (type == PathType::StartMenu_Directory) {
|
||||
TCHAR startMenuPath[MAX_PATH];
|
||||
auto success = SUCCEEDED(SHGetFolderPath(NULL, CSIDL_STARTMENU, NULL, 0, startMenuPath));
|
||||
outPath = CString(startMenuPath) + _T("\\Programs\\HQ\\");
|
||||
success = SHCreateDirectoryEx(NULL, outPath, NULL) || ERROR_ALREADY_EXISTS == GetLastError();
|
||||
return success;
|
||||
} else if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, localDataPath))) {
|
||||
_tcscat_s(localDataPath, _T("\\") + DIRECTORY_NAME_APP + _T("\\"));
|
||||
outPath = CString(localDataPath);
|
||||
if (type == PathType::Download_Directory) {
|
||||
outPath += DIRECTORY_NAME_DOWNLOADS + _T("\\");
|
||||
} else if (type == PathType::Interface_Directory) {
|
||||
outPath += DIRECTORY_NAME_INTERFACE;
|
||||
} else if (type == PathType::Content_Directory) {
|
||||
outPath += DIRECTORY_NAME_CONTENT;
|
||||
}
|
||||
return (CreateDirectory(outPath, NULL) || ERROR_ALREADY_EXISTS == GetLastError());
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LauncherManager::getInstalledVersion(const CString& path, CString& version) {
|
||||
CStdioFile cfile;
|
||||
BOOL success = cfile.Open(path, CFile::modeRead);
|
||||
if (success) {
|
||||
cfile.ReadString(version);
|
||||
cfile.Close();
|
||||
}
|
||||
return success;
|
||||
CStdioFile cfile;
|
||||
BOOL success = cfile.Open(path, CFile::modeRead);
|
||||
if (success) {
|
||||
cfile.ReadString(version);
|
||||
cfile.Close();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
BOOL LauncherManager::launchApplication(const CString& tokensJSON) {
|
||||
CString installDir;
|
||||
LauncherManager::getAndCreatePaths(PathType::Interface_Directory, installDir);
|
||||
CString interfaceExe = installDir + _T("\\interface.exe");
|
||||
CString params1 = _T("--url \"") + _domainURL + ("\" ");
|
||||
CString cacheDir;
|
||||
LauncherManager::getAndCreatePaths(PathType::Content_Directory, cacheDir);
|
||||
CString params3 = _T("--cache \"") + cacheDir + ("\" ");
|
||||
CString params4 = !_displayName.IsEmpty() ? _T("--displayName \"") + _displayName + ("\" ") : _T("");
|
||||
CString parsedTokens = tokensJSON;
|
||||
parsedTokens.Replace(_T("\""), _T("\\\""));
|
||||
CString params5 = !tokensJSON.IsEmpty() ? _T("--tokens \"") + parsedTokens + ("\"") : _T("");
|
||||
CString params = params1 + params3 + params4 + params5 + EXTRA_PARAMETERS;
|
||||
auto rs = ShellExecute(NULL, L"open", interfaceExe, params, NULL, SW_SHOW);
|
||||
return (rs != NULL);
|
||||
CString installDir;
|
||||
LauncherManager::getAndCreatePaths(PathType::Interface_Directory, installDir);
|
||||
CString interfaceExe = installDir + _T("\\interface.exe");
|
||||
CString params1 = _T("--url \"") + _domainURL + ("\" ");
|
||||
CString scriptsURL = installDir + _T("\\scripts\\simplifiedUI");
|
||||
CString params2 = _T("--scripts \"") + scriptsURL + ("\" ");
|
||||
CString cacheDir;
|
||||
LauncherManager::getAndCreatePaths(PathType::Content_Directory, cacheDir);
|
||||
CString params3 = _T("--cache \"") + cacheDir + ("\" ");
|
||||
CString params4 = !_displayName.IsEmpty() ? _T("--displayName \"") + _displayName + ("\" ") : _T("");
|
||||
CString parsedTokens = tokensJSON;
|
||||
parsedTokens.Replace(_T("\""), _T("\\\""));
|
||||
CString params5 = !tokensJSON.IsEmpty() ? _T("--tokens \"") + parsedTokens + ("\"") : _T("");
|
||||
CString params = params1 + params2 + params3 + params4 + params5 + EXTRA_PARAMETERS;
|
||||
|
||||
auto rs = ShellExecute(NULL, L"open", interfaceExe, params, NULL, SW_SHOW);
|
||||
return (rs != NULL);
|
||||
}
|
||||
|
||||
BOOL LauncherManager::createConfigJSON() {
|
||||
CString configPath;
|
||||
LauncherManager::getAndCreatePaths(PathType::Interface_Directory, configPath);
|
||||
configPath += "\\config.json";
|
||||
std::ofstream configFile(configPath, std::ofstream::binary);
|
||||
if (configFile.fail()) {
|
||||
return FALSE;
|
||||
}
|
||||
Json::Value config;
|
||||
CString applicationPath;
|
||||
LauncherManager::getAndCreatePaths(PathType::Launcher_Directory, applicationPath);
|
||||
applicationPath += LAUNCHER_EXE_FILENAME;
|
||||
config["loggedIn"] = _loggedIn;
|
||||
config["launcherPath"] = LauncherUtils::cStringToStd(applicationPath);
|
||||
config["version"] = LauncherUtils::cStringToStd(_latestVersion);
|
||||
config["domain"] = LauncherUtils::cStringToStd(_domainURL);
|
||||
CString content;
|
||||
getAndCreatePaths(PathType::Content_Directory, content);
|
||||
config["content"] = LauncherUtils::cStringToStd(content);
|
||||
configFile << config;
|
||||
configFile.close();
|
||||
return TRUE;
|
||||
CString configPath;
|
||||
LauncherManager::getAndCreatePaths(PathType::Interface_Directory, configPath);
|
||||
configPath += "\\config.json";
|
||||
std::ofstream configFile(configPath, std::ofstream::binary);
|
||||
if (configFile.fail()) {
|
||||
return FALSE;
|
||||
}
|
||||
Json::Value config;
|
||||
CString applicationPath;
|
||||
LauncherManager::getAndCreatePaths(PathType::Launcher_Directory, applicationPath);
|
||||
applicationPath += LAUNCHER_EXE_FILENAME;
|
||||
config["loggedIn"] = _loggedIn;
|
||||
config["launcherPath"] = LauncherUtils::cStringToStd(applicationPath);
|
||||
config["version"] = LauncherUtils::cStringToStd(_latestVersion);
|
||||
config["domain"] = LauncherUtils::cStringToStd(_domainURL);
|
||||
CString content;
|
||||
getAndCreatePaths(PathType::Content_Directory, content);
|
||||
config["content"] = LauncherUtils::cStringToStd(content);
|
||||
configFile << config;
|
||||
configFile.close();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LauncherUtils::ResponseError LauncherManager::readConfigJSON(CString& version, CString& domain, CString& content, bool& loggedIn) {
|
||||
CString configPath;
|
||||
getAndCreatePaths(PathType::Interface_Directory, configPath);
|
||||
configPath += "\\config.json";
|
||||
std::ifstream configFile(configPath, std::ifstream::binary);
|
||||
if (configFile.fail()) {
|
||||
return LauncherUtils::ResponseError::Open;
|
||||
}
|
||||
Json::Value config;
|
||||
configFile >> config;
|
||||
if (config["version"].isString() && config["domain"].isString() &&
|
||||
config["content"].isString()) {
|
||||
loggedIn = config["loggedIn"].asBool();
|
||||
version = config["version"].asCString();
|
||||
domain = config["domain"].asCString();
|
||||
content = config["content"].asCString();
|
||||
configFile.close();
|
||||
return LauncherUtils::ResponseError::NoError;
|
||||
}
|
||||
configFile.close();
|
||||
return LauncherUtils::ResponseError::ParsingJSON;
|
||||
CString configPath;
|
||||
getAndCreatePaths(PathType::Interface_Directory, configPath);
|
||||
configPath += "\\config.json";
|
||||
std::ifstream configFile(configPath, std::ifstream::binary);
|
||||
if (configFile.fail()) {
|
||||
return LauncherUtils::ResponseError::Open;
|
||||
}
|
||||
Json::Value config;
|
||||
configFile >> config;
|
||||
if (config["version"].isString() && config["domain"].isString() &&
|
||||
config["content"].isString()) {
|
||||
loggedIn = config["loggedIn"].asBool();
|
||||
version = config["version"].asCString();
|
||||
domain = config["domain"].asCString();
|
||||
content = config["content"].asCString();
|
||||
configFile.close();
|
||||
return LauncherUtils::ResponseError::NoError;
|
||||
}
|
||||
configFile.close();
|
||||
return LauncherUtils::ResponseError::ParsingJSON;
|
||||
}
|
||||
|
||||
LauncherUtils::ResponseError LauncherManager::readOrganizationJSON(const CString& hash) {
|
||||
CString contentTypeJson = L"content-type:application/json";
|
||||
CString response;
|
||||
CString url = _T("/hifi-public/huffman/organizations/") + hash + _T(".json");
|
||||
LauncherUtils::ResponseError error = LauncherUtils::makeHTTPCall(L"HQ Launcher", L"s3.amazonaws.com", url,
|
||||
contentTypeJson, CStringA(), response, false);
|
||||
if (error != LauncherUtils::ResponseError::NoError) {
|
||||
return error;
|
||||
}
|
||||
Json::Value json;
|
||||
if (LauncherUtils::parseJSON(response, json)) {
|
||||
if (json["content_set_url"].isString() && json["domain"].isString()) {
|
||||
_contentURL = json["content_set_url"].asCString();
|
||||
_domainURL = json["domain"].asCString();
|
||||
return LauncherUtils::ResponseError::NoError;
|
||||
}
|
||||
}
|
||||
return LauncherUtils::ResponseError::ParsingJSON;
|
||||
CString contentTypeJson = L"content-type:application/json";
|
||||
CString response;
|
||||
CString url = _T("/hifi-public/huffman/organizations/") + hash + _T(".json");
|
||||
LauncherUtils::ResponseError error = LauncherUtils::makeHTTPCall(L"HQ Launcher", L"s3.amazonaws.com", url,
|
||||
contentTypeJson, CStringA(), response, false);
|
||||
if (error != LauncherUtils::ResponseError::NoError) {
|
||||
return error;
|
||||
}
|
||||
Json::Value json;
|
||||
if (LauncherUtils::parseJSON(response, json)) {
|
||||
if (json["content_set_url"].isString() && json["domain"].isString()) {
|
||||
_contentURL = json["content_set_url"].asCString();
|
||||
_domainURL = json["domain"].asCString();
|
||||
return LauncherUtils::ResponseError::NoError;
|
||||
}
|
||||
}
|
||||
return LauncherUtils::ResponseError::ParsingJSON;
|
||||
}
|
||||
|
||||
LauncherUtils::ResponseError LauncherManager::getMostRecentBuild(CString& urlOut, CString& versionOut) {
|
||||
CString contentTypeJson = L"content-type:application/json";
|
||||
CString response;
|
||||
LauncherUtils::ResponseError error = LauncherUtils::makeHTTPCall(L"HQ Launcher", L"thunder.highfidelity.com", L"/builds/api/tags/latest?format=json",
|
||||
contentTypeJson, CStringA(), response, false);
|
||||
if (error != LauncherUtils::ResponseError::NoError) {
|
||||
return error;
|
||||
}
|
||||
Json::Value json;
|
||||
if (LauncherUtils::parseJSON(response, json)) {
|
||||
int count = json["count"].isInt() ? json["count"].asInt() : 0;
|
||||
if (count > 0 && json["results"].isArray()) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (json["results"][i].isObject()) {
|
||||
Json::Value result = json["results"][i];
|
||||
if (result["latest_version"].isInt()) {
|
||||
std::string version = std::to_string(result["latest_version"].asInt());
|
||||
versionOut = CString(version.c_str());
|
||||
}
|
||||
if (result["installers"].isObject() &&
|
||||
result["installers"]["windows"].isObject() &&
|
||||
result["installers"]["windows"]["zip_url"].isString()) {
|
||||
urlOut = result["installers"]["windows"]["zip_url"].asCString();
|
||||
return LauncherUtils::ResponseError::NoError;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return LauncherUtils::ResponseError::ParsingJSON;
|
||||
CString contentTypeJson = L"content-type:application/json";
|
||||
CString response;
|
||||
LauncherUtils::ResponseError error = LauncherUtils::makeHTTPCall(L"HQ Launcher", L"thunder.highfidelity.com", L"/builds/api/tags/latest?format=json",
|
||||
contentTypeJson, CStringA(), response, false);
|
||||
if (error != LauncherUtils::ResponseError::NoError) {
|
||||
return error;
|
||||
}
|
||||
Json::Value json;
|
||||
if (LauncherUtils::parseJSON(response, json)) {
|
||||
int count = json["count"].isInt() ? json["count"].asInt() : 0;
|
||||
if (count > 0 && json["results"].isArray()) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (json["results"][i].isObject()) {
|
||||
Json::Value result = json["results"][i];
|
||||
if (result["latest_version"].isInt()) {
|
||||
std::string version = std::to_string(result["latest_version"].asInt());
|
||||
versionOut = CString(version.c_str());
|
||||
}
|
||||
if (result["installers"].isObject() &&
|
||||
result["installers"]["windows"].isObject() &&
|
||||
result["installers"]["windows"]["zip_url"].isString()) {
|
||||
urlOut = result["installers"]["windows"]["zip_url"].asCString();
|
||||
return LauncherUtils::ResponseError::NoError;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return LauncherUtils::ResponseError::ParsingJSON;
|
||||
}
|
||||
|
||||
LauncherUtils::ResponseError LauncherManager::getAccessTokenForCredentials(const CString& username, const CString& password) {
|
||||
CStringA post = "grant_type=password&username=";
|
||||
post += username;
|
||||
post += "&password=";
|
||||
post += password;
|
||||
post += "&scope=owner";
|
||||
CStringA post = "grant_type=password&username=";
|
||||
post += username;
|
||||
post += "&password=";
|
||||
post += password;
|
||||
post += "&scope=owner";
|
||||
|
||||
CString contentTypeText = L"content-type:application/x-www-form-urlencoded";
|
||||
CString response;
|
||||
LauncherUtils::ResponseError error = LauncherUtils::makeHTTPCall(L"HQ Launcher", L"metaverse.highfidelity.com", L"/oauth/token",
|
||||
contentTypeText, post, response, true);
|
||||
if (error != LauncherUtils::ResponseError::NoError) {
|
||||
return error;
|
||||
}
|
||||
Json::Value json;
|
||||
if (LauncherUtils::parseJSON(response, json)) {
|
||||
if (json["error"].isString()) {
|
||||
return LauncherUtils::ResponseError::BadCredentials;
|
||||
} else if (json["access_token"].isString()) {
|
||||
_tokensJSON = response;
|
||||
return LauncherUtils::ResponseError::NoError;
|
||||
}
|
||||
}
|
||||
return LauncherUtils::ResponseError::ParsingJSON;
|
||||
CString contentTypeText = L"content-type:application/x-www-form-urlencoded";
|
||||
CString response;
|
||||
LauncherUtils::ResponseError error = LauncherUtils::makeHTTPCall(L"HQ Launcher", L"metaverse.highfidelity.com", L"/oauth/token",
|
||||
contentTypeText, post, response, true);
|
||||
if (error != LauncherUtils::ResponseError::NoError) {
|
||||
return error;
|
||||
}
|
||||
Json::Value json;
|
||||
if (LauncherUtils::parseJSON(response, json)) {
|
||||
if (json["error"].isString()) {
|
||||
return LauncherUtils::ResponseError::BadCredentials;
|
||||
} else if (json["access_token"].isString()) {
|
||||
_tokensJSON = response;
|
||||
return LauncherUtils::ResponseError::NoError;
|
||||
}
|
||||
}
|
||||
return LauncherUtils::ResponseError::ParsingJSON;
|
||||
}
|
||||
|
||||
BOOL LauncherManager::createApplicationRegistryKeys(int size) {
|
||||
const std::string REGISTRY_PATH = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\HQ";
|
||||
BOOL success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "DisplayName", "HQ");
|
||||
CString installDir;
|
||||
getAndCreatePaths(PathType::Launcher_Directory, installDir);
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "InstallLocation", LauncherUtils::cStringToStd(installDir));
|
||||
std::string applicationExe = LauncherUtils::cStringToStd(installDir + LAUNCHER_EXE_FILENAME);
|
||||
std::string uninstallPath = '"' + applicationExe + '"' + " --uninstall";
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "UninstallString", uninstallPath);
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "DisplayVersion", LauncherUtils::cStringToStd(_latestVersion));
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "DisplayIcon", applicationExe);
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "Publisher", "High Fidelity");
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "InstallDate", LauncherUtils::cStringToStd(CTime::GetCurrentTime().Format("%Y%m%d")));
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "EstimatedSize", (DWORD)size);
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "NoModify", (DWORD)1);
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "NoRepair", (DWORD)1);
|
||||
return success;
|
||||
const std::string REGISTRY_PATH = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\HQ";
|
||||
BOOL success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "DisplayName", "HQ");
|
||||
CString installDir;
|
||||
getAndCreatePaths(PathType::Launcher_Directory, installDir);
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "InstallLocation", LauncherUtils::cStringToStd(installDir));
|
||||
std::string applicationExe = LauncherUtils::cStringToStd(installDir + LAUNCHER_EXE_FILENAME);
|
||||
std::string uninstallPath = '"' + applicationExe + '"' + " --uninstall";
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "UninstallString", uninstallPath);
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "DisplayVersion", LauncherUtils::cStringToStd(_latestVersion));
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "DisplayIcon", applicationExe);
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "Publisher", "High Fidelity");
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "InstallDate", LauncherUtils::cStringToStd(CTime::GetCurrentTime().Format("%Y%m%d")));
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "EstimatedSize", (DWORD)size);
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "NoModify", (DWORD)1);
|
||||
success = LauncherUtils::insertRegistryKey(REGISTRY_PATH, "NoRepair", (DWORD)1);
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL LauncherManager::deleteApplicationRegistryKeys() {
|
||||
const CString REGISTRY_PATH = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\HQ");
|
||||
return LauncherUtils::deleteRegistryKey(REGISTRY_PATH);
|
||||
const CString REGISTRY_PATH = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\HQ");
|
||||
return LauncherUtils::deleteRegistryKey(REGISTRY_PATH);
|
||||
}
|
||||
|
||||
BOOL LauncherManager::uninstallApplication() {
|
||||
CString installDir;
|
||||
getAndCreatePaths(PathType::Launcher_Directory, installDir);
|
||||
BOOL success = LauncherUtils::deleteFileOrDirectory(installDir);
|
||||
success = success && (deleteShortcuts());
|
||||
success = success && (deleteApplicationRegistryKeys());
|
||||
return success;
|
||||
CString installDir;
|
||||
getAndCreatePaths(PathType::Launcher_Directory, installDir);
|
||||
BOOL success = LauncherUtils::deleteFileOrDirectory(installDir);
|
||||
success = success && (deleteShortcuts());
|
||||
success = success && (deleteApplicationRegistryKeys());
|
||||
return success;
|
||||
}
|
||||
|
||||
void LauncherManager::onZipExtracted(ZipType type, int size) {
|
||||
if (type == ZipType::ZipContent) {
|
||||
if (type == ZipType::ZipContent) {
|
||||
addToLog(_T("Downloading application."));
|
||||
downloadApplication();
|
||||
} else if (type == ZipType::ZipApplication) {
|
||||
createShortcuts();
|
||||
CString versionPath;
|
||||
getAndCreatePaths(LauncherManager::PathType::Launcher_Directory, versionPath);
|
||||
downloadApplication();
|
||||
} else if (type == ZipType::ZipApplication) {
|
||||
createShortcuts();
|
||||
CString versionPath;
|
||||
getAndCreatePaths(LauncherManager::PathType::Launcher_Directory, versionPath);
|
||||
addToLog(_T("Creating config.json"));
|
||||
createConfigJSON();
|
||||
addToLog(_T("Launching application."));
|
||||
launchApplication(_tokensJSON);
|
||||
launchApplication(_tokensJSON);
|
||||
addToLog(_T("Creating registry keys."));
|
||||
createApplicationRegistryKeys(size);
|
||||
_shouldShutdown = TRUE;
|
||||
}
|
||||
createApplicationRegistryKeys(size);
|
||||
_shouldShutdown = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LauncherManager::extractApplication() {
|
||||
CString installPath;
|
||||
getAndCreatePaths(LauncherManager::PathType::Interface_Directory, installPath);
|
||||
BOOL success = LauncherUtils::unzipFileOnThread(ZipType::ZipApplication, LauncherUtils::cStringToStd(_applicationZipPath),
|
||||
LauncherUtils::cStringToStd(installPath), [&](int type, int size) {
|
||||
onZipExtracted((ZipType)type, size);
|
||||
});
|
||||
return success;
|
||||
CString installPath;
|
||||
getAndCreatePaths(LauncherManager::PathType::Interface_Directory, installPath);
|
||||
BOOL success = LauncherUtils::unzipFileOnThread(ZipType::ZipApplication, LauncherUtils::cStringToStd(_applicationZipPath),
|
||||
LauncherUtils::cStringToStd(installPath), [&](int type, int size) {
|
||||
onZipExtracted((ZipType)type, size);
|
||||
});
|
||||
return success;
|
||||
}
|
||||
|
||||
void LauncherManager::onFileDownloaded(DownloadType type) {
|
||||
if (type == DownloadType::DownloadContent) {
|
||||
if (type == DownloadType::DownloadContent) {
|
||||
addToLog(_T("Installing content."));
|
||||
installContent();
|
||||
} else if (type == DownloadType::DownloadApplication) {
|
||||
installContent();
|
||||
} else if (type == DownloadType::DownloadApplication) {
|
||||
addToLog(_T("Installing application."));
|
||||
extractApplication();
|
||||
}
|
||||
extractApplication();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL LauncherManager::installContent() {
|
||||
std::string contentZipFile = LauncherUtils::cStringToStd(_contentZipPath);
|
||||
CString contentPath;
|
||||
getAndCreatePaths(LauncherManager::PathType::Content_Directory, contentPath);
|
||||
BOOL success = LauncherUtils::unzipFileOnThread(ZipType::ZipContent, contentZipFile,
|
||||
LauncherUtils::cStringToStd(contentPath), [&](int type, int size) {
|
||||
onZipExtracted((ZipType)type, size);
|
||||
});
|
||||
return success;
|
||||
std::string contentZipFile = LauncherUtils::cStringToStd(_contentZipPath);
|
||||
CString contentPath;
|
||||
getAndCreatePaths(LauncherManager::PathType::Content_Directory, contentPath);
|
||||
BOOL success = LauncherUtils::unzipFileOnThread(ZipType::ZipContent, contentZipFile,
|
||||
LauncherUtils::cStringToStd(contentPath), [&](int type, int size) {
|
||||
onZipExtracted((ZipType)type, size);
|
||||
});
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
BOOL LauncherManager::downloadFile(DownloadType type, const CString& url, CString& outPath) {
|
||||
CString fileName = url.Mid(url.ReverseFind('/') + 1);
|
||||
CString downloadDirectory;
|
||||
BOOL success = getAndCreatePaths(LauncherManager::PathType::Download_Directory, downloadDirectory);
|
||||
outPath = downloadDirectory + fileName;
|
||||
if (success) {
|
||||
if (!LauncherUtils::downloadFileOnThread(type, url, outPath, [&](int type) {
|
||||
onFileDownloaded((DownloadType)type);
|
||||
})) {
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
CString fileName = url.Mid(url.ReverseFind('/') + 1);
|
||||
CString downloadDirectory;
|
||||
BOOL success = getAndCreatePaths(LauncherManager::PathType::Download_Directory, downloadDirectory);
|
||||
outPath = downloadDirectory + fileName;
|
||||
if (success) {
|
||||
if (!LauncherUtils::downloadFileOnThread(type, url, outPath, [&](int type) {
|
||||
onFileDownloaded((DownloadType)type);
|
||||
})) {
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL LauncherManager::downloadContent() {
|
||||
addToLog(_T("Downloading content."));
|
||||
CString contentURL = getContentURL();
|
||||
return downloadFile(DownloadType::DownloadContent, contentURL, _contentZipPath);
|
||||
CString contentURL = getContentURL();
|
||||
return downloadFile(DownloadType::DownloadContent, contentURL, _contentZipPath);
|
||||
}
|
||||
|
||||
BOOL LauncherManager::downloadApplication() {
|
||||
CString applicationURL = getLatestInterfaceURL();
|
||||
return downloadFile(DownloadType::DownloadApplication, applicationURL, _applicationZipPath);
|
||||
CString applicationURL = getLatestInterfaceURL();
|
||||
return downloadFile(DownloadType::DownloadApplication, applicationURL, _applicationZipPath);
|
||||
}
|
||||
|
|
|
@ -23,91 +23,91 @@ const bool INSTALL_ZIP = true;
|
|||
class LauncherManager
|
||||
{
|
||||
public:
|
||||
enum PathType {
|
||||
Running_Path = 0,
|
||||
Launcher_Directory,
|
||||
Download_Directory,
|
||||
Interface_Directory,
|
||||
Desktop_Directory,
|
||||
Content_Directory,
|
||||
StartMenu_Directory,
|
||||
Temp_Directory
|
||||
};
|
||||
enum ZipType {
|
||||
ZipContent = 0,
|
||||
ZipApplication
|
||||
};
|
||||
enum DownloadType {
|
||||
DownloadContent = 0,
|
||||
DownloadApplication
|
||||
};
|
||||
enum ErrorType {
|
||||
ErrorNetworkAuth,
|
||||
ErrorNetworkUpdate,
|
||||
ErrorNetworkHq,
|
||||
ErrorDownloading,
|
||||
ErrorUpdating,
|
||||
ErrorInstall,
|
||||
ErrorIOFiles
|
||||
};
|
||||
LauncherManager();
|
||||
~LauncherManager();
|
||||
void init();
|
||||
enum PathType {
|
||||
Running_Path = 0,
|
||||
Launcher_Directory,
|
||||
Download_Directory,
|
||||
Interface_Directory,
|
||||
Desktop_Directory,
|
||||
Content_Directory,
|
||||
StartMenu_Directory,
|
||||
Temp_Directory
|
||||
};
|
||||
enum ZipType {
|
||||
ZipContent = 0,
|
||||
ZipApplication
|
||||
};
|
||||
enum DownloadType {
|
||||
DownloadContent = 0,
|
||||
DownloadApplication
|
||||
};
|
||||
enum ErrorType {
|
||||
ErrorNetworkAuth,
|
||||
ErrorNetworkUpdate,
|
||||
ErrorNetworkHq,
|
||||
ErrorDownloading,
|
||||
ErrorUpdating,
|
||||
ErrorInstall,
|
||||
ErrorIOFiles
|
||||
};
|
||||
LauncherManager();
|
||||
~LauncherManager();
|
||||
void init();
|
||||
BOOL initLog();
|
||||
BOOL addToLog(const CString& line);
|
||||
void closeLog();
|
||||
BOOL getAndCreatePaths(PathType type, CString& outPath);
|
||||
BOOL getInstalledVersion(const CString& path, CString& version);
|
||||
BOOL isApplicationInstalled(CString& version, CString& domain,
|
||||
CString& content, bool& loggedIn);
|
||||
LauncherUtils::ResponseError getAccessTokenForCredentials(const CString& username, const CString& password);
|
||||
LauncherUtils::ResponseError getMostRecentBuild(CString& urlOut, CString& versionOut);
|
||||
LauncherUtils::ResponseError readOrganizationJSON(const CString& hash);
|
||||
LauncherUtils::ResponseError readConfigJSON(CString& version, CString& domain,
|
||||
CString& content, bool& loggedIn);
|
||||
BOOL createConfigJSON();
|
||||
BOOL createApplicationRegistryKeys(int size);
|
||||
BOOL deleteApplicationRegistryKeys();
|
||||
BOOL createShortcuts();
|
||||
BOOL deleteShortcuts();
|
||||
BOOL launchApplication(const CString& tokensJSON = _T(""));
|
||||
BOOL uninstallApplication();
|
||||
BOOL installLauncher();
|
||||
BOOL getAndCreatePaths(PathType type, CString& outPath);
|
||||
BOOL getInstalledVersion(const CString& path, CString& version);
|
||||
BOOL isApplicationInstalled(CString& version, CString& domain,
|
||||
CString& content, bool& loggedIn);
|
||||
LauncherUtils::ResponseError getAccessTokenForCredentials(const CString& username, const CString& password);
|
||||
LauncherUtils::ResponseError getMostRecentBuild(CString& urlOut, CString& versionOut);
|
||||
LauncherUtils::ResponseError readOrganizationJSON(const CString& hash);
|
||||
LauncherUtils::ResponseError readConfigJSON(CString& version, CString& domain,
|
||||
CString& content, bool& loggedIn);
|
||||
BOOL createConfigJSON();
|
||||
BOOL createApplicationRegistryKeys(int size);
|
||||
BOOL deleteApplicationRegistryKeys();
|
||||
BOOL createShortcuts();
|
||||
BOOL deleteShortcuts();
|
||||
BOOL launchApplication(const CString& tokensJSON = _T(""));
|
||||
BOOL uninstallApplication();
|
||||
BOOL installLauncher();
|
||||
|
||||
// getters
|
||||
const CString& getContentURL() const { return _contentURL; }
|
||||
const CString& getdomainURL() const { return _domainURL; }
|
||||
const CString& getVersion() const { return _version; }
|
||||
BOOL shouldShutDown() const { return _shouldShutdown; }
|
||||
BOOL needsUpdate() { return _shouldUpdate; }
|
||||
BOOL needsUninstall() { return _shouldUninstall; }
|
||||
void setDisplayName(const CString& displayName) { _displayName = displayName; }
|
||||
bool isLoggedIn() { return _loggedIn; }
|
||||
const CString& getLatestInterfaceURL() const { return _latestApplicationURL; }
|
||||
void uninstall() { _shouldUninstall = true; };
|
||||
// getters
|
||||
const CString& getContentURL() const { return _contentURL; }
|
||||
const CString& getdomainURL() const { return _domainURL; }
|
||||
const CString& getVersion() const { return _version; }
|
||||
BOOL shouldShutDown() const { return _shouldShutdown; }
|
||||
BOOL needsUpdate() { return _shouldUpdate; }
|
||||
BOOL needsUninstall() { return _shouldUninstall; }
|
||||
void setDisplayName(const CString& displayName) { _displayName = displayName; }
|
||||
bool isLoggedIn() { return _loggedIn; }
|
||||
const CString& getLatestInterfaceURL() const { return _latestApplicationURL; }
|
||||
void uninstall() { _shouldUninstall = true; };
|
||||
|
||||
BOOL downloadFile(DownloadType type, const CString& url, CString& localPath);
|
||||
BOOL downloadContent();
|
||||
BOOL downloadApplication();
|
||||
BOOL installContent();
|
||||
BOOL extractApplication();
|
||||
void onZipExtracted(ZipType type, int size);
|
||||
void onFileDownloaded(DownloadType type);
|
||||
BOOL downloadFile(DownloadType type, const CString& url, CString& localPath);
|
||||
BOOL downloadContent();
|
||||
BOOL downloadApplication();
|
||||
BOOL installContent();
|
||||
BOOL extractApplication();
|
||||
void onZipExtracted(ZipType type, int size);
|
||||
void onFileDownloaded(DownloadType type);
|
||||
|
||||
private:
|
||||
CString _latestApplicationURL;
|
||||
CString _latestVersion;
|
||||
CString _contentURL;
|
||||
CString _domainURL;
|
||||
CString _version;
|
||||
CString _displayName;
|
||||
CString _tokensJSON;
|
||||
CString _applicationZipPath;
|
||||
CString _contentZipPath;
|
||||
bool _loggedIn{ false };
|
||||
BOOL _shouldUpdate{ FALSE };
|
||||
BOOL _shouldUninstall{ FALSE };
|
||||
BOOL _shouldShutdown{ FALSE };
|
||||
CString _latestApplicationURL;
|
||||
CString _latestVersion;
|
||||
CString _contentURL;
|
||||
CString _domainURL;
|
||||
CString _version;
|
||||
CString _displayName;
|
||||
CString _tokensJSON;
|
||||
CString _applicationZipPath;
|
||||
CString _contentZipPath;
|
||||
bool _loggedIn{ false };
|
||||
BOOL _shouldUpdate{ FALSE };
|
||||
BOOL _shouldUninstall{ FALSE };
|
||||
BOOL _shouldShutdown{ FALSE };
|
||||
CStdioFile _logFile;
|
||||
};
|
||||
|
||||
|
|
|
@ -36,360 +36,360 @@ CString LauncherUtils::urlEncodeString(const CString& url) {
|
|||
}
|
||||
|
||||
BOOL LauncherUtils::IsProcessRunning(const wchar_t *processName) {
|
||||
bool exists = false;
|
||||
PROCESSENTRY32 entry;
|
||||
entry.dwSize = sizeof(PROCESSENTRY32);
|
||||
bool exists = false;
|
||||
PROCESSENTRY32 entry;
|
||||
entry.dwSize = sizeof(PROCESSENTRY32);
|
||||
|
||||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
|
||||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
|
||||
|
||||
if (Process32First(snapshot, &entry)) {
|
||||
while (Process32Next(snapshot, &entry)) {
|
||||
if (!_wcsicmp(entry.szExeFile, processName)) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(snapshot);
|
||||
return exists;
|
||||
if (Process32First(snapshot, &entry)) {
|
||||
while (Process32Next(snapshot, &entry)) {
|
||||
if (!_wcsicmp(entry.szExeFile, processName)) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(snapshot);
|
||||
return exists;
|
||||
}
|
||||
|
||||
HRESULT LauncherUtils::CreateLink(LPCWSTR lpszPathObj, LPCSTR lpszPathLink, LPCWSTR lpszDesc, LPCWSTR lpszArgs) {
|
||||
IShellLink* psl;
|
||||
IShellLink* psl;
|
||||
|
||||
// Get a pointer to the IShellLink interface. It is assumed that CoInitialize
|
||||
// has already been called.
|
||||
CoInitialize(NULL);
|
||||
HRESULT hres = E_INVALIDARG;
|
||||
if ((lpszPathObj != NULL) && (wcslen(lpszPathObj) > 0) &&
|
||||
(lpszDesc != NULL) &&
|
||||
(lpszPathLink != NULL) && (strlen(lpszPathLink) > 0)) {
|
||||
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
|
||||
if (SUCCEEDED(hres)) {
|
||||
IPersistFile* ppf;
|
||||
// Get a pointer to the IShellLink interface. It is assumed that CoInitialize
|
||||
// has already been called.
|
||||
CoInitialize(NULL);
|
||||
HRESULT hres = E_INVALIDARG;
|
||||
if ((lpszPathObj != NULL) && (wcslen(lpszPathObj) > 0) &&
|
||||
(lpszDesc != NULL) &&
|
||||
(lpszPathLink != NULL) && (strlen(lpszPathLink) > 0)) {
|
||||
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
|
||||
if (SUCCEEDED(hres)) {
|
||||
IPersistFile* ppf;
|
||||
|
||||
// Set the path to the shortcut target and add the description.
|
||||
psl->SetPath(lpszPathObj);
|
||||
psl->SetDescription(lpszDesc);
|
||||
psl->SetArguments(lpszArgs);
|
||||
// Set the path to the shortcut target and add the description.
|
||||
psl->SetPath(lpszPathObj);
|
||||
psl->SetDescription(lpszDesc);
|
||||
psl->SetArguments(lpszArgs);
|
||||
|
||||
// Query IShellLink for the IPersistFile interface, used for saving the
|
||||
// shortcut in persistent storage.
|
||||
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
|
||||
// Query IShellLink for the IPersistFile interface, used for saving the
|
||||
// shortcut in persistent storage.
|
||||
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
|
||||
|
||||
if (SUCCEEDED(hres)) {
|
||||
WCHAR wsz[MAX_PATH];
|
||||
if (SUCCEEDED(hres)) {
|
||||
WCHAR wsz[MAX_PATH];
|
||||
|
||||
// Ensure that the string is Unicode.
|
||||
MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH);
|
||||
// Ensure that the string is Unicode.
|
||||
MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH);
|
||||
|
||||
// Add code here to check return value from MultiByteWideChar
|
||||
// for success.
|
||||
// Add code here to check return value from MultiByteWideChar
|
||||
// for success.
|
||||
|
||||
// Save the link by calling IPersistFile::Save.
|
||||
hres = ppf->Save(wsz, TRUE);
|
||||
ppf->Release();
|
||||
}
|
||||
psl->Release();
|
||||
}
|
||||
}
|
||||
CoUninitialize();
|
||||
return SUCCEEDED(hres);
|
||||
// Save the link by calling IPersistFile::Save.
|
||||
hres = ppf->Save(wsz, TRUE);
|
||||
ppf->Release();
|
||||
}
|
||||
psl->Release();
|
||||
}
|
||||
}
|
||||
CoUninitialize();
|
||||
return SUCCEEDED(hres);
|
||||
}
|
||||
|
||||
std::string LauncherUtils::cStringToStd(CString cstring) {
|
||||
CT2CA convertedString(cstring);
|
||||
std::string strStd(convertedString);
|
||||
return strStd;
|
||||
CT2CA convertedString(cstring);
|
||||
std::string strStd(convertedString);
|
||||
return strStd;
|
||||
}
|
||||
|
||||
BOOL LauncherUtils::launchApplication(LPCWSTR lpApplicationName, LPTSTR cmdArgs) {
|
||||
// additional information
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
// additional information
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
// set the size of the structures
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
ZeroMemory(&pi, sizeof(pi));
|
||||
// set the size of the structures
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
ZeroMemory(&pi, sizeof(pi));
|
||||
|
||||
// start the program up
|
||||
BOOL success = CreateProcess(
|
||||
lpApplicationName, // the path
|
||||
cmdArgs, // Command line
|
||||
NULL, // Process handle not inheritable
|
||||
NULL, // Thread handle not inheritable
|
||||
FALSE, // Set handle inheritance to FALSE
|
||||
CREATE_NEW_CONSOLE, // Opens file in a separate console
|
||||
NULL, // Use parent's environment block
|
||||
NULL, // Use parent's starting directory
|
||||
&si, // Pointer to STARTUPINFO structure
|
||||
&pi // Pointer to PROCESS_INFORMATION structure
|
||||
);
|
||||
// Close process and thread handles.
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
return success;
|
||||
// start the program up
|
||||
BOOL success = CreateProcess(
|
||||
lpApplicationName, // the path
|
||||
cmdArgs, // Command line
|
||||
NULL, // Process handle not inheritable
|
||||
NULL, // Thread handle not inheritable
|
||||
FALSE, // Set handle inheritance to FALSE
|
||||
CREATE_NEW_CONSOLE, // Opens file in a separate console
|
||||
NULL, // Use parent's environment block
|
||||
NULL, // Use parent's starting directory
|
||||
&si, // Pointer to STARTUPINFO structure
|
||||
&pi // Pointer to PROCESS_INFORMATION structure
|
||||
);
|
||||
// Close process and thread handles.
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL LauncherUtils::deleteRegistryKey(const CString& registryPath) {
|
||||
TCHAR szDelKey[MAX_PATH * 2];
|
||||
StringCchCopy(szDelKey, MAX_PATH * 2, registryPath);
|
||||
auto status = RegDeleteKey(HKEY_CURRENT_USER, szDelKey);
|
||||
if (status == ERROR_SUCCESS) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
TCHAR szDelKey[MAX_PATH * 2];
|
||||
StringCchCopy(szDelKey, MAX_PATH * 2, registryPath);
|
||||
auto status = RegDeleteKey(HKEY_CURRENT_USER, szDelKey);
|
||||
if (status == ERROR_SUCCESS) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LauncherUtils::ResponseError LauncherUtils::makeHTTPCall(const CString& callerName,
|
||||
const CString& mainUrl, const CString& dirUrl,
|
||||
const CString& contentType, CStringA& postData,
|
||||
CString& response, bool isPost = false) {
|
||||
const CString& mainUrl, const CString& dirUrl,
|
||||
const CString& contentType, CStringA& postData,
|
||||
CString& response, bool isPost = false) {
|
||||
|
||||
HINTERNET hopen = WinHttpOpen(callerName, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
||||
WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
|
||||
if (!hopen) {
|
||||
return ResponseError::Open;
|
||||
}
|
||||
HINTERNET hconnect = WinHttpConnect(hopen, mainUrl, INTERNET_DEFAULT_HTTPS_PORT, 0);
|
||||
if (!hconnect) {
|
||||
return ResponseError::Connect;
|
||||
}
|
||||
HINTERNET hrequest = WinHttpOpenRequest(hconnect, isPost ? L"POST" : L"GET", dirUrl,
|
||||
NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
|
||||
if (!hrequest) {
|
||||
return ResponseError::OpenRequest;
|
||||
}
|
||||
if (isPost) {
|
||||
if (!WinHttpSendRequest(hrequest, contentType, -1,
|
||||
postData.GetBuffer(postData.GetLength()), (DWORD)strlen(postData), (DWORD)strlen(postData), NULL)) {
|
||||
return ResponseError::SendRequest;
|
||||
}
|
||||
} else {
|
||||
if (!WinHttpSendRequest(hrequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) {
|
||||
return ResponseError::SendRequest;
|
||||
}
|
||||
}
|
||||
if (!WinHttpReceiveResponse(hrequest, 0)) {
|
||||
return ResponseError::ReceiveRequest;
|
||||
}
|
||||
// query remote file size, set haveContentLength on success and dwContentLength to the length
|
||||
wchar_t szContentLength[32];
|
||||
DWORD bufferBytes = 4096;
|
||||
DWORD dwHeaderIndex = WINHTTP_NO_HEADER_INDEX;
|
||||
HINTERNET hopen = WinHttpOpen(callerName, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
|
||||
WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
|
||||
if (!hopen) {
|
||||
return ResponseError::Open;
|
||||
}
|
||||
HINTERNET hconnect = WinHttpConnect(hopen, mainUrl, INTERNET_DEFAULT_HTTPS_PORT, 0);
|
||||
if (!hconnect) {
|
||||
return ResponseError::Connect;
|
||||
}
|
||||
HINTERNET hrequest = WinHttpOpenRequest(hconnect, isPost ? L"POST" : L"GET", dirUrl,
|
||||
NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
|
||||
if (!hrequest) {
|
||||
return ResponseError::OpenRequest;
|
||||
}
|
||||
if (isPost) {
|
||||
if (!WinHttpSendRequest(hrequest, contentType, -1,
|
||||
postData.GetBuffer(postData.GetLength()), (DWORD)strlen(postData), (DWORD)strlen(postData), NULL)) {
|
||||
return ResponseError::SendRequest;
|
||||
}
|
||||
} else {
|
||||
if (!WinHttpSendRequest(hrequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) {
|
||||
return ResponseError::SendRequest;
|
||||
}
|
||||
}
|
||||
if (!WinHttpReceiveResponse(hrequest, 0)) {
|
||||
return ResponseError::ReceiveRequest;
|
||||
}
|
||||
// query remote file size, set haveContentLength on success and dwContentLength to the length
|
||||
wchar_t szContentLength[32];
|
||||
DWORD bufferBytes = 4096;
|
||||
DWORD dwHeaderIndex = WINHTTP_NO_HEADER_INDEX;
|
||||
|
||||
BOOL haveContentLength = WinHttpQueryHeaders(hrequest, WINHTTP_QUERY_CONTENT_LENGTH, NULL,
|
||||
&szContentLength, &bufferBytes, &dwHeaderIndex);
|
||||
BOOL haveContentLength = WinHttpQueryHeaders(hrequest, WINHTTP_QUERY_CONTENT_LENGTH, NULL,
|
||||
&szContentLength, &bufferBytes, &dwHeaderIndex);
|
||||
|
||||
DWORD dwContentLength;
|
||||
if (haveContentLength) {
|
||||
dwContentLength = _wtoi(szContentLength);
|
||||
}
|
||||
byte p[4096];
|
||||
if (!WinHttpQueryDataAvailable(hrequest, &bufferBytes)) {
|
||||
return ResponseError::ReadResponse;
|
||||
}
|
||||
WinHttpReadData(hrequest, p, bufferBytes, &bufferBytes);
|
||||
response = CString((const char*)p, (int)bufferBytes);
|
||||
return ResponseError::NoError;
|
||||
DWORD dwContentLength;
|
||||
if (haveContentLength) {
|
||||
dwContentLength = _wtoi(szContentLength);
|
||||
}
|
||||
byte p[4096];
|
||||
if (!WinHttpQueryDataAvailable(hrequest, &bufferBytes)) {
|
||||
return ResponseError::ReadResponse;
|
||||
}
|
||||
WinHttpReadData(hrequest, p, bufferBytes, &bufferBytes);
|
||||
response = CString((const char*)p, (int)bufferBytes);
|
||||
return ResponseError::NoError;
|
||||
}
|
||||
|
||||
BOOL LauncherUtils::parseJSON(const CString& jsonTxt, Json::Value& root) {
|
||||
Json::CharReaderBuilder CharBuilder;
|
||||
std::string jsonString = cStringToStd(jsonTxt);
|
||||
std::string errs;
|
||||
Json::CharReader* nreader = CharBuilder.newCharReader();
|
||||
bool parsingSuccessful = false;
|
||||
if (nreader != NULL) {
|
||||
parsingSuccessful = nreader->parse(jsonString.c_str(), jsonString.c_str() + jsonString.length(), &root, &errs);
|
||||
delete nreader;
|
||||
}
|
||||
return parsingSuccessful;
|
||||
Json::CharReaderBuilder CharBuilder;
|
||||
std::string jsonString = cStringToStd(jsonTxt);
|
||||
std::string errs;
|
||||
Json::CharReader* nreader = CharBuilder.newCharReader();
|
||||
bool parsingSuccessful = false;
|
||||
if (nreader != NULL) {
|
||||
parsingSuccessful = nreader->parse(jsonString.c_str(), jsonString.c_str() + jsonString.length(), &root, &errs);
|
||||
delete nreader;
|
||||
}
|
||||
return parsingSuccessful;
|
||||
}
|
||||
|
||||
BOOL LauncherUtils::getFont(const CString& fontName, int fontSize, bool isBold, CFont& fontOut) {
|
||||
LOGFONT lf;
|
||||
memset(&lf, 0, sizeof(lf));
|
||||
lf.lfHeight = fontSize;
|
||||
lf.lfWeight = isBold ? FW_BOLD : FW_NORMAL;
|
||||
lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
|
||||
lf.lfQuality = ANTIALIASED_QUALITY;
|
||||
|
||||
wcscpy_s(lf.lfFaceName, fontName);
|
||||
if (!fontOut.CreateFontIndirect(&lf)) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
LOGFONT lf;
|
||||
memset(&lf, 0, sizeof(lf));
|
||||
lf.lfHeight = fontSize;
|
||||
lf.lfWeight = isBold ? FW_BOLD : FW_NORMAL;
|
||||
lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
|
||||
lf.lfQuality = ANTIALIASED_QUALITY;
|
||||
|
||||
wcscpy_s(lf.lfFaceName, fontName);
|
||||
if (!fontOut.CreateFontIndirect(&lf)) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
uint64_t LauncherUtils::extractZip(const std::string& zipFile, const std::string& path, std::vector<std::string>& files) {
|
||||
mz_zip_archive zip_archive;
|
||||
memset(&zip_archive, 0, sizeof(zip_archive));
|
||||
mz_zip_archive zip_archive;
|
||||
memset(&zip_archive, 0, sizeof(zip_archive));
|
||||
|
||||
auto status = mz_zip_reader_init_file(&zip_archive, zipFile.c_str(), 0);
|
||||
auto status = mz_zip_reader_init_file(&zip_archive, zipFile.c_str(), 0);
|
||||
|
||||
if (!status) return 0;
|
||||
int fileCount = (int)mz_zip_reader_get_num_files(&zip_archive);
|
||||
if (fileCount == 0) {
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return 0;
|
||||
}
|
||||
mz_zip_archive_file_stat file_stat;
|
||||
if (!mz_zip_reader_file_stat(&zip_archive, 0, &file_stat)) {
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return 0;
|
||||
}
|
||||
// Get root folder
|
||||
CString lastDir = _T("");
|
||||
uint64_t totalSize = 0;
|
||||
for (int i = 0; i < fileCount; i++) {
|
||||
if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) continue;
|
||||
std::string filename = file_stat.m_filename;
|
||||
std::replace(filename.begin(), filename.end(), '/', '\\');
|
||||
CString fullFilename = CString(path.c_str()) + "\\" + CString(filename.c_str());
|
||||
if (mz_zip_reader_is_file_a_directory(&zip_archive, i)) {
|
||||
if (SHCreateDirectoryEx(NULL, fullFilename, NULL) || ERROR_ALREADY_EXISTS == GetLastError()) {
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
CT2A destFile(fullFilename);
|
||||
if (mz_zip_reader_extract_to_file(&zip_archive, i, destFile, 0)) {
|
||||
totalSize += (uint64_t)file_stat.m_uncomp_size;
|
||||
files.emplace_back(destFile);
|
||||
}
|
||||
}
|
||||
if (!status) return 0;
|
||||
int fileCount = (int)mz_zip_reader_get_num_files(&zip_archive);
|
||||
if (fileCount == 0) {
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return 0;
|
||||
}
|
||||
mz_zip_archive_file_stat file_stat;
|
||||
if (!mz_zip_reader_file_stat(&zip_archive, 0, &file_stat)) {
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return 0;
|
||||
}
|
||||
// Get root folder
|
||||
CString lastDir = _T("");
|
||||
uint64_t totalSize = 0;
|
||||
for (int i = 0; i < fileCount; i++) {
|
||||
if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) continue;
|
||||
std::string filename = file_stat.m_filename;
|
||||
std::replace(filename.begin(), filename.end(), '/', '\\');
|
||||
CString fullFilename = CString(path.c_str()) + "\\" + CString(filename.c_str());
|
||||
if (mz_zip_reader_is_file_a_directory(&zip_archive, i)) {
|
||||
if (SHCreateDirectoryEx(NULL, fullFilename, NULL) || ERROR_ALREADY_EXISTS == GetLastError()) {
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
CT2A destFile(fullFilename);
|
||||
if (mz_zip_reader_extract_to_file(&zip_archive, i, destFile, 0)) {
|
||||
totalSize += (uint64_t)file_stat.m_uncomp_size;
|
||||
files.emplace_back(destFile);
|
||||
}
|
||||
}
|
||||
|
||||
// Close the archive, freeing any resources it was using
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return totalSize;
|
||||
// Close the archive, freeing any resources it was using
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
BOOL LauncherUtils::insertRegistryKey(const std::string& regPath, const std::string& name, const std::string& value) {
|
||||
HKEY key;
|
||||
auto status = RegCreateKeyExA(HKEY_CURRENT_USER, regPath.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_QUERY_VALUE, NULL, &key, NULL);
|
||||
if (status == ERROR_SUCCESS) {
|
||||
status = RegSetValueExA(key, name.c_str(), 0, REG_SZ, (const BYTE*)value.c_str(), (DWORD)(value.size() + 1));
|
||||
return status == ERROR_SUCCESS;
|
||||
}
|
||||
RegCloseKey(key);
|
||||
return FALSE;
|
||||
HKEY key;
|
||||
auto status = RegCreateKeyExA(HKEY_CURRENT_USER, regPath.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_QUERY_VALUE, NULL, &key, NULL);
|
||||
if (status == ERROR_SUCCESS) {
|
||||
status = RegSetValueExA(key, name.c_str(), 0, REG_SZ, (const BYTE*)value.c_str(), (DWORD)(value.size() + 1));
|
||||
return status == ERROR_SUCCESS;
|
||||
}
|
||||
RegCloseKey(key);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LauncherUtils::insertRegistryKey(const std::string& regPath, const std::string& name, DWORD value) {
|
||||
HKEY key;
|
||||
auto status = RegCreateKeyExA(HKEY_CURRENT_USER, regPath.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_QUERY_VALUE, NULL, &key, NULL);
|
||||
if (status == ERROR_SUCCESS) {
|
||||
status = RegSetValueExA(key, name.c_str(), 0, REG_DWORD, (const BYTE*)&value, sizeof(value));
|
||||
return TRUE;
|
||||
}
|
||||
RegCloseKey(key);
|
||||
return FALSE;
|
||||
HKEY key;
|
||||
auto status = RegCreateKeyExA(HKEY_CURRENT_USER, regPath.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_QUERY_VALUE, NULL, &key, NULL);
|
||||
if (status == ERROR_SUCCESS) {
|
||||
status = RegSetValueExA(key, name.c_str(), 0, REG_DWORD, (const BYTE*)&value, sizeof(value));
|
||||
return TRUE;
|
||||
}
|
||||
RegCloseKey(key);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LauncherUtils::deleteFileOrDirectory(const CString& dirPath, bool noRecycleBin) {
|
||||
CString dir = dirPath;
|
||||
// Add extra null to string
|
||||
dir.AppendChar(0);
|
||||
SHFILEOPSTRUCT fileop;
|
||||
fileop.hwnd = NULL; // no status display
|
||||
fileop.wFunc = FO_DELETE; // delete operation
|
||||
fileop.pFrom = dir; // source file name as double null terminated string
|
||||
fileop.pTo = NULL; // no destination needed
|
||||
fileop.fFlags = FOF_NOCONFIRMATION | FOF_SILENT; // do not prompt the user
|
||||
CString dir = dirPath;
|
||||
// Add extra null to string
|
||||
dir.AppendChar(0);
|
||||
SHFILEOPSTRUCT fileop;
|
||||
fileop.hwnd = NULL; // no status display
|
||||
fileop.wFunc = FO_DELETE; // delete operation
|
||||
fileop.pFrom = dir; // source file name as double null terminated string
|
||||
fileop.pTo = NULL; // no destination needed
|
||||
fileop.fFlags = FOF_NOCONFIRMATION | FOF_SILENT; // do not prompt the user
|
||||
|
||||
if (!noRecycleBin) {
|
||||
fileop.fFlags |= FOF_ALLOWUNDO;
|
||||
}
|
||||
if (!noRecycleBin) {
|
||||
fileop.fFlags |= FOF_ALLOWUNDO;
|
||||
}
|
||||
|
||||
fileop.fAnyOperationsAborted = FALSE;
|
||||
fileop.lpszProgressTitle = NULL;
|
||||
fileop.hNameMappings = NULL;
|
||||
fileop.fAnyOperationsAborted = FALSE;
|
||||
fileop.lpszProgressTitle = NULL;
|
||||
fileop.hNameMappings = NULL;
|
||||
|
||||
int ret = SHFileOperation(&fileop);
|
||||
return (ret == 0);
|
||||
int ret = SHFileOperation(&fileop);
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
BOOL LauncherUtils::hMac256(const CString& cmessage, const char* keystr, CString& hashOut) {
|
||||
char message[256];
|
||||
strcpy_s(message, CStringA(cmessage).GetString());
|
||||
char key[256];
|
||||
strcpy_s(key, keystr);
|
||||
HCRYPTPROV hProv = 0;
|
||||
HCRYPTHASH hHash = 0;
|
||||
HCRYPTKEY hKey = 0;
|
||||
HCRYPTHASH hHmacHash = 0;
|
||||
BYTE pbHash[32];
|
||||
HMAC_INFO HmacInfo;
|
||||
int err = 0;
|
||||
typedef struct blob {
|
||||
BLOBHEADER header;
|
||||
DWORD len;
|
||||
BYTE key[1];
|
||||
} m_blob;
|
||||
char message[256];
|
||||
strcpy_s(message, CStringA(cmessage).GetString());
|
||||
char key[256];
|
||||
strcpy_s(key, keystr);
|
||||
HCRYPTPROV hProv = 0;
|
||||
HCRYPTHASH hHash = 0;
|
||||
HCRYPTKEY hKey = 0;
|
||||
HCRYPTHASH hHmacHash = 0;
|
||||
BYTE pbHash[32];
|
||||
HMAC_INFO HmacInfo;
|
||||
int err = 0;
|
||||
typedef struct blob {
|
||||
BLOBHEADER header;
|
||||
DWORD len;
|
||||
BYTE key[1];
|
||||
} m_blob;
|
||||
|
||||
ZeroMemory(&HmacInfo, sizeof(HmacInfo));
|
||||
HmacInfo.HashAlgid = CALG_SHA_256;
|
||||
ZeroMemory(&pbHash, 32);
|
||||
m_blob* kb = NULL;
|
||||
DWORD kbSize = DWORD(sizeof(m_blob) + strlen(key));
|
||||
ZeroMemory(&HmacInfo, sizeof(HmacInfo));
|
||||
HmacInfo.HashAlgid = CALG_SHA_256;
|
||||
ZeroMemory(&pbHash, 32);
|
||||
m_blob* kb = NULL;
|
||||
DWORD kbSize = DWORD(sizeof(m_blob) + strlen(key));
|
||||
|
||||
kb = (m_blob*)malloc(kbSize);
|
||||
kb->header.bType = PLAINTEXTKEYBLOB;
|
||||
kb->header.bVersion = CUR_BLOB_VERSION;
|
||||
kb->header.reserved = 0;
|
||||
kb->header.aiKeyAlg = CALG_RC2;
|
||||
memcpy(&kb->key, key, strlen(key));
|
||||
kb->len = (DWORD)strlen(key);
|
||||
BOOL success = false;
|
||||
DWORD datalen = (DWORD)32;
|
||||
if (CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET)
|
||||
&& CryptImportKey(hProv, (BYTE*)kb, kbSize, 0, CRYPT_IPSEC_HMAC_KEY, &hKey)
|
||||
&& CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHmacHash)
|
||||
&& CryptSetHashParam(hHmacHash, HP_HMAC_INFO, (BYTE*)&HmacInfo, 0)
|
||||
&& CryptHashData(hHmacHash, (BYTE*)message, (DWORD)strlen(message), 0)
|
||||
&& CryptGetHashParam(hHmacHash, HP_HASHVAL, pbHash, &datalen, 0)) {
|
||||
char *Hex = "0123456789abcdef";
|
||||
char HashString[65] = { 0 };
|
||||
for (int Count = 0; Count < 32; Count++)
|
||||
{
|
||||
HashString[Count * 2] = Hex[pbHash[Count] >> 4];
|
||||
HashString[(Count * 2) + 1] = Hex[pbHash[Count] & 0xF];
|
||||
}
|
||||
hashOut = CString(HashString);
|
||||
success = true;
|
||||
}
|
||||
kb = (m_blob*)malloc(kbSize);
|
||||
kb->header.bType = PLAINTEXTKEYBLOB;
|
||||
kb->header.bVersion = CUR_BLOB_VERSION;
|
||||
kb->header.reserved = 0;
|
||||
kb->header.aiKeyAlg = CALG_RC2;
|
||||
memcpy(&kb->key, key, strlen(key));
|
||||
kb->len = (DWORD)strlen(key);
|
||||
BOOL success = false;
|
||||
DWORD datalen = (DWORD)32;
|
||||
if (CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET)
|
||||
&& CryptImportKey(hProv, (BYTE*)kb, kbSize, 0, CRYPT_IPSEC_HMAC_KEY, &hKey)
|
||||
&& CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHmacHash)
|
||||
&& CryptSetHashParam(hHmacHash, HP_HMAC_INFO, (BYTE*)&HmacInfo, 0)
|
||||
&& CryptHashData(hHmacHash, (BYTE*)message, (DWORD)strlen(message), 0)
|
||||
&& CryptGetHashParam(hHmacHash, HP_HASHVAL, pbHash, &datalen, 0)) {
|
||||
char *Hex = "0123456789abcdef";
|
||||
char HashString[65] = { 0 };
|
||||
for (int Count = 0; Count < 32; Count++)
|
||||
{
|
||||
HashString[Count * 2] = Hex[pbHash[Count] >> 4];
|
||||
HashString[(Count * 2) + 1] = Hex[pbHash[Count] & 0xF];
|
||||
}
|
||||
hashOut = CString(HashString);
|
||||
success = true;
|
||||
}
|
||||
|
||||
free(kb);
|
||||
if (hHmacHash)
|
||||
CryptDestroyHash(hHmacHash);
|
||||
if (hKey)
|
||||
CryptDestroyKey(hKey);
|
||||
if (hHash)
|
||||
CryptDestroyHash(hHash);
|
||||
if (hProv)
|
||||
CryptReleaseContext(hProv, 0);
|
||||
return success;
|
||||
free(kb);
|
||||
if (hHmacHash)
|
||||
CryptDestroyHash(hHmacHash);
|
||||
if (hKey)
|
||||
CryptDestroyKey(hKey);
|
||||
if (hHash)
|
||||
CryptDestroyHash(hHash);
|
||||
if (hProv)
|
||||
CryptReleaseContext(hProv, 0);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
DWORD WINAPI LauncherUtils::unzipThread(LPVOID lpParameter) {
|
||||
UnzipThreadData& data = *((UnzipThreadData*)lpParameter);
|
||||
uint64_t size = LauncherUtils::extractZip(data._zipFile, data._path, std::vector<std::string>());
|
||||
int mb_size = (int)(size * 0.001f);
|
||||
data.callback(data._type, mb_size);
|
||||
delete &data;
|
||||
return 0;
|
||||
UnzipThreadData& data = *((UnzipThreadData*)lpParameter);
|
||||
uint64_t size = LauncherUtils::extractZip(data._zipFile, data._path, std::vector<std::string>());
|
||||
int mb_size = (int)(size * 0.001f);
|
||||
data.callback(data._type, mb_size);
|
||||
delete &data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD WINAPI LauncherUtils::downloadThread(LPVOID lpParameter)
|
||||
{
|
||||
DownloadThreadData& data = *((DownloadThreadData*)lpParameter);
|
||||
auto hr = URLDownloadToFile(0, data._url, data._file, 0, NULL);
|
||||
data.callback(data._type);
|
||||
return 0;
|
||||
DownloadThreadData& data = *((DownloadThreadData*)lpParameter);
|
||||
auto hr = URLDownloadToFile(0, data._url, data._file, 0, NULL);
|
||||
data.callback(data._type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD WINAPI LauncherUtils::deleteDirectoriesThread(LPVOID lpParameter) {
|
||||
|
@ -406,33 +406,33 @@ DWORD WINAPI LauncherUtils::deleteDirectoriesThread(LPVOID lpParameter) {
|
|||
}
|
||||
|
||||
BOOL LauncherUtils::unzipFileOnThread(int type, const std::string& zipFile, const std::string& path, std::function<void(int, int)> callback) {
|
||||
DWORD myThreadID;
|
||||
UnzipThreadData* unzipThreadData = new UnzipThreadData();
|
||||
unzipThreadData->_type = type;
|
||||
unzipThreadData->_zipFile = zipFile;
|
||||
unzipThreadData->_path = path;
|
||||
unzipThreadData->setCallback(callback);
|
||||
HANDLE myHandle = CreateThread(0, 0, unzipThread, unzipThreadData, 0, &myThreadID);
|
||||
if (myHandle) {
|
||||
CloseHandle(myHandle);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
DWORD myThreadID;
|
||||
UnzipThreadData* unzipThreadData = new UnzipThreadData();
|
||||
unzipThreadData->_type = type;
|
||||
unzipThreadData->_zipFile = zipFile;
|
||||
unzipThreadData->_path = path;
|
||||
unzipThreadData->setCallback(callback);
|
||||
HANDLE myHandle = CreateThread(0, 0, unzipThread, unzipThreadData, 0, &myThreadID);
|
||||
if (myHandle) {
|
||||
CloseHandle(myHandle);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LauncherUtils::downloadFileOnThread(int type, const CString& url, const CString& file, std::function<void(int)> callback) {
|
||||
DWORD myThreadID;
|
||||
DownloadThreadData* downloadThreadData = new DownloadThreadData();
|
||||
downloadThreadData->_type = type;
|
||||
downloadThreadData->_url = url;
|
||||
downloadThreadData->_file = file;
|
||||
downloadThreadData->setCallback(callback);
|
||||
HANDLE myHandle = CreateThread(0, 0, downloadThread, downloadThreadData, 0, &myThreadID);
|
||||
if (myHandle) {
|
||||
CloseHandle(myHandle);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
DWORD myThreadID;
|
||||
DownloadThreadData* downloadThreadData = new DownloadThreadData();
|
||||
downloadThreadData->_type = type;
|
||||
downloadThreadData->_url = url;
|
||||
downloadThreadData->_file = file;
|
||||
downloadThreadData->setCallback(callback);
|
||||
HANDLE myHandle = CreateThread(0, 0, downloadThread, downloadThreadData, 0, &myThreadID);
|
||||
if (myHandle) {
|
||||
CloseHandle(myHandle);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LauncherUtils::deleteDirectoriesOnThread(const CString& applicationDir,
|
||||
|
|
|
@ -18,17 +18,17 @@
|
|||
class LauncherUtils
|
||||
{
|
||||
public:
|
||||
enum ResponseError {
|
||||
Open = 0,
|
||||
Connect,
|
||||
OpenRequest,
|
||||
SendRequest,
|
||||
ReceiveRequest,
|
||||
ReadResponse,
|
||||
ParsingJSON,
|
||||
BadCredentials,
|
||||
NoError
|
||||
};
|
||||
enum ResponseError {
|
||||
Open = 0,
|
||||
Connect,
|
||||
OpenRequest,
|
||||
SendRequest,
|
||||
ReceiveRequest,
|
||||
ReadResponse,
|
||||
ParsingJSON,
|
||||
BadCredentials,
|
||||
NoError
|
||||
};
|
||||
|
||||
enum DeleteDirError {
|
||||
NoErrorDeleting = 0,
|
||||
|
@ -37,27 +37,27 @@ public:
|
|||
ErrorDeletingBothDirs
|
||||
};
|
||||
|
||||
struct DownloadThreadData {
|
||||
int _type;
|
||||
CString _url;
|
||||
CString _file;
|
||||
std::function<void(int)> callback;
|
||||
// function(type)
|
||||
void setCallback(std::function<void(int)> fn) {
|
||||
callback = std::bind(fn, std::placeholders::_1);
|
||||
}
|
||||
};
|
||||
struct DownloadThreadData {
|
||||
int _type;
|
||||
CString _url;
|
||||
CString _file;
|
||||
std::function<void(int)> callback;
|
||||
// function(type)
|
||||
void setCallback(std::function<void(int)> fn) {
|
||||
callback = std::bind(fn, std::placeholders::_1);
|
||||
}
|
||||
};
|
||||
|
||||
struct UnzipThreadData {
|
||||
int _type;
|
||||
std::string _zipFile;
|
||||
std::string _path;
|
||||
// function(type, size)
|
||||
std::function<void(int, int)> callback;
|
||||
void setCallback(std::function<void(int, int)> fn) {
|
||||
callback = std::bind(fn, std::placeholders::_1, std::placeholders::_2);
|
||||
}
|
||||
};
|
||||
struct UnzipThreadData {
|
||||
int _type;
|
||||
std::string _zipFile;
|
||||
std::string _path;
|
||||
// function(type, size)
|
||||
std::function<void(int, int)> callback;
|
||||
void setCallback(std::function<void(int, int)> fn) {
|
||||
callback = std::bind(fn, std::placeholders::_1, std::placeholders::_2);
|
||||
}
|
||||
};
|
||||
|
||||
struct DeleteThreadData {
|
||||
CString _applicationDir;
|
||||
|
@ -66,31 +66,31 @@ public:
|
|||
void setCallback(std::function<void(int)> fn) { callback = std::bind(fn, std::placeholders::_1); }
|
||||
};
|
||||
|
||||
static BOOL parseJSON(const CString& jsonTxt, Json::Value& jsonObject);
|
||||
static ResponseError makeHTTPCall(const CString& callerName, const CString& mainUrl,
|
||||
const CString& dirUrl, const CString& contentType,
|
||||
CStringA& postData, CString& response, bool isPost);
|
||||
static std::string cStringToStd(CString cstring);
|
||||
static BOOL getFont(const CString& fontName, int fontSize, bool isBold, CFont& fontOut);
|
||||
static BOOL launchApplication(LPCWSTR lpApplicationName, LPTSTR cmdArgs = _T(""));
|
||||
static BOOL IsProcessRunning(const wchar_t *processName);
|
||||
static BOOL insertRegistryKey(const std::string& regPath, const std::string& name, const std::string& value);
|
||||
static BOOL insertRegistryKey(const std::string& regPath, const std::string& name, DWORD value);
|
||||
static BOOL deleteFileOrDirectory(const CString& dirPath, bool noRecycleBin = true);
|
||||
static HRESULT CreateLink(LPCWSTR lpszPathObj, LPCSTR lpszPathLink, LPCWSTR lpszDesc, LPCWSTR lpszArgs = _T(""));
|
||||
static BOOL hMac256(const CString& message, const char* key, CString& hashOut);
|
||||
static uint64_t extractZip(const std::string& zipFile, const std::string& path, std::vector<std::string>& files);
|
||||
static BOOL deleteRegistryKey(const CString& registryPath);
|
||||
static BOOL unzipFileOnThread(int type, const std::string& zipFile, const std::string& path, std::function<void(int, int)> callback);
|
||||
static BOOL downloadFileOnThread(int type, const CString& url, const CString& file, std::function<void(int)> callback);
|
||||
static BOOL parseJSON(const CString& jsonTxt, Json::Value& jsonObject);
|
||||
static ResponseError makeHTTPCall(const CString& callerName, const CString& mainUrl,
|
||||
const CString& dirUrl, const CString& contentType,
|
||||
CStringA& postData, CString& response, bool isPost);
|
||||
static std::string cStringToStd(CString cstring);
|
||||
static BOOL getFont(const CString& fontName, int fontSize, bool isBold, CFont& fontOut);
|
||||
static BOOL launchApplication(LPCWSTR lpApplicationName, LPTSTR cmdArgs = _T(""));
|
||||
static BOOL IsProcessRunning(const wchar_t *processName);
|
||||
static BOOL insertRegistryKey(const std::string& regPath, const std::string& name, const std::string& value);
|
||||
static BOOL insertRegistryKey(const std::string& regPath, const std::string& name, DWORD value);
|
||||
static BOOL deleteFileOrDirectory(const CString& dirPath, bool noRecycleBin = true);
|
||||
static HRESULT CreateLink(LPCWSTR lpszPathObj, LPCSTR lpszPathLink, LPCWSTR lpszDesc, LPCWSTR lpszArgs = _T(""));
|
||||
static BOOL hMac256(const CString& message, const char* key, CString& hashOut);
|
||||
static uint64_t extractZip(const std::string& zipFile, const std::string& path, std::vector<std::string>& files);
|
||||
static BOOL deleteRegistryKey(const CString& registryPath);
|
||||
static BOOL unzipFileOnThread(int type, const std::string& zipFile, const std::string& path, std::function<void(int, int)> callback);
|
||||
static BOOL downloadFileOnThread(int type, const CString& url, const CString& file, std::function<void(int)> callback);
|
||||
static BOOL deleteDirectoriesOnThread(const CString& applicationDir,
|
||||
const CString& downloadsDir,
|
||||
std::function<void(int)> callback);
|
||||
static CString urlEncodeString(const CString& url);
|
||||
|
||||
private:
|
||||
// Threads
|
||||
static DWORD WINAPI unzipThread(LPVOID lpParameter);
|
||||
static DWORD WINAPI downloadThread(LPVOID lpParameter);
|
||||
// Threads
|
||||
static DWORD WINAPI unzipThread(LPVOID lpParameter);
|
||||
static DWORD WINAPI downloadThread(LPVOID lpParameter);
|
||||
static DWORD WINAPI deleteDirectoriesThread(LPVOID lpParameter);
|
||||
};
|
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
|
@ -396,9 +396,10 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
|||
}
|
||||
|
||||
const size_t byteArraySize = AvatarDataPacket::MAX_CONSTANT_HEADER_SIZE + NUM_BYTES_RFC4122_UUID +
|
||||
AvatarDataPacket::maxFaceTrackerInfoSize(_headData->getBlendshapeCoefficients().size()) +
|
||||
AvatarDataPacket::maxJointDataSize(_jointData.size()) +
|
||||
AvatarDataPacket::maxJointDefaultPoseFlagsSize(_jointData.size());
|
||||
AvatarDataPacket::maxFaceTrackerInfoSize(_headData->getBlendshapeCoefficients().size()) +
|
||||
AvatarDataPacket::maxJointDataSize(_jointData.size()) +
|
||||
AvatarDataPacket::maxJointDefaultPoseFlagsSize(_jointData.size()) +
|
||||
AvatarDataPacket::FAR_GRAB_JOINTS_SIZE;
|
||||
|
||||
if (maxDataSize == 0) {
|
||||
maxDataSize = (int)byteArraySize;
|
||||
|
|
|
@ -302,6 +302,15 @@ namespace AvatarDataPacket {
|
|||
const size_t AVATAR_LOCAL_POSITION_SIZE = 12;
|
||||
static_assert(sizeof(AvatarLocalPosition) == AVATAR_LOCAL_POSITION_SIZE, "AvatarDataPacket::AvatarLocalPosition size doesn't match.");
|
||||
|
||||
PACKED_BEGIN struct HandControllers {
|
||||
SixByteQuat leftHandRotation;
|
||||
SixByteTrans leftHandTranslation;
|
||||
SixByteQuat rightHandRotation;
|
||||
SixByteTrans rightHandTranslation;
|
||||
} PACKED_END;
|
||||
static const size_t HAND_CONTROLLERS_SIZE = 24;
|
||||
static_assert(sizeof(HandControllers) == HAND_CONTROLLERS_SIZE, "AvatarDataPacket::HandControllers size doesn't match.");
|
||||
|
||||
const size_t MAX_CONSTANT_HEADER_SIZE = HEADER_SIZE +
|
||||
AVATAR_GLOBAL_POSITION_SIZE +
|
||||
AVATAR_BOUNDING_BOX_SIZE +
|
||||
|
@ -312,17 +321,8 @@ namespace AvatarDataPacket {
|
|||
SENSOR_TO_WORLD_SIZE +
|
||||
ADDITIONAL_FLAGS_SIZE +
|
||||
PARENT_INFO_SIZE +
|
||||
AVATAR_LOCAL_POSITION_SIZE;
|
||||
|
||||
PACKED_BEGIN struct HandControllers {
|
||||
SixByteQuat leftHandRotation;
|
||||
SixByteTrans leftHandTranslation;
|
||||
SixByteQuat rightHandRotation;
|
||||
SixByteTrans rightHandTranslation;
|
||||
} PACKED_END;
|
||||
static const size_t HAND_CONTROLLERS_SIZE = 24;
|
||||
static_assert(sizeof(HandControllers) == HAND_CONTROLLERS_SIZE, "AvatarDataPacket::HandControllers size doesn't match.");
|
||||
|
||||
AVATAR_LOCAL_POSITION_SIZE +
|
||||
HAND_CONTROLLERS_SIZE;
|
||||
|
||||
// variable length structure follows
|
||||
|
||||
|
@ -1211,6 +1211,12 @@ public:
|
|||
const QString& getDisplayName() const { return _displayName; }
|
||||
const QString& getSessionDisplayName() const { return _sessionDisplayName; }
|
||||
bool getLookAtSnappingEnabled() const { return _lookAtSnappingEnabled; }
|
||||
|
||||
/**jsdoc
|
||||
* Sets the avatar's skeleton model.
|
||||
* @function Avatar.setSkeletonModelURL
|
||||
* @param {string} url - The avatar's FST file.
|
||||
*/
|
||||
Q_INVOKABLE virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
||||
|
||||
virtual void setDisplayName(const QString& displayName);
|
||||
|
|
|
@ -346,7 +346,7 @@ void ResourceCache::setRequestLimit(uint32_t limit) {
|
|||
QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl& fallback, void* extra, size_t extraHash) {
|
||||
QSharedPointer<Resource> resource;
|
||||
{
|
||||
QReadLocker locker(&_resourcesLock);
|
||||
QWriteLocker locker(&_resourcesLock);
|
||||
auto& resourcesWithExtraHash = _resources[url];
|
||||
auto resourcesWithExtraHashIter = resourcesWithExtraHash.find(extraHash);
|
||||
if (resourcesWithExtraHashIter != resourcesWithExtraHash.end()) {
|
||||
|
|
|
@ -59,10 +59,13 @@ void Socket::bind(const QHostAddress& address, quint16 port) {
|
|||
auto sd = _udpSocket.socketDescriptor();
|
||||
int val = IP_PMTUDISC_DONT;
|
||||
setsockopt(sd, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val));
|
||||
#elif defined(Q_OS_WINDOWS)
|
||||
#elif defined(Q_OS_WIN)
|
||||
auto sd = _udpSocket.socketDescriptor();
|
||||
int val = 0; // false
|
||||
setsockopt(sd, IPPROTO_IP, IP_DONTFRAGMENT, &val, sizeof(val));
|
||||
if (setsockopt(sd, IPPROTO_IP, IP_DONTFRAGMENT, (const char *)&val, sizeof(val))) {
|
||||
int wsaError = WSAGetLastError();
|
||||
qCWarning(networking) << "Socket::bind Cannot setsockopt IP_DONTFRAGMENT" << wsaError;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -231,14 +234,14 @@ qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& soc
|
|||
return -1;
|
||||
}
|
||||
qint64 bytesWritten = _udpSocket.writeDatagram(datagram, sockAddr.getAddress(), sockAddr.getPort());
|
||||
|
||||
if (bytesWritten < 0) {
|
||||
qCDebug(networking) << "udt::writeDatagram (" << _udpSocket.state() << ") error - " << _udpSocket.error() << "(" << _udpSocket.errorString() << ")";
|
||||
|
||||
int pending = _udpSocket.bytesToWrite();
|
||||
if (bytesWritten < 0 || pending) {
|
||||
int wsaError = 0;
|
||||
#ifdef WIN32
|
||||
int wsaError = WSAGetLastError();
|
||||
qCDebug(networking) << "windows socket error " << wsaError;
|
||||
wsaError = WSAGetLastError();
|
||||
#endif
|
||||
qCDebug(networking) << "udt::writeDatagram (" << _udpSocket.state() << ") error - " << wsaError << _udpSocket.error() << "(" << _udpSocket.errorString() << ")"
|
||||
<< (pending ? "pending bytes:" : "pending:") << pending;
|
||||
|
||||
#ifdef DEBUG_EVENT_QUEUE
|
||||
int nodeListQueueSize = ::hifi::qt::getEventQueueSize(thread());
|
||||
|
@ -506,11 +509,13 @@ std::vector<HifiSockAddr> Socket::getConnectionSockAddrs() {
|
|||
}
|
||||
|
||||
void Socket::handleSocketError(QAbstractSocket::SocketError socketError) {
|
||||
qCDebug(networking) << "udt::Socket (" << _udpSocket.state() << ") error - " << socketError << "(" << _udpSocket.errorString() << ")";
|
||||
int wsaError = 0;
|
||||
#ifdef WIN32
|
||||
int wsaError = WSAGetLastError();
|
||||
qCDebug(networking) << "windows socket error " << wsaError;
|
||||
wsaError = WSAGetLastError();
|
||||
#endif
|
||||
int pending = _udpSocket.bytesToWrite();
|
||||
qCDebug(networking) << "udt::Socket (" << _udpSocket.state() << ") error - " << wsaError << socketError << "(" << _udpSocket.errorString() << ")"
|
||||
<< (pending ? "pending bytes:" : "pending:") << pending;
|
||||
#ifdef DEBUG_EVENT_QUEUE
|
||||
int nodeListQueueSize = ::hifi::qt::getEventQueueSize(thread());
|
||||
qCDebug(networking) << "Networking queue size - " << nodeListQueueSize;
|
||||
|
|
|
@ -35,7 +35,7 @@ static bool flipNormalsMyAvatarVsBackfacingTriangles(btManifoldPoint& cp,
|
|||
const btVector3* v = triShape->m_vertices1;
|
||||
btVector3 faceNormal = colObj1Wrap->getWorldTransform().getBasis() * btCross(v[1] - v[0], v[2] - v[0]);
|
||||
float nDotF = btDot(faceNormal, cp.m_normalWorldOnB);
|
||||
if (nDotF <= 0.0f) {
|
||||
if (nDotF <= 0.0f && faceNormal.length2() > EPSILON) {
|
||||
faceNormal.normalize();
|
||||
// flip the contact normal to be aligned with the face normal
|
||||
cp.m_normalWorldOnB += -2.0f * nDotF * faceNormal;
|
||||
|
|
|
@ -939,6 +939,11 @@ void GeometryCache::renderWireSphere(gpu::Batch& batch, const glm::vec4& color)
|
|||
void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
|
||||
int majorRows, int majorCols, float majorEdge, int minorRows, int minorCols, float minorEdge,
|
||||
const glm::vec4& color, bool forward, int id) {
|
||||
|
||||
if (majorRows == 0 || majorCols == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vec2FloatPair majorKey(glm::vec2(majorRows, majorCols), majorEdge);
|
||||
Vec2FloatPair minorKey(glm::vec2(minorRows, minorCols), minorEdge);
|
||||
Vec2FloatPairPair key(majorKey, minorKey);
|
||||
|
@ -962,8 +967,8 @@ void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, co
|
|||
gridBuffer.edit<GridSchema>().period = glm::vec4(majorRows, majorCols, minorRows, minorCols);
|
||||
gridBuffer.edit<GridSchema>().offset.x = -(majorEdge / majorRows) / 2;
|
||||
gridBuffer.edit<GridSchema>().offset.y = -(majorEdge / majorCols) / 2;
|
||||
gridBuffer.edit<GridSchema>().offset.z = -(minorEdge / minorRows) / 2;
|
||||
gridBuffer.edit<GridSchema>().offset.w = -(minorEdge / minorCols) / 2;
|
||||
gridBuffer.edit<GridSchema>().offset.z = minorRows == 0 ? 0 : -(minorEdge / minorRows) / 2;
|
||||
gridBuffer.edit<GridSchema>().offset.w = minorCols == 0 ? 0 : -(minorEdge / minorCols) / 2;
|
||||
gridBuffer.edit<GridSchema>().edge = glm::vec4(glm::vec2(majorEdge),
|
||||
// If rows or columns are not set, do not draw minor gridlines
|
||||
glm::vec2((minorRows != 0 && minorCols != 0) ? minorEdge : 0.0f));
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/* global EntityListTool, Tablet, selectionManager, Entities, Camera, MyAvatar, Vec3, Menu, Messages,
|
||||
cameraManager, MENU_EASE_ON_FOCUS, deleteSelectedEntities, toggleSelectedEntitiesLocked, toggleSelectedEntitiesVisible,
|
||||
keyUpEventFromUIWindow */
|
||||
keyUpEventFromUIWindow, Script, SelectionDisplay, SelectionManager, Clipboard */
|
||||
|
||||
var PROFILING_ENABLED = false;
|
||||
var profileIndent = '';
|
||||
|
@ -148,6 +148,20 @@ EntityListTool = function(shouldUseEditTabletApp) {
|
|||
return value !== undefined ? value : "";
|
||||
}
|
||||
|
||||
function entityIsBaked(properties) {
|
||||
if (properties.type === "Model") {
|
||||
var lowerModelURL = properties.modelURL.toLowerCase();
|
||||
return lowerModelURL.endsWith(".baked.fbx") || lowerModelURL.endsWith(".baked.fst");
|
||||
} else if (properties.type === "Zone") {
|
||||
var lowerSkyboxURL = properties.skybox ? properties.skybox.url.toLowerCase() : "";
|
||||
var lowerAmbientURL = properties.ambientLight ? properties.ambientLight.ambientURL.toLowerCase() : "";
|
||||
return (lowerSkyboxURL === "" || lowerSkyboxURL.endsWith(".texmeta.json")) &&
|
||||
(lowerAmbientURL === "" || lowerAmbientURL.endsWith(".texmeta.json"));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
that.sendUpdate = function() {
|
||||
PROFILE('Script-sendUpdate', function() {
|
||||
var entities = [];
|
||||
|
@ -164,7 +178,8 @@ EntityListTool = function(shouldUseEditTabletApp) {
|
|||
var cameraPosition = Camera.position;
|
||||
PROFILE("getMultipleProperties", function () {
|
||||
var multipleProperties = Entities.getMultipleEntityProperties(ids, ['name', 'type', 'locked',
|
||||
'visible', 'renderInfo', 'modelURL', 'materialURL', 'imageURL', 'script', 'certificateID']);
|
||||
'visible', 'renderInfo', 'modelURL', 'materialURL', 'imageURL', 'script', 'certificateID',
|
||||
'skybox.url', 'ambientLight.url']);
|
||||
for (var i = 0; i < multipleProperties.length; i++) {
|
||||
var properties = multipleProperties[i];
|
||||
|
||||
|
@ -193,7 +208,7 @@ EntityListTool = function(shouldUseEditTabletApp) {
|
|||
valueIfDefined(properties.renderInfo.texturesSize) : ""),
|
||||
hasTransparent: (properties.renderInfo !== undefined ?
|
||||
valueIfDefined(properties.renderInfo.hasTransparent) : ""),
|
||||
isBaked: properties.type === "Model" ? url.toLowerCase().endsWith(".baked.fbx") : false,
|
||||
isBaked: entityIsBaked(properties),
|
||||
drawCalls: (properties.renderInfo !== undefined ?
|
||||
valueIfDefined(properties.renderInfo.drawCalls) : ""),
|
||||
hasScript: properties.script !== ""
|
||||
|
|
|
@ -3,6 +3,7 @@ import os
|
|||
import sys
|
||||
import shutil
|
||||
import zipfile
|
||||
import base64
|
||||
|
||||
SOURCE_PATH = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..', '..'))
|
||||
# FIXME move the helper python modules somewher other than the root of the repo
|
||||
|
@ -111,10 +112,43 @@ def fixupWinZip(filename):
|
|||
print("Replacing {} with fixed {}".format(fullPath, outFullPath))
|
||||
shutil.move(outFullPath, fullPath)
|
||||
|
||||
def buildLightLauncher():
|
||||
# FIXME remove once MFC is enabled on the windows build hosts
|
||||
if sys.platform == 'win32':
|
||||
def signBuild(executablePath):
|
||||
if sys.platform != 'win32':
|
||||
print('Skipping signing because platform is not win32')
|
||||
return
|
||||
|
||||
RELEASE_TYPE = os.getenv("RELEASE_TYPE", "")
|
||||
if RELEASE_TYPE != "PRODUCTION":
|
||||
print('Skipping signing because RELEASE_TYPE "{}" != "PRODUCTION"'.format(RELEASE_TYPE))
|
||||
return
|
||||
|
||||
HF_PFX_FILE = os.getenv("HF_PFX_FILE", "")
|
||||
if HF_PFX_FILE == "":
|
||||
print('Skipping signing because HF_PFX_FILE is empty')
|
||||
return
|
||||
|
||||
HF_PFX_PASSPHRASE = os.getenv("HF_PFX_PASSPHRASE", "")
|
||||
if HF_PFX_PASSPHRASE == "":
|
||||
print('Skipping signing because HF_PFX_PASSPHRASE is empty')
|
||||
return
|
||||
|
||||
# FIXME use logic similar to the SetPackagingParameteres.cmake to locate the executable
|
||||
SIGN_TOOL = "C:/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x64/signtool.exe"
|
||||
# sign the launcher executable
|
||||
print("Signing {}".format(executablePath))
|
||||
hifi_utils.executeSubprocess([
|
||||
SIGN_TOOL,
|
||||
'sign',
|
||||
'/fd', 'sha256',
|
||||
'/f', HF_PFX_FILE,
|
||||
'/p', HF_PFX_PASSPHRASE,
|
||||
'/tr', 'http://sha256timestamp.ws.symantec.com/sha256/timestamp',
|
||||
'/td', 'SHA256',
|
||||
executablePath
|
||||
])
|
||||
|
||||
|
||||
def buildLightLauncher():
|
||||
launcherSourcePath = os.path.join(SOURCE_PATH, 'launchers', sys.platform)
|
||||
launcherBuildPath = os.path.join(BUILD_PATH, 'launcher')
|
||||
if not os.path.exists(launcherBuildPath):
|
||||
|
@ -144,13 +178,16 @@ def buildLightLauncher():
|
|||
launcherDestFile = os.path.join(BUILD_PATH, "{}.dmg".format(computeArchiveName('Launcher')))
|
||||
launcherSourceFile = os.path.join(launcherBuildPath, "HQ Launcher.dmg")
|
||||
elif sys.platform == 'win32':
|
||||
# FIXME
|
||||
launcherDestFile = os.path.join(BUILD_PATH, "{}.exe".format(computeArchiveName('Launcher')))
|
||||
launcherSourceFile = os.path.join(launcherBuildPath, "Launcher.exe")
|
||||
launcherSourceFile = os.path.join(launcherBuildPath, "Release", "HQLauncher.exe")
|
||||
|
||||
print("Moving {} to {}".format(launcherSourceFile, launcherDestFile))
|
||||
shutil.move(launcherSourceFile, launcherDestFile)
|
||||
signBuild(launcherDestFile)
|
||||
|
||||
|
||||
|
||||
# Main
|
||||
for wipePath in WIPE_PATHS:
|
||||
wipeClientBuildPath(wipePath)
|
||||
|
||||
|
|
Loading…
Reference in a new issue