Some minor changes
This commit is contained in:
parent
58dce86e0f
commit
8e7c207720
@ -3,7 +3,7 @@ import {
|
||||
AbstractServerConnection,
|
||||
CommandOptionDefaults,
|
||||
CommandOptions,
|
||||
ConnectionStateListener, ConnectionStatistics,
|
||||
ConnectionStatistics,
|
||||
ServerCommand
|
||||
} from "tc-shared/connection/ConnectionBase";
|
||||
import {CommandResult} from "tc-shared/connection/ServerConnectionDeclaration";
|
||||
@ -353,9 +353,11 @@ export class ServerConnection extends AbstractServerConnection {
|
||||
}
|
||||
|
||||
getControlStatistics(): ConnectionStatistics {
|
||||
const stats = this.nativeHandle?.statistics();
|
||||
|
||||
return {
|
||||
bytesReceived: 0,
|
||||
bytesSend: 0
|
||||
bytesReceived: stats?.control_bytes_received ? stats?.control_bytes_received : 0,
|
||||
bytesSend: stats?.control_bytes_send ? stats?.control_bytes_send : 0
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import {
|
||||
WhisperSessionInitializer
|
||||
} from "tc-shared/connection/VoiceConnection";
|
||||
import {RecorderProfile} from "tc-shared/voice/RecorderProfile";
|
||||
import {NativeVoiceClient, NativeVoiceConnection, PlayerState} from "tc-native/connection";
|
||||
import {NativeServerConnection, NativeVoiceClient, NativeVoiceConnection, PlayerState} from "tc-native/connection";
|
||||
import {ServerConnection} from "./ServerConnection";
|
||||
import {VoiceClient} from "tc-shared/voice/VoiceClient";
|
||||
import {WhisperSession, WhisperTarget} from "tc-shared/voice/VoiceWhisper";
|
||||
@ -231,9 +231,12 @@ export class NativeVoiceConnectionWrapper extends AbstractVoiceConnection {
|
||||
}
|
||||
|
||||
getConnectionStats(): Promise<ConnectionStatistics> {
|
||||
/* FIXME: This is iffy! */
|
||||
const stats = (this.connection as any as NativeServerConnection)["nativeHandle"]?.statistics();
|
||||
|
||||
return Promise.resolve({
|
||||
bytesSend: 0,
|
||||
bytesReceived: 0
|
||||
bytesSend: stats?.voice_bytes_send ? stats?.voice_bytes_send : 0,
|
||||
bytesReceived: stats?.voice_bytes_received ? stats?.voice_bytes_received : 0
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ message("Module path: ${CMAKE_MODULE_PATH}")
|
||||
function(setup_nodejs)
|
||||
set(NodeJS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||
set(NODEJS_URL "https://atom.io/download/atom-shell")
|
||||
set(NODEJS_VERSION "v11.0.3")
|
||||
set(NODEJS_VERSION "v8.0.0")
|
||||
|
||||
#set(NODEJS_URL "https://nodejs.org/download/release/")
|
||||
#set(NODEJS_VERSION "v12.13.0")
|
||||
|
2
native/serverconnection/exports/exports.d.ts
vendored
2
native/serverconnection/exports/exports.d.ts
vendored
@ -78,6 +78,8 @@ declare module "tc-native/connection" {
|
||||
|
||||
/* ping in microseconds */
|
||||
current_ping() : number;
|
||||
|
||||
statistics() : { voice_bytes_received: number, voice_bytes_send: number, control_bytes_received: number, control_bytes_send } | undefined
|
||||
}
|
||||
|
||||
export function spawn_server_connection() : NativeServerConnection;
|
||||
|
@ -67,6 +67,11 @@ void ProtocolHandler::reset() {
|
||||
this->crypt_handler.reset();
|
||||
|
||||
this->ping.ping_received_timestamp = system_clock::time_point{};
|
||||
|
||||
this->statistics_.control_bytes_received = 0;
|
||||
this->statistics_.control_bytes_send = 0;
|
||||
this->statistics_.voice_bytes_send = 0;
|
||||
this->statistics_.voice_bytes_received = 0;
|
||||
}
|
||||
|
||||
void ProtocolHandler::connect() {
|
||||
@ -125,8 +130,9 @@ void ProtocolHandler::execute_tick() {
|
||||
}
|
||||
|
||||
void ProtocolHandler::execute_resend() {
|
||||
if(this->connection_state >= connection_state::DISCONNECTED)
|
||||
if(this->connection_state >= connection_state::DISCONNECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::deque<std::shared_ptr<ts::connection::AcknowledgeManager::Entry>> buffers;
|
||||
auto now = system_clock::now();
|
||||
@ -145,8 +151,12 @@ void ProtocolHandler::execute_resend() {
|
||||
|
||||
auto socket = this->handle->get_socket();
|
||||
if(socket) {
|
||||
for(const auto& buffer : buffers)
|
||||
for(const auto& buffer : buffers) {
|
||||
socket->send_message(buffer->buffer);
|
||||
|
||||
/* only control packets are getting resend */
|
||||
this->statistics_.control_bytes_send += buffer->buffer.length();
|
||||
}
|
||||
}
|
||||
|
||||
this->handle->schedule_resend(next);
|
||||
@ -169,11 +179,17 @@ void ProtocolHandler::progress_packet(const pipes::buffer_view &buffer) {
|
||||
auto ordered = packet_type.type() == protocol::COMMAND || packet_type.type() == protocol::COMMAND_LOW;
|
||||
//log_trace(category::connection, tr("Received packet {} with id {}"), packet->type().name(), packet->packetId());
|
||||
|
||||
/*
|
||||
if(ordered)
|
||||
if(rand() & 1)
|
||||
return;
|
||||
*/
|
||||
switch(packet_type.type()) {
|
||||
case ts::protocol::PacketType::VOICE:
|
||||
case ts::protocol::PacketType::VOICE_WHISPER:
|
||||
this->statistics_.voice_bytes_received += buffer.length();
|
||||
break;
|
||||
|
||||
case ts::protocol::PacketType::COMMAND:
|
||||
case ts::protocol::PacketType::COMMAND_LOW:
|
||||
this->statistics_.control_bytes_received += buffer.length();
|
||||
break;
|
||||
}
|
||||
|
||||
/* special handling */
|
||||
if(packet_type.type() == protocol::INIT1) {
|
||||
@ -565,6 +581,7 @@ void ProtocolHandler::send_command(const ts::Command &cmd, const std::function<v
|
||||
//log_trace(category::connection, tr("Time needed for command: {}ms. Success: {}"), chrono::duration_cast<chrono::milliseconds>(end - begin).count(), f);
|
||||
});
|
||||
}
|
||||
|
||||
packet->enable_flag(PacketFlag::NewProtocol);
|
||||
this->send_packet(packet);
|
||||
}
|
||||
@ -594,8 +611,24 @@ void ProtocolHandler::send_packet(const std::shared_ptr<ts::protocol::ClientPack
|
||||
return;
|
||||
}
|
||||
|
||||
for(const auto& buffer : result)
|
||||
size_t total_size{0};
|
||||
for(const auto& buffer : result) {
|
||||
socket->send_message(buffer);
|
||||
|
||||
total_size += buffer.length();
|
||||
}
|
||||
|
||||
switch(packet->type().type()) {
|
||||
case ts::protocol::PacketType::VOICE:
|
||||
case ts::protocol::PacketType::VOICE_WHISPER:
|
||||
this->statistics_.voice_bytes_send += total_size;
|
||||
break;
|
||||
|
||||
case ts::protocol::PacketType::COMMAND:
|
||||
case ts::protocol::PacketType::COMMAND_LOW:
|
||||
this->statistics_.control_bytes_send += total_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolHandler::send_acknowledge(uint16_t packet_id, bool low) {
|
||||
@ -632,4 +665,8 @@ void ProtocolHandler::disconnect(const std::string &reason) {
|
||||
if(success && this->connection_state == connection_state::DISCONNECTING && this->disconnect_id == did)
|
||||
this->handle->close_connection();
|
||||
});
|
||||
}
|
||||
|
||||
const ConnectionStatistics& ProtocolHandler::statistics() {
|
||||
return this->statistics_;
|
||||
}
|
@ -16,139 +16,147 @@
|
||||
#include <protocol/generation.h>
|
||||
#include "ServerConnection.h"
|
||||
|
||||
namespace ts {
|
||||
namespace connection {
|
||||
class CryptionHandler;
|
||||
class CompressionHandler;
|
||||
}
|
||||
namespace ts::connection {
|
||||
class CryptionHandler;
|
||||
class CompressionHandler;
|
||||
}
|
||||
|
||||
namespace tc {
|
||||
namespace connection {
|
||||
class ServerConnection;
|
||||
namespace tc::connection {
|
||||
class ServerConnection;
|
||||
|
||||
namespace connection_state {
|
||||
enum value {
|
||||
INITIALIZING,
|
||||
INIT_LOW,
|
||||
INIT_HIGH,
|
||||
CONNECTING,
|
||||
CONNECTED,
|
||||
DISCONNECTING,
|
||||
DISCONNECTED
|
||||
};
|
||||
};
|
||||
namespace pow_state {
|
||||
enum value : uint8_t {
|
||||
COOKIE_GET,
|
||||
COOKIE_SET,
|
||||
PUZZLE_GET,
|
||||
PUZZLE_SET,
|
||||
PUZZLE_SOLVE,
|
||||
PUZZLE_RESET,
|
||||
COMPLETED,
|
||||
COMMAND_RESET = 127,
|
||||
UNSET = 0xFB
|
||||
};
|
||||
};
|
||||
namespace connection_state {
|
||||
enum value {
|
||||
INITIALIZING,
|
||||
INIT_LOW,
|
||||
INIT_HIGH,
|
||||
CONNECTING,
|
||||
CONNECTED,
|
||||
DISCONNECTING,
|
||||
DISCONNECTED
|
||||
};
|
||||
};
|
||||
namespace pow_state {
|
||||
enum value : uint8_t {
|
||||
COOKIE_GET,
|
||||
COOKIE_SET,
|
||||
PUZZLE_GET,
|
||||
PUZZLE_SET,
|
||||
PUZZLE_SOLVE,
|
||||
PUZZLE_RESET,
|
||||
COMPLETED,
|
||||
COMMAND_RESET = 127,
|
||||
UNSET = 0xFB
|
||||
};
|
||||
};
|
||||
|
||||
class ProtocolHandler {
|
||||
typedef ts::protocol::PacketRingBuffer<ts::protocol::ServerPacket, 88> packet_buffer_t;
|
||||
typedef std::array<packet_buffer_t, 8> packet_buffers_t;
|
||||
friend class ServerConnection;
|
||||
public:
|
||||
ProtocolHandler(ServerConnection*);
|
||||
~ProtocolHandler();
|
||||
struct ConnectionStatistics {
|
||||
size_t control_bytes_send{0};
|
||||
size_t control_bytes_received{0};
|
||||
|
||||
void reset();
|
||||
void connect();
|
||||
void execute_tick();
|
||||
void execute_resend();
|
||||
size_t voice_bytes_send{0};
|
||||
size_t voice_bytes_received{0};
|
||||
};
|
||||
|
||||
void progress_packet(const pipes::buffer_view& /* buffer */);
|
||||
bool handle_packets(); /* if true we have more left */
|
||||
void send_packet(const std::shared_ptr<ts::protocol::ClientPacket>& /* packet */);
|
||||
void send_command(const ts::Command& /* command */, const std::function<void(bool)> & /* acknowledge callback */ = NULL);
|
||||
class ProtocolHandler {
|
||||
typedef ts::protocol::PacketRingBuffer<ts::protocol::ServerPacket, 88> packet_buffer_t;
|
||||
typedef std::array<packet_buffer_t, 8> packet_buffers_t;
|
||||
friend class ServerConnection;
|
||||
public:
|
||||
explicit ProtocolHandler(ServerConnection*);
|
||||
~ProtocolHandler();
|
||||
|
||||
void disconnect(const std::string& /* message */);
|
||||
void reset();
|
||||
void connect();
|
||||
void execute_tick();
|
||||
void execute_resend();
|
||||
|
||||
void send_acknowledge(uint16_t /* packet id */, bool /* low */);
|
||||
const ConnectionStatistics& statistics();
|
||||
|
||||
ecc_key& get_identity_key() { return this->crypto.identity; }
|
||||
void progress_packet(const pipes::buffer_view& /* buffer */);
|
||||
bool handle_packets(); /* if true we have more left */
|
||||
void send_packet(const std::shared_ptr<ts::protocol::ClientPacket>& /* packet */);
|
||||
void send_command(const ts::Command& /* command */, const std::function<void(bool)> & /* acknowledge callback */ = NULL);
|
||||
|
||||
inline std::chrono::microseconds current_ping() { return this->ping.value; }
|
||||
void disconnect(const std::string& /* message */);
|
||||
void send_acknowledge(uint16_t /* packet id */, bool /* low */);
|
||||
|
||||
connection_state::value connection_state = connection_state::INITIALIZING;
|
||||
server_type::value server_type = server_type::TEASPEAK;
|
||||
private:
|
||||
void do_close_connection(); /* only call from ServerConnection. Close all connections via ServerConnection! */
|
||||
ecc_key& get_identity_key() { return this->crypto.identity; }
|
||||
|
||||
void handlePacketCommand(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
||||
void handlePacketAck(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
||||
void handlePacketVoice(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
||||
void handlePacketPing(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
||||
void handlePacketInit(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
||||
inline std::chrono::microseconds current_ping() { return this->ping.value; }
|
||||
|
||||
bool create_datagram_packets(std::vector<pipes::buffer> &result, const std::shared_ptr<ts::protocol::ClientPacket> &packet);
|
||||
connection_state::value connection_state = connection_state::INITIALIZING;
|
||||
server_type::value server_type = server_type::TEASPEAK;
|
||||
private:
|
||||
void do_close_connection(); /* only call from ServerConnection. Close all connections via ServerConnection! */
|
||||
|
||||
ServerConnection* handle;
|
||||
void handlePacketCommand(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
||||
void handlePacketAck(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
||||
void handlePacketVoice(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
||||
void handlePacketPing(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
||||
void handlePacketInit(const std::shared_ptr<ts::protocol::ServerPacket>&);
|
||||
|
||||
std::chrono::system_clock::time_point connect_timestamp;
|
||||
std::chrono::system_clock::time_point disconnect_timestamp;
|
||||
uint8_t disconnect_id = 0;
|
||||
bool create_datagram_packets(std::vector<pipes::buffer> &result, const std::shared_ptr<ts::protocol::ClientPacket> &packet);
|
||||
|
||||
struct {
|
||||
size_t retry_count{0};
|
||||
pow_state::value state;
|
||||
ServerConnection* handle;
|
||||
|
||||
uint64_t client_ts3_build_timestamp = 173265950 /* TS3 */; /* needs to be lower than 173265950 for old stuff, else new protocol */
|
||||
uint8_t client_control_data[4] = {0,0,0,0};
|
||||
uint8_t server_control_data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
uint8_t server_data[100];
|
||||
std::chrono::system_clock::time_point connect_timestamp;
|
||||
std::chrono::system_clock::time_point disconnect_timestamp;
|
||||
uint8_t disconnect_id = 0;
|
||||
|
||||
std::chrono::system_clock::time_point last_response;
|
||||
std::chrono::system_clock::time_point last_resend;
|
||||
pipes::buffer last_buffer;
|
||||
} pow;
|
||||
void pow_send_cookie_get();
|
||||
struct {
|
||||
size_t retry_count{0};
|
||||
pow_state::value state;
|
||||
|
||||
struct {
|
||||
uint8_t alpha[10];
|
||||
uint8_t beta[54];
|
||||
uint8_t beta_length; /* 10 or 54 */
|
||||
uint64_t client_ts3_build_timestamp = 173265950 /* TS3 */; /* needs to be lower than 173265950 for old stuff, else new protocol */
|
||||
uint8_t client_control_data[4] = {0,0,0,0};
|
||||
uint8_t server_control_data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
uint8_t server_data[100];
|
||||
|
||||
ecc_key identity{};
|
||||
std::chrono::system_clock::time_point last_response;
|
||||
std::chrono::system_clock::time_point last_resend;
|
||||
pipes::buffer last_buffer;
|
||||
} pow;
|
||||
void pow_send_cookie_get();
|
||||
|
||||
std::string initiv_command;
|
||||
} crypto;
|
||||
std::string generate_client_initiv();
|
||||
struct {
|
||||
uint8_t alpha[10];
|
||||
uint8_t beta[54];
|
||||
uint8_t beta_length; /* 10 or 54 */
|
||||
|
||||
uint16_t client_id = 0;
|
||||
ts::protocol::PacketIdManager _packet_id_manager;
|
||||
packet_buffers_t _packet_buffers;
|
||||
std::array<bool, 9> _packet_buffer_overflow{false};
|
||||
ecc_key identity{};
|
||||
|
||||
std::array<ts::protocol::generation_estimator, 9> incoming_generation_estimators{}; /* implementation is thread save */
|
||||
uint8_t _packet_buffers_index = 0;
|
||||
std::string initiv_command;
|
||||
} crypto;
|
||||
std::string generate_client_initiv();
|
||||
|
||||
bool crypt_setupped{false};
|
||||
ts::connection::CryptHandler crypt_handler;
|
||||
ts::connection::CompressionHandler compression_handler;
|
||||
ts::connection::AcknowledgeManager acknowledge_handler;
|
||||
uint16_t client_id = 0;
|
||||
ts::protocol::PacketIdManager _packet_id_manager;
|
||||
packet_buffers_t _packet_buffers;
|
||||
std::array<bool, 9> _packet_buffer_overflow{false};
|
||||
|
||||
void handleCommandInitIVExpend(ts::Command&);
|
||||
void handleCommandInitIVExpend2(ts::Command&);
|
||||
void handleCommandInitServer(ts::Command&);
|
||||
std::array<ts::protocol::generation_estimator, 9> incoming_generation_estimators{}; /* implementation is thread save */
|
||||
uint8_t _packet_buffers_index = 0;
|
||||
|
||||
struct {
|
||||
std::chrono::system_clock::time_point ping_send_timestamp;
|
||||
std::chrono::system_clock::time_point ping_received_timestamp;
|
||||
std::chrono::microseconds value;
|
||||
uint16_t ping_id;
|
||||
bool crypt_setupped{false};
|
||||
ts::connection::CryptHandler crypt_handler;
|
||||
ts::connection::CompressionHandler compression_handler;
|
||||
ts::connection::AcknowledgeManager acknowledge_handler;
|
||||
|
||||
std::chrono::microseconds interval = std::chrono::microseconds(2500);
|
||||
} ping;
|
||||
void ping_send_request();
|
||||
};
|
||||
}
|
||||
ConnectionStatistics statistics_{};
|
||||
|
||||
struct {
|
||||
std::chrono::system_clock::time_point ping_send_timestamp{};
|
||||
std::chrono::system_clock::time_point ping_received_timestamp{};
|
||||
std::chrono::microseconds value{0};
|
||||
uint16_t ping_id{0};
|
||||
|
||||
std::chrono::microseconds interval{2500};
|
||||
} ping;
|
||||
|
||||
void handleCommandInitIVExpend(ts::Command&);
|
||||
void handleCommandInitIVExpend2(ts::Command&);
|
||||
void handleCommandInitServer(ts::Command&);
|
||||
|
||||
void ping_send_request();
|
||||
};
|
||||
}
|
@ -16,14 +16,16 @@ using namespace ts::protocol;
|
||||
using namespace ts;
|
||||
|
||||
inline void generate_random(uint8_t *destination, size_t length) {
|
||||
while(length-- > 0)
|
||||
*(destination++) = (uint8_t) rand();
|
||||
while(length-- > 0) {
|
||||
*(destination++) = (uint8_t) rand();
|
||||
}
|
||||
}
|
||||
|
||||
inline void write_reversed(uint8_t* destination, uint8_t* source, size_t length) {
|
||||
destination += length;
|
||||
while(length-- > 0)
|
||||
*(--destination) = *(source++);
|
||||
while(length-- > 0) {
|
||||
*(--destination) = *(source++);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool solve_puzzle(mp_int& x, mp_int& n, mp_int& result, uint32_t level) {
|
||||
@ -63,8 +65,10 @@ void ProtocolHandler::handlePacketInit(const std::shared_ptr<ts::protocol::Serve
|
||||
}
|
||||
|
||||
log_trace(category::connection, tr("[POW] State {} | {}"), packet_state, data.length());
|
||||
if(packet_state != this->pow.state)
|
||||
return; //TODO handle error?
|
||||
if(packet_state != this->pow.state) {
|
||||
return; //TODO handle error?
|
||||
}
|
||||
|
||||
this->acknowledge_handler.reset(); /* we don't need an ack anymore for our init packet */
|
||||
|
||||
if(packet_state == pow_state::COOKIE_SET) {
|
||||
@ -146,6 +150,7 @@ void ProtocolHandler::handlePacketInit(const std::shared_ptr<ts::protocol::Serve
|
||||
this->pow.last_resend = system_clock::now();
|
||||
this->send_packet(make_shared<ClientPacket>(PacketTypeInfo::Init1, PacketFlag::Unencrypted, this->pow.last_buffer));
|
||||
}
|
||||
|
||||
mp_clear_multi(&point_x, &point_n, &result, nullptr);
|
||||
this->connection_state = connection_state::INIT_HIGH;
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ NAN_MODULE_INIT(ServerConnection::Init) {
|
||||
Nan::SetPrototypeMethod(klass, "send_voice_data", ServerConnection::_send_voice_data);
|
||||
Nan::SetPrototypeMethod(klass, "send_voice_data_raw", ServerConnection::_send_voice_data_raw);
|
||||
Nan::SetPrototypeMethod(klass, "current_ping", ServerConnection::_current_ping);
|
||||
Nan::SetPrototypeMethod(klass, "statistics", ServerConnection::statistics);
|
||||
|
||||
constructor().Reset(Nan::GetFunction(klass).ToLocalChecked());
|
||||
}
|
||||
@ -620,7 +621,7 @@ void ServerConnection::send_voice_data(const void *buffer, size_t buffer_length,
|
||||
}
|
||||
|
||||
void ServerConnection::close_connection() {
|
||||
lock_guard lock(this->disconnect_lock);
|
||||
lock_guard lock{this->disconnect_lock};
|
||||
if(this->socket && this_thread::get_id() == this->socket->io_thread().get_id()) {
|
||||
logger::debug(category::connection, tr("close_connection() called in IO thread. Closing connection within event loop!"));
|
||||
if(!this->event_loop_execute_connection_close) {
|
||||
@ -643,11 +644,13 @@ void ServerConnection::close_connection() {
|
||||
}
|
||||
|
||||
void ServerConnection::execute_tick() {
|
||||
if(this->protocol_handler)
|
||||
this->protocol_handler->execute_tick();
|
||||
if(this->protocol_handler) {
|
||||
this->protocol_handler->execute_tick();
|
||||
}
|
||||
|
||||
if(auto vc{this->voice_connection}; vc)
|
||||
vc->execute_tick();
|
||||
if(auto vc{this->voice_connection}; vc) {
|
||||
vc->execute_tick();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerConnection::_execute_callback_commands() {
|
||||
@ -759,9 +762,30 @@ void ServerConnection::_execute_callback_disconnect(const std::string &reason) {
|
||||
|
||||
NAN_METHOD(ServerConnection::_current_ping) {
|
||||
auto connection = ObjectWrap::Unwrap<ServerConnection>(info.Holder());
|
||||
lock_guard lock{connection->disconnect_lock};
|
||||
|
||||
auto& phandler = connection->protocol_handler;
|
||||
if(phandler)
|
||||
info.GetReturnValue().Set((uint32_t) chrono::floor<microseconds>(phandler->current_ping()).count());
|
||||
else
|
||||
info.GetReturnValue().Set(-1);
|
||||
}
|
||||
|
||||
NAN_METHOD(ServerConnection::statistics) {
|
||||
auto connection = ObjectWrap::Unwrap<ServerConnection>(info.Holder());
|
||||
lock_guard lock{connection->disconnect_lock};
|
||||
|
||||
auto& phandler = connection->protocol_handler;
|
||||
if(phandler) {
|
||||
auto statistics = phandler->statistics();
|
||||
|
||||
auto result = Nan::New<v8::Object>();
|
||||
Nan::Set(result, Nan::LocalString("voice_bytes_received"), Nan::New<v8::Number>(statistics.voice_bytes_received));
|
||||
Nan::Set(result, Nan::LocalString("voice_bytes_send"), Nan::New<v8::Number>(statistics.voice_bytes_send));
|
||||
Nan::Set(result, Nan::LocalString("control_bytes_received"), Nan::New<v8::Number>(statistics.control_bytes_received));
|
||||
Nan::Set(result, Nan::LocalString("control_bytes_send"), Nan::New<v8::Number>(statistics.control_bytes_send));
|
||||
info.GetReturnValue().Set(result);
|
||||
} else {
|
||||
info.GetReturnValue().Set(Nan::Undefined());
|
||||
}
|
||||
}
|
@ -86,6 +86,7 @@ namespace tc {
|
||||
static NAN_METHOD(_send_voice_data_raw);
|
||||
static NAN_METHOD(_error_message);
|
||||
static NAN_METHOD(_current_ping);
|
||||
static NAN_METHOD(statistics);
|
||||
|
||||
std::unique_ptr<Nan::Callback> callback_connect;
|
||||
std::unique_ptr<Nan::Callback> callback_disconnect;
|
||||
|
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "TeaClient",
|
||||
"version": "1.4.13",
|
||||
"version": "1.5.0-2",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
Loading…
Reference in New Issue
Block a user