First draft of the new snapshot system and database changes
This commit is contained in:
@@ -367,18 +367,22 @@ command_result ConnectedClient::handleCommandClientChatClosed(Command &cmd) {
|
||||
return command_result{error::ok};
|
||||
}
|
||||
|
||||
//start=0 duration=10
|
||||
//pattern=%asd%
|
||||
|
||||
struct ClientDbArgs {
|
||||
shared_ptr<VirtualServer> server;
|
||||
int index = 0;
|
||||
int offset = 0;
|
||||
int resultIndex = 0;
|
||||
bool showIp = false;
|
||||
bool largeInfo = false;
|
||||
Command *result = nullptr;
|
||||
};
|
||||
constexpr static auto kDBListQuery{R"(
|
||||
SELECT `clients`.*, `properties`.`value` as `client_description` FROM (
|
||||
SELECT
|
||||
`clients_server`.`client_database_id`,
|
||||
`clients_server`.`client_unique_id`,
|
||||
`clients_server`.`client_nickname`,
|
||||
`clients_server`.`client_ip`,
|
||||
`clients_server`.`client_created`,
|
||||
`clients_server`.`client_last_connected`,
|
||||
`clients_server`.`client_total_connections`,
|
||||
`clients`.`client_login_name` FROM `clients_server`
|
||||
INNER JOIN `clients` ON `clients`.`client_database_id` = `clients_server`.`client_database_id`
|
||||
WHERE `server_id` = :serverId LIMIT :offset, :limit
|
||||
) AS `clients`
|
||||
LEFT JOIN `properties` ON `properties`.serverId = :serverId AND `properties`.key = 'client_description' AND `properties`.`id` = `clients`.`client_database_id`
|
||||
)"};
|
||||
|
||||
command_result ConnectedClient::handleCommandClientDbList(Command &cmd) {
|
||||
CMD_REQ_SERVER;
|
||||
@@ -386,86 +390,79 @@ command_result ConnectedClient::handleCommandClientDbList(Command &cmd) {
|
||||
CMD_CHK_AND_INC_FLOOD_POINTS(25);
|
||||
ACTION_REQUIRES_GLOBAL_PERMISSION(permission::b_virtualserver_client_dblist, 1);
|
||||
|
||||
Command notify(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifyclientdblist" : "");
|
||||
size_t offset = cmd[0].has("start") ? cmd["start"].as<size_t>() : 0;
|
||||
size_t limit = cmd[0].has("duration") ? cmd["duration"].as<int>() : 0;
|
||||
if(limit > 2000 || limit < 1)
|
||||
limit = 2000;
|
||||
|
||||
if (!cmd[0].has("start"))
|
||||
cmd["start"] = 0;
|
||||
if (!cmd[0].has("duration"))
|
||||
cmd["duration"] = 20;
|
||||
if (cmd[0]["duration"].as<int>() > 2000) cmd["duration"] = 2000;
|
||||
if (cmd[0]["duration"].as<int>() < 1) cmd["duration"] = 1;
|
||||
ts::command_builder result{this->notify_response_command("notifyclientdblist")};
|
||||
result.reserve_bulks(limit);
|
||||
|
||||
auto maxIndex = cmd["start"].as<uint32_t>() + cmd["duration"].as<uint32_t>();
|
||||
ClientDbArgs args;
|
||||
args.server = this->server;
|
||||
args.offset = cmd["start"].as<uint32_t>();
|
||||
args.result = ¬ify;
|
||||
args.resultIndex = 0;
|
||||
args.index = 0;
|
||||
args.showIp = permission::v2::permission_granted(1, this->calculate_permission(permission::b_client_remoteaddress_view, 0));
|
||||
args.largeInfo = cmd.hasParm("details");
|
||||
size_t command_index{0}, set_index{0};
|
||||
|
||||
(LOG_SQL_CMD)(sql::command(this->server->getSql(), "SELECT * FROM `clients` WHERE `serverId` = :sid ORDER BY `cldbid` ASC" + (maxIndex > 0 ? " LIMIT " + to_string(maxIndex) : ""), variable{":sid", this->server->getServerId()}).query(
|
||||
[](ClientDbArgs *pArgs, int length, char **values, char **column) {
|
||||
pArgs->index++;
|
||||
if (pArgs->offset < pArgs->index) {
|
||||
ClientDbId id = 0;
|
||||
string uid, name, ip;
|
||||
string created = "0", lastConnected = "0", connections = "0";
|
||||
for (int index = 0; index < length; index++) {
|
||||
string key = column[index];
|
||||
if (key == "cldbid")
|
||||
id = stoll(values[index]);
|
||||
else if (key == "clientUid")
|
||||
uid = values[index];
|
||||
else if (key == "firstConnect")
|
||||
created = values[index];
|
||||
else if (key == "lastConnect")
|
||||
lastConnected = values[index];
|
||||
else if (key == "connections")
|
||||
connections = values[index];
|
||||
else if (key == "lastName")
|
||||
name = values[index];
|
||||
}
|
||||
auto show_ip = permission::v2::permission_granted(1, this->calculate_permission(permission::b_client_remoteaddress_view, 0));
|
||||
|
||||
pArgs->result->operator[](pArgs->resultIndex)["cldbid"] = id;
|
||||
pArgs->result->operator[](pArgs->resultIndex)["client_unique_identifier"] = uid;
|
||||
pArgs->result->operator[](pArgs->resultIndex)["client_nickname"] = name;
|
||||
pArgs->result->operator[](pArgs->resultIndex)["client_created"] = created;
|
||||
pArgs->result->operator[](pArgs->resultIndex)["client_lastconnected"] = lastConnected;
|
||||
pArgs->result->operator[](pArgs->resultIndex)["client_totalconnections"] = connections;
|
||||
pArgs->result->operator[](pArgs->resultIndex)["client_description"] = "";
|
||||
auto sqlResult = sql::command{this->server->getSql(), kDBListQuery, variable{":serverId", this->getServerId()}, variable{":offset", offset}, variable{":limit", limit}}
|
||||
.query([&](int length, std::string* values, std::string* names) {
|
||||
set_index++;
|
||||
auto bulk = result.bulk(command_index++);
|
||||
bulk.reserve(300);
|
||||
|
||||
auto props = serverInstance->databaseHelper()->loadClientProperties(pArgs->server, id, ClientType::CLIENT_TEAMSPEAK);
|
||||
if (props) {
|
||||
pArgs->result->operator[](pArgs->resultIndex)["client_lastip"] = (*props)[property::CONNECTION_CLIENT_IP].as<string>();
|
||||
pArgs->result->operator[](pArgs->resultIndex)["client_description"] = (*props)[property::CLIENT_DESCRIPTION].as<string>();
|
||||
auto index{0};
|
||||
try {
|
||||
assert(names[index] == "client_database_id");
|
||||
bulk.put_unchecked("cldbid", values[index++]);
|
||||
|
||||
if (pArgs->largeInfo) {
|
||||
pArgs->result->operator[](pArgs->resultIndex)["client_badges"] = (*props)[property::CLIENT_BADGES].as<string>();
|
||||
pArgs->result->operator[](pArgs->resultIndex)["client_version"] = (*props)[property::CLIENT_VERSION].as<string>();
|
||||
pArgs->result->operator[](pArgs->resultIndex)["client_platform"] = (*props)[property::CLIENT_PLATFORM].as<string>();
|
||||
pArgs->result->operator[](pArgs->resultIndex)["client_hwid"] = (*props)[property::CLIENT_HARDWARE_ID].as<string>();
|
||||
}
|
||||
}
|
||||
if (!pArgs->showIp)
|
||||
pArgs->result->operator[](pArgs->resultIndex)["client_lastip"] = "hidden";
|
||||
pArgs->resultIndex++;
|
||||
}
|
||||
return 0;
|
||||
}, &args));
|
||||
assert(names[index] == "client_unique_id");
|
||||
bulk.put_unchecked("client_unique_identifier", values[index++]);
|
||||
|
||||
assert(names[index] == "client_nickname");
|
||||
bulk.put_unchecked("client_nickname", values[index++]);
|
||||
|
||||
assert(names[index] == "client_ip");
|
||||
bulk.put_unchecked("client_lastip", show_ip ? values[index++] : "hidden");
|
||||
|
||||
assert(names[index] == "client_created");
|
||||
bulk.put_unchecked("client_lastconnected", values[index++]);
|
||||
|
||||
assert(names[index] == "client_last_connected");
|
||||
bulk.put_unchecked("client_created", values[index++]);
|
||||
|
||||
assert(names[index] == "client_total_connections");
|
||||
bulk.put_unchecked("client_totalconnections", values[index++]);
|
||||
|
||||
assert(names[index] == "client_login_name");
|
||||
bulk.put_unchecked("client_login_name", values[index++]);
|
||||
|
||||
assert(names[index] == "client_description");
|
||||
bulk.put_unchecked("client_description", values[index++]);
|
||||
|
||||
assert(index == length);
|
||||
} catch (std::exception& ex) {
|
||||
command_index--;
|
||||
logError(this->getServerId(), "Failed to parse client base properties at index {}: {}. Offset: {} Limit: {} Set: {}",
|
||||
index - 1,
|
||||
ex.what(),
|
||||
offset,
|
||||
limit,
|
||||
set_index - 1
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
if (command_index == 0)
|
||||
return command_result{error::database_empty_result};
|
||||
|
||||
if (args.resultIndex == 0) return command_result{error::database_empty_result};
|
||||
if (cmd.hasParm("count")) {
|
||||
size_t result = 0;
|
||||
sql::command(this->server->getSql(), "SELECT COUNT(*) AS `count` FROM `clients` WHERE `serverId` = :sid", variable{":sid", this->server->getServerId()}).query([](size_t *ptr, int, char **v, char **) {
|
||||
*ptr = static_cast<size_t>(stoll(v[0]));
|
||||
return 0;
|
||||
}, &result);
|
||||
notify[0]["count"] = result;
|
||||
size_t count{0};
|
||||
sql::command(this->server->getSql(), "SELECT COUNT(`client_database_id`) AS `count` FROM `clients_server` WHERE `server_id` = :sid", variable{":sid", this->server->getServerId()})
|
||||
.query([&](int, std::string* v, std::string*) {
|
||||
count = stoll(v[0]);
|
||||
});
|
||||
result.put_unchecked(0, "count", count);
|
||||
}
|
||||
this->sendCommand(notify);
|
||||
|
||||
this->sendCommand(result);
|
||||
return command_result{error::ok};
|
||||
}
|
||||
|
||||
@@ -869,8 +866,9 @@ command_result ConnectedClient::handleCommandClientGetDBIDfromUID(Command &cmd)
|
||||
CMD_RESET_IDLE;
|
||||
|
||||
deque<string> unique_ids;
|
||||
for(int index = 0; index < cmd.bulkCount(); index++)
|
||||
unique_ids.push_back(cmd[index]["cluid"].as<string>());
|
||||
for(int index = 0; index < cmd.bulkCount(); index++) {
|
||||
unique_ids.push_back(cmd[index]["cluid"]);
|
||||
}
|
||||
|
||||
auto res = serverInstance->databaseHelper()->queryDatabaseInfoByUid(this->server, unique_ids);
|
||||
if (res.empty()) return command_result{error::database_empty_result};
|
||||
@@ -878,8 +876,8 @@ command_result ConnectedClient::handleCommandClientGetDBIDfromUID(Command &cmd)
|
||||
Command result(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifyclientdbidfromuid" : "");
|
||||
int result_index = 0;
|
||||
for(auto& info : res) {
|
||||
result[result_index]["cluid"] = info->uniqueId;
|
||||
result[result_index]["cldbid"] = info->cldbid;
|
||||
result[result_index]["cluid"] = info->client_unique_id;
|
||||
result[result_index]["cldbid"] = info->client_database_id;
|
||||
result_index++;
|
||||
}
|
||||
this->sendCommand(result);
|
||||
@@ -900,10 +898,10 @@ command_result ConnectedClient::handleCommandClientGetNameFromDBID(Command &cmd)
|
||||
Command result(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifyclientgetnamefromdbid" : "");
|
||||
int result_index = 0;
|
||||
for(auto& info : res) {
|
||||
result[result_index]["cluid"] = info->uniqueId;
|
||||
result[result_index]["cldbid"] = info->cldbid;
|
||||
result[result_index]["name"] = info->lastName;
|
||||
result[result_index]["clname"] = info->lastName;
|
||||
result[result_index]["cluid"] = info->client_unique_id;
|
||||
result[result_index]["cldbid"] = info->client_database_id;
|
||||
result[result_index]["name"] = info->client_nickname;
|
||||
result[result_index]["clname"] = info->client_nickname;
|
||||
result_index++;
|
||||
}
|
||||
this->sendCommand(result);
|
||||
@@ -924,10 +922,10 @@ command_result ConnectedClient::handleCommandClientGetNameFromUid(Command &cmd)
|
||||
Command result(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifyclientnamefromuid" : "");
|
||||
int result_index = 0;
|
||||
for(auto& info : res) {
|
||||
result[result_index]["cluid"] = info->uniqueId;
|
||||
result[result_index]["cldbid"] = info->cldbid;
|
||||
result[result_index]["name"] = info->lastName;
|
||||
result[result_index]["clname"] = info->lastName;
|
||||
result[result_index]["cluid"] = info->client_unique_id;
|
||||
result[result_index]["cldbid"] = info->client_database_id;
|
||||
result[result_index]["name"] = info->client_nickname;
|
||||
result[result_index]["clname"] = info->client_nickname;
|
||||
result_index++;
|
||||
}
|
||||
this->sendCommand(result);
|
||||
@@ -1086,16 +1084,16 @@ command_result ConnectedClient::handleCommandClientDbInfo(Command &cmd) {
|
||||
|
||||
size_t index = 0;
|
||||
for(const auto& info : basic) {
|
||||
res[index]["client_base64HashClientUID"] = hex::hex(base64::validate(info->uniqueId) ? base64::decode(info->uniqueId) : info->uniqueId, 'a', 'q');
|
||||
res[index]["client_unique_identifier"] = info->uniqueId;
|
||||
res[index]["client_nickname"] = info->lastName;
|
||||
res[index]["client_database_id"] = info->cldbid;
|
||||
res[index]["client_created"] = chrono::duration_cast<chrono::seconds>(info->created.time_since_epoch()).count();
|
||||
res[index]["client_lastconnected"] = chrono::duration_cast<chrono::seconds>(info->lastjoin.time_since_epoch()).count();
|
||||
res[index]["client_totalconnections"] = info->connections;
|
||||
res[index]["client_database_id"] = info->cldbid;
|
||||
res[index]["client_base64HashClientUID"] = hex::hex(base64::validate(info->client_unique_id) ? base64::decode(info->client_unique_id) : info->client_unique_id, 'a', 'q');
|
||||
res[index]["client_unique_identifier"] = info->client_unique_id;
|
||||
res[index]["client_nickname"] = info->client_nickname;
|
||||
res[index]["client_database_id"] = info->client_database_id;
|
||||
res[index]["client_created"] = chrono::duration_cast<chrono::seconds>(info->client_created.time_since_epoch()).count();
|
||||
res[index]["client_lastconnected"] = chrono::duration_cast<chrono::seconds>(info->client_last_connected.time_since_epoch()).count();
|
||||
res[index]["client_totalconnections"] = info->client_total_connections;
|
||||
res[index]["client_database_id"] = info->client_database_id;
|
||||
|
||||
auto props = serverInstance->databaseHelper()->loadClientProperties(this->server, info->cldbid, ClientType::CLIENT_TEAMSPEAK);
|
||||
auto props = serverInstance->databaseHelper()->loadClientProperties(this->server, info->client_database_id, ClientType::CLIENT_TEAMSPEAK);
|
||||
if (allow_ip)
|
||||
res[index]["client_lastip"] = (*props)[property::CONNECTION_CLIENT_IP].as<string>();
|
||||
else
|
||||
@@ -1136,13 +1134,6 @@ command_result ConnectedClient::handleCommandClientDBDelete(Command &cmd) {
|
||||
return command_result{error::ok};
|
||||
}
|
||||
|
||||
struct DBFindArgs {
|
||||
int index = 0;
|
||||
bool full = false;
|
||||
bool ip = false;
|
||||
Command cmd{""};
|
||||
};
|
||||
|
||||
command_result ConnectedClient::handleCommandClientDBFind(Command &cmd) {
|
||||
CMD_REQ_SERVER;
|
||||
CMD_RESET_IDLE;
|
||||
@@ -1152,48 +1143,73 @@ command_result ConnectedClient::handleCommandClientDBFind(Command &cmd) {
|
||||
bool uid = cmd.hasParm("uid");
|
||||
string pattern = cmd["pattern"];
|
||||
|
||||
DBFindArgs args{};
|
||||
args.cmd = Command(this->getType() == CLIENT_QUERY ? "" : "notifyclientdbfind");
|
||||
args.full = cmd.hasParm("details");
|
||||
args.ip = permission::v2::permission_granted(1, this->calculate_permission(permission::b_client_remoteaddress_view, 0));
|
||||
auto res = sql::command(this->sql, "SELECT * FROM `clients` WHERE `serverId` = :sid AND `" + std::string{uid ? "clientUid" : "lastName"} + "` LIKE :pattern LIMIT 50",
|
||||
variable{":sid", this->server->getServerId()},
|
||||
variable{":pattern", pattern}).query(
|
||||
[&](DBFindArgs *ptr, int len, char **values, char **names) {
|
||||
for (int index = 0; index < len; index++)
|
||||
if (strcmp(names[index], "cldbid") == 0)
|
||||
ptr->cmd[ptr->index]["cldbid"] = values[index];
|
||||
else if (strcmp(names[index], "clientUid") == 0 && ptr->full)
|
||||
ptr->cmd[ptr->index]["client_unique_identifier"] = values[index];
|
||||
else if (strcmp(names[index], "lastConnect") == 0 && ptr->full)
|
||||
ptr->cmd[ptr->index]["client_lastconnected"] = values[index];
|
||||
else if (strcmp(names[index], "connections") == 0 && ptr->full)
|
||||
ptr->cmd[ptr->index]["client_totalconnections"] = values[index];
|
||||
else if (strcmp(names[index], "lastName") == 0 && ptr->full)
|
||||
ptr->cmd[ptr->index]["client_nickname"] = values[index];
|
||||
if (ptr->full) {
|
||||
auto props = serverInstance->databaseHelper()->loadClientProperties(this->server, ptr->cmd[ptr->index]["cldbid"], ClientType::CLIENT_TEAMSPEAK);
|
||||
if (props) {
|
||||
if (ptr->ip) {
|
||||
ptr->cmd[ptr->index]["client_lastip"] = (*props)[property::CONNECTION_CLIENT_IP].as<string>();
|
||||
} else {
|
||||
ptr->cmd[ptr->index]["client_lastip"] = "hidden";
|
||||
}
|
||||
ptr->cmd[ptr->index]["client_badges"] = (*props)[property::CLIENT_BADGES].as<string>();
|
||||
ptr->cmd[ptr->index]["client_version"] = (*props)[property::CLIENT_VERSION].as<string>();
|
||||
ptr->cmd[ptr->index]["client_platform"] = (*props)[property::CLIENT_PLATFORM].as<string>();
|
||||
ptr->cmd[ptr->index]["client_hwid"] = (*props)[property::CLIENT_HARDWARE_ID].as<string>();
|
||||
}
|
||||
const auto detailed = cmd.hasParm("details");
|
||||
const auto show_ip = permission::v2::permission_granted(1, this->calculate_permission(permission::b_client_remoteaddress_view, 0));
|
||||
|
||||
size_t command_index{0};
|
||||
ts::command_builder result{this->notify_response_command("notifyclientdbfind")};
|
||||
result.reserve_bulks(50);
|
||||
|
||||
constexpr static auto kBaseCommand{"SELECT `client_database_id`, `client_unique_id`, `client_nickname`, `client_ip`, `client_last_connected`, `client_total_connections` FROM `clients_server` WHERE "};
|
||||
|
||||
auto sql_result = sql::command{this->sql, std::string{kBaseCommand} + "`server_id` = :sid AND " + (uid ? "`client_unique_id`" : "`client_nickname`") + " LIKE :pattern LIMIT 50", variable{":sid", this->getServerId()}, variable{":pattern", pattern}}
|
||||
.query([&](int length, std::string* values, std::string* names) {
|
||||
auto bulk = result.bulk(command_index++);
|
||||
bulk.reserve(300);
|
||||
|
||||
auto index{0};
|
||||
ClientDbId client_database_id;
|
||||
try {
|
||||
assert(names[index] == "client_database_id");
|
||||
client_database_id = std::stoull(values[index]);
|
||||
bulk.put_unchecked("cldbid", values[index++]);
|
||||
|
||||
assert(names[index] == "client_unique_id");
|
||||
bulk.put_unchecked("client_unique_identifier", values[index++]);
|
||||
|
||||
assert(names[index] == "client_nickname");
|
||||
bulk.put_unchecked("client_nickname", values[index++]);
|
||||
|
||||
assert(names[index] == "client_ip");
|
||||
if(detailed) {
|
||||
bulk.put_unchecked("client_lastip", show_ip ? values[index++] : "hidden");
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
ptr->index++;
|
||||
return 0;
|
||||
}, &args);
|
||||
auto pf = LOG_SQL_CMD;
|
||||
pf(res);
|
||||
if (args.index == 0) return command_result{error::database_empty_result};
|
||||
|
||||
this->sendCommand(args.cmd);
|
||||
assert(names[index] == "client_last_connected");
|
||||
bulk.put_unchecked("client_lastconnected", values[index++]);
|
||||
|
||||
assert(names[index] == "client_total_connections");
|
||||
bulk.put_unchecked("client_totalconnections", values[index++]);
|
||||
|
||||
assert(index == length);
|
||||
} catch (std::exception& ex) {
|
||||
command_index--;
|
||||
logError(this->getServerId(), "Failed to parse client base properties at index {}: {}. Search pattern: {}",
|
||||
index - 1,
|
||||
ex.what(),
|
||||
pattern
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if(detailed) {
|
||||
auto props = serverInstance->databaseHelper()->loadClientProperties(this->server, client_database_id, ClientType::CLIENT_TEAMSPEAK);
|
||||
if (props) {
|
||||
auto& properties = *props;
|
||||
bulk.put_unchecked("client_badges", properties[property::CLIENT_BADGES].as<std::string>());
|
||||
bulk.put_unchecked("client_version", properties[property::CLIENT_VERSION].as<std::string>());
|
||||
bulk.put_unchecked("client_platform", properties[property::CLIENT_PLATFORM].as<std::string>());
|
||||
bulk.put_unchecked("client_hwid", properties[property::CLIENT_HARDWARE_ID].as<std::string>());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(command_index == 0)
|
||||
return command_result{error::database_empty_result};
|
||||
|
||||
this->sendCommand(result);
|
||||
return command_result{error::ok};
|
||||
}
|
||||
|
||||
|
||||
@@ -714,7 +714,7 @@ command_result ConnectedClient::handleCommandBanAdd(Command &cmd) {
|
||||
return command_result{permission::b_client_ban_create};
|
||||
}
|
||||
|
||||
auto max_ban_time = server->calculate_permission(permission::i_client_ban_max_bantime, this->getClientDatabaseId(), this->getType(), 0);
|
||||
auto max_ban_time = this->calculate_permission(permission::i_client_ban_max_bantime, this->getClientDatabaseId(), this->getType(), 0);
|
||||
if(!max_ban_time.has_value) return command_result{permission::i_client_ban_max_bantime};
|
||||
if (!max_ban_time.has_infinite_power()) {
|
||||
if (max_ban_time.value < time)
|
||||
@@ -1884,10 +1884,10 @@ command_result ConnectedClient::handleCommandComplainList(Command &cmd) {
|
||||
result[index]["timestamp"] = chrono::duration_cast<chrono::seconds>(elm->created.time_since_epoch()).count();
|
||||
|
||||
for (const auto &e : dbInfo) {
|
||||
if (e->cldbid == elm->target)
|
||||
result[index]["tname"] = e->lastName;
|
||||
if (e->cldbid == elm->invoker)
|
||||
result[index]["fname"] = e->lastName;
|
||||
if (e->client_database_id == elm->target)
|
||||
result[index]["tname"] = e->client_nickname;
|
||||
if (e->client_database_id == elm->invoker)
|
||||
result[index]["fname"] = e->client_nickname;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
@@ -2351,7 +2351,7 @@ command_result ConnectedClient::handleCommandQueryCreate(ts::Command &cmd) {
|
||||
auto info = serverInstance->databaseHelper()->queryDatabaseInfo(server, {cmd["cldbid"].as<ClientDbId>()});
|
||||
if(info.empty())
|
||||
return command_result{error::database_empty_result};
|
||||
uid = info[0]->uniqueId;
|
||||
uid = info[0]->client_unique_id;
|
||||
} else {
|
||||
if(server) {
|
||||
if(!permission::v2::permission_granted(1, server->calculate_permission(permission::b_client_query_create_own, this->getClientDatabaseId(), this->getType(), 0)))
|
||||
|
||||
Reference in New Issue
Block a user