Some changes
This commit is contained in:
parent
787f911b6f
commit
79f8c91157
@ -1 +1 @@
|
||||
Subproject commit 535d63f039b3e0b0559e7e09a5c80b04111fe93f
|
||||
Subproject commit 0063a5acb2f6f5af91ca1d06dd27f432ec78e8a9
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <misc/base64.h>
|
||||
#include <misc/digest.h>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
@ -24,6 +25,7 @@ using namespace license;
|
||||
* Requests (license) / ip: SELECT DISTINCT `ip`, COUNT(`ip`) FROM `license_request` WHERE `keyId` = ? GROUP BY `ip`
|
||||
*
|
||||
* SELECT DISTINCT(`ip`), `keyId` FROM `license_request` WHERE `timestamp` > (UNIX_TIMESTAMP() - 2 * 60 * 60) * 1000
|
||||
* //462
|
||||
*
|
||||
* SELECT DISTINCT(`ip`), `license_request`.`keyId`, `license_info`.`username` FROM `license_request` LEFT JOIN `license_info` ON `license_info`.`keyId` = `license_request`.`keyId` WHERE `timestamp` > (UNIX_TIMESTAMP() - 2 * 60 * 60) * 1000
|
||||
*
|
||||
@ -110,9 +112,15 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
{
|
||||
*/
|
||||
/*
|
||||
{
|
||||
ofstream _file_out("version_history.txt");
|
||||
|
||||
auto _now = system_clock::now();
|
||||
auto statistics = license_manager->list_statistics_version(_now - hours(24) * 9, _now, duration_cast<milliseconds>(hours(1)));
|
||||
cout << "Getting statistics" << endl;
|
||||
auto statistics = license_manager->list_statistics_version(_now - hours(24) * 32 * 12, _now, duration_cast<milliseconds>(hours(1)));
|
||||
cout << "Grouping statistics" << endl;
|
||||
std::deque<std::string> versions;
|
||||
const auto version_name = [](const std::string& key) {
|
||||
auto space = key.find(' ');
|
||||
@ -130,6 +138,7 @@ int main(int argc, char** argv) {
|
||||
versions.push_back(name);
|
||||
}
|
||||
}
|
||||
cout << "Sorting statistics" << endl;
|
||||
sort(versions.begin(), versions.end(), [](const std::string& a, const std::string& b) {
|
||||
const auto index_a = a.find_last_of('.');
|
||||
const auto index_b = b.find_last_of('.');
|
||||
@ -141,10 +150,11 @@ int main(int argc, char** argv) {
|
||||
return patch_a > patch_b;
|
||||
});
|
||||
|
||||
cout << "Date";
|
||||
for(auto it = versions.begin(); it != versions.end(); it++)
|
||||
cout << "," << *it;
|
||||
cout << endl;
|
||||
cout << "Writing statistics" << endl;
|
||||
_file_out << "Date";
|
||||
for(auto & version : versions)
|
||||
_file_out << "," << version;
|
||||
_file_out << endl;
|
||||
|
||||
for(const auto& entry : statistics) {
|
||||
auto time = system_clock::to_time_t(entry->timestamp);
|
||||
@ -158,14 +168,17 @@ int main(int argc, char** argv) {
|
||||
version_count[name] += version.second;
|
||||
}
|
||||
|
||||
cout << string_time;
|
||||
_file_out << string_time;
|
||||
for(const auto& name : versions) {
|
||||
cout << "," << version_count[name];
|
||||
_file_out << "," << version_count[name];
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
*/
|
||||
_file_out << endl;
|
||||
}s
|
||||
cout << "Done statistics" << endl;
|
||||
_file_out.flush();
|
||||
}
|
||||
return 0;
|
||||
*/
|
||||
|
||||
ssl_manager = make_shared<ts::ssl::SSLManager>();
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ message ServerValidation {
|
||||
}
|
||||
|
||||
message LicenseResponse {
|
||||
required bool valid = 1;
|
||||
required bool valid = 1; //If set the license is valid. The blacklist field could still be active. If the flag is false then the blacklist will container the message
|
||||
required Blacklist blacklist = 2;
|
||||
optional LicenseInfo license_info = 3; //Only availible when ServerValidation::license_info = true
|
||||
}
|
||||
|
@ -305,43 +305,117 @@ bool LicenseManager::logStatistic(const std::string &key, const std::string& uni
|
||||
return true;
|
||||
}
|
||||
|
||||
std::deque<std::unique_ptr<LicenseManager::GlobalUserStatistics>> LicenseManager::list_statistics_user(const system_clock::time_point &begin, const system_clock::time_point &end, const milliseconds &interval) {
|
||||
map<std::string, deque<unique_ptr<LicenseManager::UserStatistics>>> server_statistics;
|
||||
std::shared_ptr<LicenseManager::UserHistory> LicenseManager::list_statistics_user(const system_clock::time_point &begin, const system_clock::time_point &end, const milliseconds &interval) {
|
||||
auto timeout = hours(2) + minutes(10); //TODO timeout configurable?
|
||||
|
||||
auto state = command(this->database,"SELECT * FROM `history_online` WHERE `timestamp` >= :timestamp_start AND `timestamp` <= :timestamp_end ORDER BY `timestamp` ASC",
|
||||
/* initialize the result */
|
||||
auto allocated_records = (size_t) floor((end - begin) / interval) + 1;
|
||||
auto _result = (UserHistory*) malloc(sizeof(UserHistory) + sizeof(GlobalUserStatistics) * allocated_records);
|
||||
new (_result) UserHistory();
|
||||
|
||||
auto result = shared_ptr<UserHistory>(_result, [](UserHistory* ptr){
|
||||
ptr->~UserHistory();
|
||||
free(ptr);
|
||||
});
|
||||
|
||||
|
||||
result->record_count = 0;
|
||||
result->begin = begin;
|
||||
result->end = end;
|
||||
result->interval = interval;
|
||||
|
||||
memset(&result->history[0], 0, allocated_records * sizeof(GlobalUserStatistics));
|
||||
auto info = &_result->history[0];
|
||||
|
||||
/* temp db variables */
|
||||
map<std::string, LicenseManager::DatabaseUserStatistics> server_statistics;
|
||||
|
||||
bool have_key, have_uid;
|
||||
LicenseManager::DatabaseUserStatistics temp_stats; /* temp struct for stats parsing */
|
||||
LicenseManager::DatabaseUserStatistics* stats_ptr; /* pointer to the target stats */
|
||||
std::chrono::system_clock::time_point current_timestamp = begin + interval; /* upper limit of the current interval */
|
||||
|
||||
auto state = command(this->database, "SELECT * FROM `history_online` WHERE `timestamp` >= :timestamp_start AND `timestamp` <= :timestamp_end ORDER BY `timestamp` ASC",
|
||||
variable{":timestamp_start", duration_cast<milliseconds>(begin.time_since_epoch() - timeout).count()},
|
||||
variable{":timestamp_end", duration_cast<milliseconds>(end.time_since_epoch()).count()}
|
||||
).query([&server_statistics](int columns, std::string* values, std::string* names){
|
||||
size_t key_id = 0;
|
||||
std::string unique_id;
|
||||
auto info = make_unique<LicenseManager::UserStatistics>();
|
||||
).query([&](int columns, std::string* values, std::string* names) {
|
||||
/* find the user statistic ptr */
|
||||
{
|
||||
size_t key_id = 0;
|
||||
std::string unique_id;
|
||||
|
||||
have_key = false;
|
||||
have_uid = false;
|
||||
for(int index = 0; index < columns; index++) {
|
||||
try {
|
||||
if(names[index] == "keyId") {
|
||||
key_id = stoull(values[index]);
|
||||
have_key = true;
|
||||
} else if(names[index] == "unique_id") {
|
||||
unique_id = values[index];
|
||||
have_uid = true;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
if(have_key && have_uid)
|
||||
break;
|
||||
} catch (std::exception& ex) {
|
||||
logError("Failed to parse column " + names[index] + " => " + ex.what() + " (Value: " + values[index] + ")");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(!have_key || !have_uid) return 0; //TODO: May log a warning
|
||||
if(key_id == 0) return 0;
|
||||
|
||||
stats_ptr = &server_statistics[to_string(key_id) + "_" + unique_id];
|
||||
}
|
||||
|
||||
for(int index = 0; index < columns; index++) {
|
||||
try {
|
||||
if(names[index] == "keyId")
|
||||
key_id = stoull(values[index]);
|
||||
else if(names[index] == "unique_id")
|
||||
unique_id = values[index];
|
||||
else if(names[index] == "timestamp")
|
||||
info->timestamp = system_clock::time_point() + milliseconds(stoll(values[index]));
|
||||
if(names[index] == "timestamp")
|
||||
temp_stats.timestamp = system_clock::time_point() + milliseconds(stoll(values[index]));
|
||||
else if(names[index] == "server")
|
||||
info->servers_online = stoull(values[index]);
|
||||
temp_stats.servers_online = stoull(values[index]);
|
||||
else if(names[index] == "clients")
|
||||
info->clients_online = stoull(values[index]);
|
||||
temp_stats.clients_online = stoull(values[index]);
|
||||
else if(names[index] == "web")
|
||||
info->web_clients_online = stoull(values[index]);
|
||||
temp_stats.web_clients_online = stoull(values[index]);
|
||||
else if(names[index] == "music")
|
||||
info->bots_online = stoull(values[index]);
|
||||
temp_stats.bots_online = stoull(values[index]);
|
||||
else if(names[index] == "queries")
|
||||
info->queries_online = stoull(values[index]);
|
||||
temp_stats.queries_online = stoull(values[index]);
|
||||
} catch (std::exception& ex) {
|
||||
logError("Failed to parse column " + names[index] + " => " + ex.what() + " (Value: " + values[index] + ")");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(key_id == 0) return 0;
|
||||
|
||||
server_statistics[to_string(key_id) + "_" + unique_id].push_back(std::move(info));
|
||||
/* because the query could only be oldest to newest */
|
||||
while(temp_stats.timestamp > current_timestamp) {
|
||||
assert(_result->record_count < allocated_records); /* ensure we write to valid memory */
|
||||
|
||||
auto min_timestamp = current_timestamp - timeout;
|
||||
for(auto& server : server_statistics) {
|
||||
auto& second = server.second;
|
||||
if(second.timestamp < min_timestamp || second.timestamp.time_since_epoch().count() == 0)
|
||||
continue; /* last server request is too old to be counted */
|
||||
|
||||
info->instance_online++;
|
||||
info->queries_online += second.queries_online;
|
||||
info->bots_online += second.bots_online;
|
||||
info->web_clients_online += second.web_clients_online;
|
||||
info->clients_online += second.clients_online;
|
||||
info->servers_online += second.servers_online;
|
||||
}
|
||||
|
||||
info++;
|
||||
_result->record_count++;
|
||||
current_timestamp += interval; /* lets gather for the next interval */
|
||||
}
|
||||
|
||||
/* write the "new" statistic */
|
||||
memcpy(stats_ptr, &temp_stats, sizeof(temp_stats));
|
||||
return 0;
|
||||
});
|
||||
|
||||
@ -350,41 +424,28 @@ std::deque<std::unique_ptr<LicenseManager::GlobalUserStatistics>> LicenseManager
|
||||
return {};
|
||||
}
|
||||
|
||||
std::deque<std::unique_ptr<LicenseManager::GlobalUserStatistics>> result;
|
||||
system_clock::time_point current_timestamp = begin;
|
||||
while(current_timestamp <= end) {
|
||||
auto info = make_unique<LicenseManager::GlobalUserStatistics>();
|
||||
info->timestamp = current_timestamp;
|
||||
/* flush the last record */
|
||||
do {
|
||||
assert(_result->record_count < allocated_records); /* ensure we write to valid memory */
|
||||
|
||||
auto min_timestamp = current_timestamp - timeout;
|
||||
for(auto& server : server_statistics) {
|
||||
while(!server.second.empty()) {
|
||||
auto& first = *server.second.begin();
|
||||
if(first->timestamp > current_timestamp) break; //Entry within the future
|
||||
if(first->timestamp + timeout < current_timestamp) { //Entry within the past
|
||||
server.second.pop_front();
|
||||
continue;
|
||||
}
|
||||
if(server.second.size() > 1) {
|
||||
auto& second = *(server.second.begin() + 1);
|
||||
if(second->timestamp <= current_timestamp) {
|
||||
server.second.pop_front(); //The next entry is more up 2 date
|
||||
continue;
|
||||
}
|
||||
}
|
||||
auto& second = server.second;
|
||||
if(second.timestamp < min_timestamp)
|
||||
continue; /* last server request is too old to be counted */
|
||||
|
||||
info->instance_online++;
|
||||
info->queries_online += first->queries_online;
|
||||
info->bots_online += first->bots_online;
|
||||
info->web_clients_online += first->web_clients_online;
|
||||
info->clients_online += first->clients_online;
|
||||
info->servers_online += first->servers_online;
|
||||
break;
|
||||
}
|
||||
info->instance_online++;
|
||||
info->queries_online += second.queries_online;
|
||||
info->bots_online += second.bots_online;
|
||||
info->web_clients_online += second.web_clients_online;
|
||||
info->clients_online += second.clients_online;
|
||||
info->servers_online += second.servers_online;
|
||||
}
|
||||
|
||||
result.push_back(std::move(info));
|
||||
info++;
|
||||
_result->record_count++;
|
||||
current_timestamp += interval;
|
||||
}
|
||||
} while(current_timestamp < end);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -393,7 +454,7 @@ std::deque<std::unique_ptr<LicenseManager::GlobalVersionsStatistic>> LicenseMana
|
||||
map<std::string, deque<unique_ptr<LicenseManager::GlobalVersionsStatistic>>> server_statistics;
|
||||
auto timeout = hours(2) + minutes(10); //TODO timeout configurable?
|
||||
|
||||
auto state = command(this->database,"SELECT * FROM `history_version` WHERE `timestamp` >= :timestamp_start AND `timestamp` <= :timestamp_end ORDER BY `timestamp` ASC",
|
||||
auto state = command(this->database, "SELECT * FROM `history_version` WHERE `timestamp` >= :timestamp_start AND `timestamp` <= :timestamp_end ORDER BY `timestamp` ASC",
|
||||
variable{":timestamp_start", duration_cast<milliseconds>(begin.time_since_epoch() - timeout).count()},
|
||||
variable{":timestamp_end", duration_cast<milliseconds>(end.time_since_epoch()).count()}
|
||||
).query([&server_statistics](int columns, std::string* values, std::string* names){
|
||||
|
@ -29,13 +29,13 @@ namespace license {
|
||||
threads::Mutex entry_update_lock;
|
||||
std::deque<CacheEntry*> entries;
|
||||
};
|
||||
|
||||
struct UserStatistics {
|
||||
std::chrono::system_clock::time_point timestamp;
|
||||
uint64_t clients_online;
|
||||
uint64_t web_clients_online;
|
||||
uint64_t bots_online;
|
||||
uint64_t queries_online;
|
||||
uint64_t servers_online;
|
||||
uint64_t clients_online = 0;
|
||||
uint64_t web_clients_online = 0;
|
||||
uint64_t bots_online = 0;
|
||||
uint64_t queries_online = 0;
|
||||
uint64_t servers_online = 0;
|
||||
};
|
||||
|
||||
struct ExtendedUserStatistics : public UserStatistics{
|
||||
@ -43,13 +43,28 @@ namespace license {
|
||||
};
|
||||
|
||||
struct GlobalUserStatistics : public UserStatistics {
|
||||
uint64_t instance_online;
|
||||
uint64_t instance_online = 0;
|
||||
};
|
||||
|
||||
struct DatabaseUserStatistics : public UserStatistics {
|
||||
std::chrono::system_clock::time_point timestamp{};
|
||||
};
|
||||
|
||||
struct GlobalVersionsStatistic {
|
||||
std::chrono::system_clock::time_point timestamp;
|
||||
std::map<std::string, uint32_t> versions;
|
||||
};
|
||||
|
||||
struct UserHistory {
|
||||
std::chrono::system_clock::time_point begin{};
|
||||
std::chrono::system_clock::time_point end{};
|
||||
std::chrono::milliseconds interval{0};
|
||||
|
||||
size_t record_count = 0;
|
||||
GlobalUserStatistics history[0];
|
||||
};
|
||||
static_assert(sizeof(UserHistory) == 32);
|
||||
|
||||
public:
|
||||
LicenseManager(sql::SqlManager* database);
|
||||
~LicenseManager();
|
||||
@ -68,7 +83,7 @@ namespace license {
|
||||
bool logRequest(const std::string& /* key */, const std::string& /* unique_id */, const std::string& /* ip */, const std::string& /* version */, int /* result */);
|
||||
bool logStatistic(const std::string& /* key */, const std::string& /* unique_id */, const std::string& /* ip */, const ts::proto::license::PropertyUpdateRequest&);
|
||||
//std::deque<std::unique_ptr<ExtendedUserStatistics>> list_statistics_user(const std::string& key, const std::chrono::system_clock::time_point& begin, const std::chrono::system_clock::time_point& end);
|
||||
std::deque<std::unique_ptr<GlobalUserStatistics>> list_statistics_user(const std::chrono::system_clock::time_point& begin, const std::chrono::system_clock::time_point& end, const std::chrono::milliseconds& /* interval */);
|
||||
std::shared_ptr<UserHistory> list_statistics_user(const std::chrono::system_clock::time_point& begin, const std::chrono::system_clock::time_point& end, const std::chrono::milliseconds& /* interval */);
|
||||
std::deque<std::unique_ptr<GlobalVersionsStatistic>> list_statistics_version(const std::chrono::system_clock::time_point& begin, const std::chrono::system_clock::time_point& end, const std::chrono::milliseconds& /* interval */);
|
||||
|
||||
inline sql::SqlManager* sql() { return this->database; }
|
||||
|
@ -49,6 +49,8 @@ namespace license {
|
||||
std::string key;
|
||||
std::string unique_identifier;
|
||||
|
||||
bool invalid_license = false;
|
||||
|
||||
void init();
|
||||
void uninit();
|
||||
void sendPacket(const protocol::packet&);
|
||||
|
@ -95,14 +95,25 @@ bool LicenseServer::handleDisconnect(shared_ptr<ConnectedClient>& client, protoc
|
||||
|
||||
inline void fill_info(proto::license::LicenseInfo* proto, const shared_ptr<LicenseInfo>& info, const std::string& key) {
|
||||
proto->set_key(key);
|
||||
proto->set_username(info->username);
|
||||
proto->set_first_name(info->first_name);
|
||||
proto->set_last_name(info->last_name);
|
||||
proto->set_email(info->email);
|
||||
proto->set_type(info->type);
|
||||
proto->set_created(duration_cast<milliseconds>(info->creation.time_since_epoch()).count());
|
||||
proto->set_begin(duration_cast<milliseconds>(info->start.time_since_epoch()).count());
|
||||
proto->set_end(duration_cast<milliseconds>(info->end.time_since_epoch()).count());
|
||||
if(info) {
|
||||
proto->set_username(info->username);
|
||||
proto->set_first_name(info->first_name);
|
||||
proto->set_last_name(info->last_name);
|
||||
proto->set_email(info->email);
|
||||
proto->set_type(info->type);
|
||||
proto->set_created(duration_cast<milliseconds>(info->creation.time_since_epoch()).count());
|
||||
proto->set_begin(duration_cast<milliseconds>(info->start.time_since_epoch()).count());
|
||||
proto->set_end(duration_cast<milliseconds>(info->end.time_since_epoch()).count());
|
||||
} else {
|
||||
proto->set_username("invalid (null)");
|
||||
proto->set_first_name("invalid (null)");
|
||||
proto->set_last_name("invalid (null)");
|
||||
proto->set_email("invalid (null)");
|
||||
proto->set_type(0);
|
||||
proto->set_created(0);
|
||||
proto->set_begin(0);
|
||||
proto->set_end(0);
|
||||
}
|
||||
}
|
||||
|
||||
std::string string_to_hex(const std::string& input)
|
||||
@ -154,7 +165,9 @@ bool LicenseServer::handleServerValidation(shared_ptr<ConnectedClient> &client,
|
||||
client->unique_identifier = pkt.info().has_unique_id() ? pkt.info().unique_id() : client->address();
|
||||
if(remoteLicense && pkt.licensed()) {
|
||||
auto info = this->manager->licenseInfo(remoteLicense->key());
|
||||
|
||||
if(!info) {
|
||||
response.mutable_blacklist()->set_reason("License hasn't been found.");
|
||||
response.set_valid(false);
|
||||
|
||||
/*
|
||||
@ -179,6 +192,7 @@ bool LicenseServer::handleServerValidation(shared_ptr<ConnectedClient> &client,
|
||||
logMessage(LOG_GENERAL, "[CLIENT][{}] Remote license hasn't been found in database. Shutting down server!", client->address());
|
||||
} else {
|
||||
if(info->deleted) {
|
||||
response.mutable_blacklist()->set_reason("License has been deleted.");
|
||||
response.set_valid(false);
|
||||
logMessage(LOG_GENERAL, "[CLIENT][{}] Remote license has been deleted! Shutting down server!", client->address());
|
||||
} else {
|
||||
@ -191,7 +205,15 @@ bool LicenseServer::handleServerValidation(shared_ptr<ConnectedClient> &client,
|
||||
response.set_valid(true);
|
||||
}
|
||||
|
||||
response.mutable_blacklist()->set_state(ts::proto::license::VALID);
|
||||
if(response.valid())
|
||||
response.mutable_blacklist()->set_state(ts::proto::license::VALID);
|
||||
else {
|
||||
if(!response.has_license_info())
|
||||
fill_info(response.mutable_license_info(), nullptr, ""); /* "Hack" for old clients which require a license. Else the server would not be stopped */
|
||||
response.mutable_blacklist()->set_state(ts::proto::license::BLACKLISTED); /* "Hack" for all old clients */
|
||||
client->invalid_license = true;
|
||||
}
|
||||
|
||||
client->sendPacket(protocol::packet{protocol::PACKET_SERVER_VALIDATION_RESPONSE, response});
|
||||
client->protocol.state = protocol::PROPERTY_ADJUSTMENT;
|
||||
return true;
|
||||
@ -199,6 +221,18 @@ bool LicenseServer::handleServerValidation(shared_ptr<ConnectedClient> &client,
|
||||
|
||||
bool LicenseServer::handlePacketPropertyUpdate(shared_ptr<ConnectedClient> &client, protocol::packet &packet, std::string &error) {
|
||||
TEST_PROTOCOL_STATE(PROPERTY_ADJUSTMENT);
|
||||
if(client->invalid_license) {
|
||||
ts::proto::license::PropertyUpdateResponse response;
|
||||
response.set_accepted(true);
|
||||
response.set_reset_speach(0);
|
||||
response.set_speach_total_remote(0);
|
||||
response.set_speach_varianz_corrector(0);
|
||||
client->sendPacket(protocol::packet{protocol::PACKET_SERVER_PROPERTY_ADJUSTMENT, response});
|
||||
this->disconnectClient(client, "finished");
|
||||
|
||||
/* Not sure if we really want here to log these data. May put a lvalid=false within the db? */
|
||||
return true;
|
||||
}
|
||||
PARSE_PROTO(PropertyUpdateRequest, pkt);
|
||||
|
||||
logMessage("[CLIENT][" + client->address() + "] Got server statistics:");
|
||||
|
@ -34,9 +34,9 @@ namespace license {
|
||||
std::chrono::system_clock::time_point begin;
|
||||
std::chrono::system_clock::time_point end;
|
||||
std::chrono::milliseconds period;
|
||||
HistoryType type;
|
||||
HistoryType type;
|
||||
|
||||
std::deque<std::unique_ptr<server::LicenseManager::GlobalUserStatistics>> statistics;
|
||||
std::shared_ptr<server::LicenseManager::UserHistory> statistics;
|
||||
};
|
||||
|
||||
class StatisticManager {
|
||||
|
@ -462,13 +462,14 @@ bool WebStatistics::handle_message(const std::shared_ptr<license::web::WebStatis
|
||||
response["history"]["end"] = duration_cast<milliseconds>(history->end.time_since_epoch()).count();
|
||||
response["history"]["interval"] = duration_cast<milliseconds>(history->period).count();
|
||||
|
||||
int index = 0;
|
||||
for(auto& element : history->statistics) {
|
||||
response["history"]["data"][index]["instances"] = element->instance_online;
|
||||
response["history"]["data"][index]["servers"] = element->servers_online;
|
||||
response["history"]["data"][index]["clients"] = element->clients_online;
|
||||
response["history"]["data"][index]["music"] = element->bots_online;
|
||||
index++;
|
||||
|
||||
int index;
|
||||
auto stats = history->statistics;
|
||||
for(index = 0; index < stats->record_count; index++) {
|
||||
response["history"]["data"][index]["instances"] = stats->history[index].instance_online;
|
||||
response["history"]["data"][index]["servers"] = stats->history[index].servers_online;
|
||||
response["history"]["data"][index]["clients"] = stats->history[index].clients_online;
|
||||
response["history"]["data"][index]["music"] = stats->history[index].bots_online;
|
||||
}
|
||||
|
||||
lock_guard lock(client->execute_lock);
|
||||
|
@ -101,7 +101,7 @@ namespace license {
|
||||
|
||||
inline std::string key() { return std::string(data.licenceKey, 64); }
|
||||
inline std::chrono::time_point<std::chrono::system_clock> end() { return std::chrono::system_clock::time_point() + std::chrono::milliseconds(this->data.endTimestamp); }
|
||||
inline std::string owner() { return std::string(this->data.licenceOwner); }
|
||||
inline std::string owner() { return std::string(this->data.licenceOwner); } //Scopetita
|
||||
inline bool isValid() { return data.endTimestamp == 0 || std::chrono::system_clock::now() < this->end(); }
|
||||
inline bool isPremium(){ return isPremiumLicense(data.type); }
|
||||
} __attribute__ ((__packed__));
|
||||
|
@ -9,8 +9,17 @@ using namespace std;
|
||||
using namespace std::chrono;
|
||||
|
||||
void LicenceRequest::handlePacketDisconnect(const std::string& message) {
|
||||
if(this->state != protocol::DISCONNECTING)
|
||||
LICENSE_FERR(this, UnexcpectedDisconnectException, "Remote side closed the connection (" + message + ")");
|
||||
if(this->state != protocol::DISCONNECTING) {
|
||||
/*
|
||||
* We got an early disconnect.
|
||||
* Test if we have a result. If so and the license is invalid then we could use that result
|
||||
*/
|
||||
if(this->response && !this->response->license_valid) {
|
||||
this->currentFuture->executionSucceed(this->response);
|
||||
} else {
|
||||
LICENSE_FERR(this, UnexcpectedDisconnectException, "Remote side closed the connection unexpectedly (" + message + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LicenceRequest::handlePacketHandshake(const std::string& data) {
|
||||
@ -48,7 +57,9 @@ void LicenceRequest::handlePacketLicenseInfo(const std::string& message) {
|
||||
|
||||
auto result = make_shared<LicenseRequestResponse>();
|
||||
auto licenseInfo = make_shared<LicenseInfo>();
|
||||
if(!response.has_license_info() && this->data->license) LICENSE_FERR(this, InvalidResponseException, "Missing license info");
|
||||
if(!response.has_license_info() && this->data->license && response.valid() && response.blacklist().state() == ts::proto::license::VALID) {
|
||||
LICENSE_FERR(this, InvalidResponseException, "Missing license info");
|
||||
}
|
||||
|
||||
if(this->data->license) {
|
||||
licenseInfo->type = (LicenseType) response.license_info().type();
|
||||
@ -75,7 +86,6 @@ void LicenceRequest::handlePacketLicenseInfo(const std::string& message) {
|
||||
result->license = licenseInfo;
|
||||
this->response = result;
|
||||
|
||||
|
||||
ts::proto::license::PropertyUpdateRequest infos;
|
||||
infos.set_speach_total(this->data->speach_total);
|
||||
infos.set_speach_dead(this->data->speach_dead);
|
||||
|
@ -37,7 +37,7 @@ ConnectedClient::~ConnectedClient() {
|
||||
memtrack::freed<ConnectedClient>(this);
|
||||
}
|
||||
|
||||
std::shared_ptr<ConnectionInfoData> ConnectedClient::requestConnectionInfo(const std::shared_ptr<ConnectedClient>& receiver) {
|
||||
std::shared_ptr<ConnectionInfoData> ConnectedClient::request_connection_info(const std::shared_ptr<ConnectedClient> &receiver, bool& send_temp) {
|
||||
auto& info = this->connection_info;
|
||||
|
||||
lock_guard info_lock(info.lock);
|
||||
@ -49,11 +49,17 @@ std::shared_ptr<ConnectionInfoData> ConnectedClient::requestConnectionInfo(const
|
||||
info.data = nullptr;
|
||||
}
|
||||
|
||||
info.receiver.erase(std::remove_if(info.receiver.begin(), info.receiver.end(), [&](const weak_ptr<ConnectedClient>& weak) {
|
||||
auto locked = weak.lock();
|
||||
return !locked || locked == receiver;
|
||||
}), info.receiver.end());
|
||||
info.receiver.push_back(receiver);
|
||||
if(receiver) {
|
||||
info.receiver.erase(std::remove_if(info.receiver.begin(), info.receiver.end(), [&](const weak_ptr<ConnectedClient>& weak) {
|
||||
auto locked = weak.lock();
|
||||
if(locked == receiver) {
|
||||
send_temp = true;
|
||||
return true;
|
||||
}
|
||||
return !locked;
|
||||
}), info.receiver.end());
|
||||
info.receiver.push_back(receiver);
|
||||
}
|
||||
|
||||
if(chrono::system_clock::now() - info.last_requested >= chrono::seconds(1)) {
|
||||
info.last_requested = chrono::system_clock::now();
|
||||
@ -764,7 +770,7 @@ void ConnectedClient::sendServerInit() {
|
||||
command["lt"] = LicenseType::LICENSE_HOSTING;
|
||||
} else
|
||||
command["lt"] = ts::config::server::DefaultServerLicense;
|
||||
command["pv"] = 6; //Protocol version
|
||||
command["pv"] = 6; //Protocol version
|
||||
command["acn"] = this->getDisplayName();
|
||||
command["aclid"] = this->getClientId();
|
||||
if(dynamic_cast<VoiceClient*>(this)) {
|
||||
|
@ -157,7 +157,7 @@ namespace ts {
|
||||
virtual bool notifyGroupPermList(const std::shared_ptr<Group>&, bool);
|
||||
virtual bool notifyClientPermList(ClientDbId, const std::shared_ptr<permission::v2::PermissionManager>&, bool);
|
||||
virtual bool notifyChannelGroupList();
|
||||
virtual bool notifyConnectionInfo(std::shared_ptr<ConnectedClient>,std::shared_ptr<ConnectionInfoData>);
|
||||
virtual bool notifyConnectionInfo(const std::shared_ptr<ConnectedClient> &target, const std::shared_ptr<ConnectionInfoData> &info);
|
||||
virtual bool notifyChannelSubscribed(const std::deque<std::shared_ptr<BasicChannel>> &);
|
||||
virtual bool notifyChannelUnsubscribed(const std::deque<std::shared_ptr<BasicChannel>> &);
|
||||
|
||||
@ -269,7 +269,7 @@ namespace ts {
|
||||
bool shouldFloodBlock();
|
||||
|
||||
virtual bool ignoresFlood() { return !this->block_flood; }
|
||||
std::shared_ptr<ConnectionInfoData> requestConnectionInfo(const std::shared_ptr<ConnectedClient>& /* receiver */);
|
||||
std::shared_ptr<ConnectionInfoData> request_connection_info(const std::shared_ptr<ConnectedClient> & /* receiver */, bool& /* send temporary (no client response yet) */);
|
||||
|
||||
virtual void updateChannelClientProperties(bool /* lock channel tree */, bool /* notify our self */);
|
||||
void updateTalkRights(permission::PermissionValue talk_power);
|
||||
|
@ -651,9 +651,13 @@ CommandResult ConnectedClient::handleCommandGetConnectionInfo(Command &cmd) {
|
||||
auto client = this->server->findClient(cmd["clid"].as<ClientId>());
|
||||
if (!client) return {findError("client_invalid_id"), "invalid client id"};
|
||||
|
||||
auto info = client->requestConnectionInfo(_this.lock());
|
||||
if (info)
|
||||
bool send_temp;
|
||||
auto info = client->request_connection_info(_this.lock(), send_temp);
|
||||
if (info) {
|
||||
this->notifyConnectionInfo(client, info);
|
||||
} else if(send_temp) {
|
||||
this->notifyConnectionInfo(client, nullptr);
|
||||
}
|
||||
|
||||
return CommandResult::Success;
|
||||
}
|
||||
@ -872,6 +876,7 @@ CommandResult ConnectedClient::handleCommandPermissionList(Command &cmd) {
|
||||
if (!permission->clientSupported) continue;
|
||||
|
||||
auto &blk = list_builder[index++];
|
||||
|
||||
blk["permname"] = permission->name;
|
||||
blk["permdesc"] = permission->description;
|
||||
blk["permid"] = permission->type;
|
||||
@ -879,7 +884,7 @@ CommandResult ConnectedClient::handleCommandPermissionList(Command &cmd) {
|
||||
return list_builder;
|
||||
};
|
||||
|
||||
if(this->getType() == CLIENT_TEASPEAK || this->getType() == CLIENT_TEAMSPEAK || this->getType() == CLIENT_QUERY) {
|
||||
if((this->getType() == CLIENT_TEASPEAK || this->getType() == CLIENT_TEAMSPEAK || this->getType() == CLIENT_QUERY) && false) {
|
||||
Command response(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifypermissionlist" : "");
|
||||
{
|
||||
lock_guard lock(permission_list_string_lock);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <log/LogUtils.h>
|
||||
#include <misc/sassert.h>
|
||||
#include <misc/timer.h>
|
||||
#include "./web/WebClient.h"
|
||||
|
||||
using namespace std::chrono;
|
||||
using namespace std;
|
||||
@ -247,16 +248,65 @@ bool ConnectedClient::notifyClientChannelGroupChanged(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConnectedClient::notifyConnectionInfo(std::shared_ptr<ConnectedClient> target, std::shared_ptr<ConnectionInfoData> info) {
|
||||
bool ConnectedClient::notifyConnectionInfo(const shared_ptr<ConnectedClient> &target, const shared_ptr<ConnectionInfoData> &info) {
|
||||
Command notify("notifyconnectioninfo");
|
||||
notify["clid"] = target->getClientId();
|
||||
|
||||
if(target->getClientId() != this->getClientId()){
|
||||
for(const auto& elm : info->properties)
|
||||
notify[elm.first] = elm.second;
|
||||
notify["connection_connected_time"] = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now() - target->connectTimestamp).count();
|
||||
notify["connection_filetransfer_bandwidth_sent"] = 0;
|
||||
notify["connection_filetransfer_bandwidth_received"] = 0;
|
||||
if(target->getClientId() != this->getClientId()) {
|
||||
/* default values which normally sets the client */
|
||||
notify["connection_bandwidth_received_last_minute_control"] = -1;
|
||||
notify["connection_bandwidth_received_last_minute_keepalive"] = -1;
|
||||
notify["connection_bandwidth_received_last_minute_speech"] = -1;
|
||||
notify["connection_bandwidth_received_last_second_control"] = -1;
|
||||
notify["connection_bandwidth_received_last_second_keepalive"] = -1;
|
||||
notify["connection_bandwidth_received_last_second_speech"] = -1;
|
||||
|
||||
notify["connection_bandwidth_sent_last_minute_control"] = -1;
|
||||
notify["connection_bandwidth_sent_last_minute_keepalive"] = -1;
|
||||
notify["connection_bandwidth_sent_last_minute_speech"] = -1;
|
||||
notify["connection_bandwidth_sent_last_second_control"] = -1;
|
||||
notify["connection_bandwidth_sent_last_second_keepalive"] = -1;
|
||||
notify["connection_bandwidth_sent_last_second_speech"] = -1;
|
||||
|
||||
notify["connection_bytes_received_control"] = -1;
|
||||
notify["connection_bytes_received_keepalive"] = -1;
|
||||
notify["connection_bytes_received_speech"] = -1;
|
||||
notify["connection_bytes_sent_control"] = -1;
|
||||
notify["connection_bytes_sent_keepalive"] = -1;
|
||||
notify["connection_bytes_sent_speech"] = -1;
|
||||
|
||||
notify["connection_packets_received_control"] = -1;
|
||||
notify["connection_packets_received_keepalive"] = -1;
|
||||
notify["connection_packets_received_speech"] = -1;
|
||||
notify["connection_packets_sent_control"] = -1;
|
||||
notify["connection_packets_sent_keepalive"] = -1;
|
||||
notify["connection_packets_sent_speech"] = -1;
|
||||
|
||||
notify["connection_server2client_packetloss_control"] = -1;
|
||||
notify["connection_server2client_packetloss_keepalive"] = -1;
|
||||
notify["connection_server2client_packetloss_speech"] = -1;
|
||||
notify["connection_server2client_packetloss_total"] = -1;
|
||||
|
||||
notify["connection_ping"] = 0;
|
||||
notify["connection_ping_deviation"] = 0;
|
||||
|
||||
notify["connection_connected_time"] = 0;
|
||||
notify["connection_idle_time"] = 0;
|
||||
|
||||
notify["connection_filetransfer_bandwidth_sent"] = 0;
|
||||
notify["connection_filetransfer_bandwidth_received"] = 0;
|
||||
|
||||
if(info) {
|
||||
for(const auto& elm : info->properties) {
|
||||
notify[elm.first] = elm.second;
|
||||
}
|
||||
} else {
|
||||
//Fill in some server stuff
|
||||
if(dynamic_pointer_cast<VoiceClient>(target))
|
||||
notify["connection_ping"] = floor<milliseconds>(dynamic_pointer_cast<VoiceClient>(target)->calculatePing()).count();
|
||||
else if(dynamic_pointer_cast<WebClient>(target))
|
||||
notify["connection_ping"] = floor<milliseconds>(dynamic_pointer_cast<WebClient>(target)->client_ping()).count();
|
||||
}
|
||||
}
|
||||
|
||||
if(target->getClientId() == this->getClientId() || this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_remoteaddress_view, 1, target->currentChannel, true)) {
|
||||
@ -264,11 +314,13 @@ bool ConnectedClient::notifyConnectionInfo(std::shared_ptr<ConnectedClient> targ
|
||||
notify["connection_client_port"] = target->getPeerPort();
|
||||
}
|
||||
|
||||
notify["connection_client2server_packetloss_speech"] = 0.f;
|
||||
notify["connection_client2server_packetloss_keepalive"] = 0.f;
|
||||
notify["connection_client2server_packetloss_control"] = 0.f;
|
||||
notify["connection_client2server_packetloss_total"] = 0.f;
|
||||
//Needs to be filled out
|
||||
notify["connection_client2server_packetloss_speech"] = -1;
|
||||
notify["connection_client2server_packetloss_keepalive"] = -1;
|
||||
notify["connection_client2server_packetloss_control"] = -1;
|
||||
notify["connection_client2server_packetloss_total"] = -1;
|
||||
|
||||
notify["connection_connected_time"] = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now() - target->connectTimestamp).count();
|
||||
notify["connection_idle_time"] = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now() - target->idleTimestamp).count();
|
||||
this->sendCommand(notify);
|
||||
return true;
|
||||
|
@ -90,7 +90,8 @@ void VoiceClient::tick(const std::chrono::system_clock::time_point &time) {
|
||||
duration_cast<milliseconds>(time - this->lastPingRequest).count(),
|
||||
duration_cast<milliseconds>(time - this->lastPingResponse).count());
|
||||
|
||||
this->requestConnectionInfo(nullptr);
|
||||
bool force;
|
||||
this->request_connection_info(nullptr, force);
|
||||
this->lastPingResponse = system_clock::now();
|
||||
return;
|
||||
}
|
||||
|
@ -124,6 +124,7 @@ ts::CommandResult VoiceClient::handleCommandClientInitIv(Command& command) {
|
||||
initivexpand2["beta"] = base64::encode(this->crypto.beta);
|
||||
initivexpand2["omega"] = serverOmega;
|
||||
initivexpand2["proof"] = proof;
|
||||
initivexpand2["tvd"] = "";
|
||||
initivexpand2["root"] = base64::encode((char*) this->crypto.chain_data->public_key, 32);
|
||||
initivexpand2["ot"] = 1;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user