mirror of
https://github.com/overte-org/overte.git
synced 2025-07-04 16:09:23 +02:00
Merge branch 'atp-server' of https://github.com/huffman/hifi into asset-upload
This commit is contained in:
commit
c277584f2e
8 changed files with 128 additions and 179 deletions
|
@ -21,89 +21,16 @@
|
||||||
#include <QRunnable>
|
#include <QRunnable>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include <NodeType.h>
|
#include "NetworkLogging.h"
|
||||||
|
#include "NodeType.h"
|
||||||
|
#include "SendAssetTask.h"
|
||||||
|
|
||||||
const QString ASSET_SERVER_LOGGING_TARGET_NAME = "asset-server";
|
const QString ASSET_SERVER_LOGGING_TARGET_NAME = "asset-server";
|
||||||
|
|
||||||
void writeError(NLPacketList* packetList, AssetServerError error) {
|
|
||||||
packetList->writePrimitive(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
class SendAssetTask : public QRunnable {
|
|
||||||
public:
|
|
||||||
SendAssetTask(MessageID messageID, const QByteArray& assetHash, QString filePath, DataOffset start, DataOffset end, const SharedNodePointer& sendToNode) :
|
|
||||||
QRunnable(),
|
|
||||||
_messageID(messageID),
|
|
||||||
_assetHash(assetHash),
|
|
||||||
_filePath(filePath),
|
|
||||||
_start(start),
|
|
||||||
_end(end),
|
|
||||||
_sendToNode(sendToNode)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void run();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void finished();
|
|
||||||
|
|
||||||
private:
|
|
||||||
MessageID _messageID;
|
|
||||||
QByteArray _assetHash;
|
|
||||||
QString _filePath;
|
|
||||||
DataOffset _start;
|
|
||||||
DataOffset _end;
|
|
||||||
SharedNodePointer _sendToNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
void SendAssetTask::run() {
|
|
||||||
qDebug() << "Starting task to send asset: " << _assetHash << " for messageID " << _messageID;
|
|
||||||
auto replyPacketList = std::unique_ptr<NLPacketList>(new NLPacketList(PacketType::AssetGetReply, QByteArray(), true, true));
|
|
||||||
|
|
||||||
replyPacketList->write(_assetHash, HASH_HEX_LENGTH);
|
|
||||||
|
|
||||||
replyPacketList->writePrimitive(_messageID);
|
|
||||||
|
|
||||||
const int64_t MAX_LENGTH = 4294967296;
|
|
||||||
|
|
||||||
if (_end <= _start) {
|
|
||||||
writeError(replyPacketList.get(), AssetServerError::INVALID_BYTE_RANGE);
|
|
||||||
} else if (_end - _start > MAX_LENGTH) {
|
|
||||||
writeError(replyPacketList.get(), AssetServerError::INVALID_BYTE_RANGE);
|
|
||||||
} else {
|
|
||||||
QFile file { _filePath };
|
|
||||||
qDebug() << "Opening file: " << QString(QFileInfo(_assetHash).fileName());
|
|
||||||
|
|
||||||
if (file.open(QIODevice::ReadOnly)) {
|
|
||||||
if (file.size() < _end) {
|
|
||||||
writeError(replyPacketList.get(), AssetServerError::INVALID_BYTE_RANGE);
|
|
||||||
} else {
|
|
||||||
auto size = _end - _start;
|
|
||||||
file.seek(_start);
|
|
||||||
replyPacketList->writePrimitive(AssetServerError::NO_ERROR);
|
|
||||||
replyPacketList->writePrimitive(size);
|
|
||||||
while (file.pos() < file.size()) {
|
|
||||||
static const int chunkSize = 20000;
|
|
||||||
QByteArray data = file.read(chunkSize);
|
|
||||||
replyPacketList->write(data, chunkSize);
|
|
||||||
}
|
|
||||||
qDebug() << "Done reading";
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
qDebug() << "Asset not found";
|
|
||||||
writeError(replyPacketList.get(), AssetServerError::ASSET_NOT_FOUND);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << "Sending asset";
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
|
||||||
nodeList->sendPacketList(std::move(replyPacketList), *_sendToNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
AssetServer::AssetServer(NLPacket& packet) :
|
AssetServer::AssetServer(NLPacket& packet) :
|
||||||
ThreadedAssignment(packet),
|
ThreadedAssignment(packet),
|
||||||
_taskPool(this) {
|
_taskPool(this)
|
||||||
|
{
|
||||||
|
|
||||||
// Most of the work will be I/O bound, reading from disk and constructing packet objects,
|
// Most of the work will be I/O bound, reading from disk and constructing packet objects,
|
||||||
// so the ideal is greater than the number of cores on the system.
|
// so the ideal is greater than the number of cores on the system.
|
||||||
|
@ -115,9 +42,6 @@ AssetServer::AssetServer(NLPacket& packet) :
|
||||||
packetReceiver.registerMessageListener(PacketType::AssetUpload, this, "handleAssetUpload");
|
packetReceiver.registerMessageListener(PacketType::AssetUpload, this, "handleAssetUpload");
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetServer::~AssetServer() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssetServer::run() {
|
void AssetServer::run() {
|
||||||
ThreadedAssignment::commonInit(ASSET_SERVER_LOGGING_TARGET_NAME, NodeType::AssetServer);
|
ThreadedAssignment::commonInit(ASSET_SERVER_LOGGING_TARGET_NAME, NodeType::AssetServer);
|
||||||
|
|
||||||
|
@ -134,8 +58,8 @@ void AssetServer::run() {
|
||||||
// Scan for new files
|
// Scan for new files
|
||||||
qDebug() << "Looking for new files in asset directory";
|
qDebug() << "Looking for new files in asset directory";
|
||||||
auto files = _resourcesDirectory.entryInfoList(QDir::Files);
|
auto files = _resourcesDirectory.entryInfoList(QDir::Files);
|
||||||
QRegExp filenameRegex { "^[a-f0-9]{32}(\\..+)?$" };
|
QRegExp filenameRegex { "^[a-f0-9]{" + QString::number(HASH_HEX_LENGTH) + "}(\\..+)?$" };
|
||||||
for (auto fileInfo : files) {
|
for (const auto& fileInfo : files) {
|
||||||
auto filename = fileInfo.fileName();
|
auto filename = fileInfo.fileName();
|
||||||
if (!filenameRegex.exactMatch(filename)) {
|
if (!filenameRegex.exactMatch(filename)) {
|
||||||
qDebug() << "Found file: " << filename;
|
qDebug() << "Found file: " << filename;
|
||||||
|
|
|
@ -22,7 +22,6 @@ class AssetServer : public ThreadedAssignment {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AssetServer(NLPacket& packet);
|
AssetServer(NLPacket& packet);
|
||||||
~AssetServer();
|
|
||||||
|
|
||||||
static QString hashData(const QByteArray& data);
|
static QString hashData(const QByteArray& data);
|
||||||
|
|
||||||
|
@ -40,4 +39,8 @@ private:
|
||||||
QThreadPool _taskPool;
|
QThreadPool _taskPool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline void writeError(NLPacketList* packetList, AssetServerError error) {
|
||||||
|
packetList->writePrimitive(error);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
73
assignment-client/src/assets/SendAssetTask.cpp
Normal file
73
assignment-client/src/assets/SendAssetTask.cpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
//
|
||||||
|
// SendAssetTask.cpp
|
||||||
|
//
|
||||||
|
// Created by Ryan Huffman on 2015/08/26
|
||||||
|
// Copyright 2015 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SendAssetTask.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
#include <NetworkLogging.h>
|
||||||
|
#include <NLPacket.h>
|
||||||
|
#include <NLPacketList.h>
|
||||||
|
#include <NodeList.h>
|
||||||
|
|
||||||
|
#include "AssetUtils.h"
|
||||||
|
|
||||||
|
SendAssetTask::SendAssetTask(MessageID messageID, const QByteArray& assetHash, QString filePath, DataOffset start, DataOffset end,
|
||||||
|
const SharedNodePointer& sendToNode) :
|
||||||
|
QRunnable(),
|
||||||
|
_messageID(messageID),
|
||||||
|
_assetHash(assetHash),
|
||||||
|
_filePath(filePath),
|
||||||
|
_start(start),
|
||||||
|
_end(end),
|
||||||
|
_sendToNode(sendToNode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendAssetTask::run() {
|
||||||
|
qDebug() << "Starting task to send asset: " << _assetHash << " for messageID " << _messageID;
|
||||||
|
auto replyPacketList = std::unique_ptr<NLPacketList>(new NLPacketList(PacketType::AssetGetReply, QByteArray(), true, true));
|
||||||
|
|
||||||
|
replyPacketList->write(_assetHash, HASH_HEX_LENGTH);
|
||||||
|
|
||||||
|
replyPacketList->writePrimitive(_messageID);
|
||||||
|
|
||||||
|
const int64_t MAX_LENGTH = 4294967296;
|
||||||
|
|
||||||
|
if (_end <= _start) {
|
||||||
|
writeError(replyPacketList.get(), AssetServerError::INVALID_BYTE_RANGE);
|
||||||
|
} else if (_end - _start > MAX_LENGTH) {
|
||||||
|
writeError(replyPacketList.get(), AssetServerError::INVALID_BYTE_RANGE);
|
||||||
|
} else {
|
||||||
|
QFile file { _filePath };
|
||||||
|
|
||||||
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
|
if (file.size() < _end) {
|
||||||
|
writeError(replyPacketList.get(), AssetServerError::INVALID_BYTE_RANGE);
|
||||||
|
qCDebug(networking) << "Bad byte range: " << _assetHash << " " << _start << ":" << _end;
|
||||||
|
} else {
|
||||||
|
auto size = _end - _start;
|
||||||
|
file.seek(_start);
|
||||||
|
replyPacketList->writePrimitive(AssetServerError::NO_ERROR);
|
||||||
|
replyPacketList->writePrimitive(size);
|
||||||
|
replyPacketList->write(file.read(size));
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
qCDebug(networking) << "Sending asset: " << _assetHash;
|
||||||
|
} else {
|
||||||
|
qCDebug(networking) << "Asset not found: " << _assetHash;
|
||||||
|
writeError(replyPacketList.get(), AssetServerError::ASSET_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
nodeList->sendPacketList(std::move(replyPacketList), *_sendToNode);
|
||||||
|
}
|
41
assignment-client/src/assets/SendAssetTask.h
Normal file
41
assignment-client/src/assets/SendAssetTask.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
//
|
||||||
|
// SendAssetTask.h
|
||||||
|
//
|
||||||
|
// Created by Ryan Huffman on 2015/08/26
|
||||||
|
// Copyright 2015 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_SendAssetTask_h
|
||||||
|
#define hifi_SendAssetTask_h
|
||||||
|
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QString>
|
||||||
|
#include <QRunnable>
|
||||||
|
|
||||||
|
#include "AssetUtils.h"
|
||||||
|
#include "AssetServer.h"
|
||||||
|
#include "Node.h"
|
||||||
|
|
||||||
|
class SendAssetTask : public QRunnable {
|
||||||
|
public:
|
||||||
|
SendAssetTask(MessageID messageID, const QByteArray& assetHash, QString filePath, DataOffset start, DataOffset end,
|
||||||
|
const SharedNodePointer& sendToNode);
|
||||||
|
|
||||||
|
void run();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
MessageID _messageID;
|
||||||
|
QByteArray _assetHash;
|
||||||
|
QString _filePath;
|
||||||
|
DataOffset _start;
|
||||||
|
DataOffset _end;
|
||||||
|
SharedNodePointer _sendToNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -53,7 +53,6 @@
|
||||||
#include <AccountManager.h>
|
#include <AccountManager.h>
|
||||||
#include <AddressManager.h>
|
#include <AddressManager.h>
|
||||||
#include <AssetClient.h>
|
#include <AssetClient.h>
|
||||||
#include <AssetScriptingInterface.h>
|
|
||||||
#include <ApplicationVersion.h>
|
#include <ApplicationVersion.h>
|
||||||
#include <CursorManager.h>
|
#include <CursorManager.h>
|
||||||
#include <AudioInjector.h>
|
#include <AudioInjector.h>
|
||||||
|
@ -300,7 +299,6 @@ bool setupEssentials(int& argc, char** argv) {
|
||||||
auto pathUtils = DependencyManager::set<PathUtils>();
|
auto pathUtils = DependencyManager::set<PathUtils>();
|
||||||
auto actionFactory = DependencyManager::set<InterfaceActionFactory>();
|
auto actionFactory = DependencyManager::set<InterfaceActionFactory>();
|
||||||
auto assetClient = DependencyManager::set<AssetClient>();
|
auto assetClient = DependencyManager::set<AssetClient>();
|
||||||
auto assetScriptingInterface = DependencyManager::set<AssetScriptingInterface>();
|
|
||||||
auto userInputMapper = DependencyManager::set<UserInputMapper>();
|
auto userInputMapper = DependencyManager::set<UserInputMapper>();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -3987,8 +3985,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
|
||||||
qScriptRegisterMetaType(scriptEngine, RayToOverlayIntersectionResultToScriptValue,
|
qScriptRegisterMetaType(scriptEngine, RayToOverlayIntersectionResultToScriptValue,
|
||||||
RayToOverlayIntersectionResultFromScriptValue);
|
RayToOverlayIntersectionResultFromScriptValue);
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("Assets", DependencyManager::get<AssetScriptingInterface>().data());
|
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("Desktop", DependencyManager::get<DesktopScriptingInterface>().data());
|
scriptEngine->registerGlobalObject("Desktop", DependencyManager::get<DesktopScriptingInterface>().data());
|
||||||
|
|
||||||
QScriptValue windowValue = scriptEngine->registerGlobalObject("Window", DependencyManager::get<WindowScriptingInterface>().data());
|
QScriptValue windowValue = scriptEngine->registerGlobalObject("Window", DependencyManager::get<WindowScriptingInterface>().data());
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
//
|
|
||||||
// AssetScriptingInterface.cpp
|
|
||||||
//
|
|
||||||
// Created by Ryan Huffman on 2015/07/22
|
|
||||||
// Copyright 2015 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
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "AssetScriptingInterface.h"
|
|
||||||
|
|
||||||
#include <QScriptEngine>
|
|
||||||
|
|
||||||
#include <AssetClient.h>
|
|
||||||
#include <AssetRequest.h>
|
|
||||||
#include <DependencyManager.h>
|
|
||||||
#include <NLPacket.h>
|
|
||||||
#include <NodeList.h>
|
|
||||||
#include <PacketReceiver.h>
|
|
||||||
|
|
||||||
#include <ResourceManager.h>
|
|
||||||
|
|
||||||
AssetScriptingInterface::AssetScriptingInterface() {
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue AssetScriptingInterface::getAsset(QString url, QScriptValue callback) {
|
|
||||||
|
|
||||||
auto assetClient = DependencyManager::get<AssetClient>();
|
|
||||||
// auto request = assetClient->requestAsset(url);
|
|
||||||
auto request = assetClient->create(url);
|
|
||||||
|
|
||||||
if (!request) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(request, &AssetRequest::finished, [callback](AssetRequest* req) mutable {
|
|
||||||
auto result = callback.engine()->newVariant(req->getData());
|
|
||||||
QList<QScriptValue> arguments { true, result };
|
|
||||||
callback.call(QScriptValue(), arguments);
|
|
||||||
});
|
|
||||||
|
|
||||||
request->start();
|
|
||||||
|
|
||||||
// bool success = AssetManager::getAsset(QUrl(url), [callback](AssetRequestUpdateType type, QByteArray data) mutable {
|
|
||||||
// auto result = callback.engine()->newVariant(data);
|
|
||||||
// QList<QScriptValue> arguments { type == AssetRequestUpdateType::COMPLETE, result };
|
|
||||||
// callback.call(QScriptValue(), arguments);
|
|
||||||
// });
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValue AssetScriptingInterface::uploadAsset(QString data, QString extension, QScriptValue callback) {
|
|
||||||
auto assetClient = DependencyManager::get<AssetClient>();
|
|
||||||
return assetClient->uploadAsset(data.toLatin1(), extension, [callback](bool success, QString hash) mutable {
|
|
||||||
QList<QScriptValue> arguments { success, hash };
|
|
||||||
auto result = callback.call(QScriptValue(), arguments);
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
//
|
|
||||||
// AssetScriptingInterface.h
|
|
||||||
//
|
|
||||||
// Created by Ryan Huffman on 2015/07/22
|
|
||||||
// Copyright 2015 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
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef hifi_AssetScriptingInterface_h
|
|
||||||
#define hifi_AssetScriptingInterface_h
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
#include <QScriptValue>
|
|
||||||
|
|
||||||
#include <DependencyManager.h>
|
|
||||||
#include <LimitedNodeList.h>
|
|
||||||
#include <NLPacket.h>
|
|
||||||
|
|
||||||
class AssetScriptingInterface : public QObject, public Dependency {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
AssetScriptingInterface();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
QScriptValue getAsset(QString hash, QScriptValue callback);
|
|
||||||
QScriptValue uploadAsset(QString data, QString extension, QScriptValue callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -11,6 +11,8 @@
|
||||||
#ifndef hifi_AssetUtils_h
|
#ifndef hifi_AssetUtils_h
|
||||||
#define hifi_AssetUtils_h
|
#define hifi_AssetUtils_h
|
||||||
|
|
||||||
|
#include "NLPacketList.h"
|
||||||
|
|
||||||
using MessageID = uint32_t;
|
using MessageID = uint32_t;
|
||||||
using DataOffset = int64_t;
|
using DataOffset = int64_t;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue