Teaspeak-Server/server/src/groups/GroupAssignmentManager.h

112 lines
4.7 KiB
C++

#pragma once
#include <mutex>
#include <deque>
#include <string>
#include <memory>
#include <utility>
#include <Definitions.h>
#include <Properties.h>
namespace sql {
class SqlManager;
}
namespace ts::server {
class ConnectedClient;
namespace vserver {
class VirtualServerBase;
}
namespace groups {
enum struct GroupAssignmentCalculateMode {
LOCAL, /* only calculate clients groups for the local server */
GLOBAL /* use the parent group manager as well, if existing */
};
class ServerGroup;
class ChannelGroup;
class GroupManager;
struct ChannelGroupAssignment {
ChannelGroupAssignment(ChannelId channel_id, GroupId group_id, bool t) : channel_id{channel_id}, group_id{group_id}, temporary_assignment{t} { }
ChannelGroupAssignment(const ChannelGroupAssignment& other) = default;
ChannelGroupAssignment(ChannelGroupAssignment&&) = default;
ChannelGroupAssignment&operator=(const ChannelGroupAssignment&) = default;
ChannelId channel_id;
GroupId group_id;
bool temporary_assignment;
};
struct ServerGroupAssignment {
explicit ServerGroupAssignment(GroupId group_id) : group_id{group_id} { }
ServerGroupAssignment(const ServerGroupAssignment& other) = default;
ServerGroupAssignment(ServerGroupAssignment&&) = default;
ServerGroupAssignment&operator=(const ServerGroupAssignment&) = default;
GroupId group_id;
};
enum struct GroupAssignmentResult {
SUCCESS,
ADD_ALREADY_MEMBER_OF_GROUP,
REMOVE_NOT_MEMBER_OF_GROUP,
SET_ALREADY_MEMBER_OF_GROUP
};
class GroupAssignmentManager {
constexpr static bool kCacheAllClients{true};
public:
explicit GroupAssignmentManager(GroupManager* /* manager */);
~GroupAssignmentManager();
/* general load/initialize methods */
bool initialize(std::string& /* error */);
bool load_data(std::string& /* error */);
void unload_data();
/* client specific cache methods */
void enable_cache_for_client(GroupAssignmentCalculateMode /* mode */, ClientDbId /* client database id */);
void disable_cache_for_client(GroupAssignmentCalculateMode /* mode */, ClientDbId /* client database id */);
/* info/query methods */
[[nodiscard]] std::vector<GroupId> server_groups_of_client(GroupAssignmentCalculateMode /* mode */, ClientDbId /* client database id */);
[[nodiscard]] std::vector<ChannelGroupAssignment> channel_groups_of_client(GroupAssignmentCalculateMode /* mode */, ClientDbId /* client database id */);
[[nodiscard]] std::deque<ClientDbId> server_group_clients(GroupId /* group id */);
//[[nodiscard]] std::deque<ClientDbId> channel_group_clients(GroupId /* group id */, ChannelId /* channel id */);
/* change methods */
GroupAssignmentResult add_server_group(ClientDbId /* client database id */, GroupId /* group id */);
GroupAssignmentResult remove_server_group(ClientDbId /* client database id */, GroupId /* group id */);
/* Use channel group id 0 to delete any assignment */
GroupAssignmentResult set_channel_group(ClientDbId /* client database id */, GroupId /* group id */, ChannelId /* channel id */, bool /* temporary assignment */);
std::deque<property::ClientProperties> update_client_group_properties(const std::shared_ptr<ConnectedClient> &client, ChannelId /* target channel */);
void cleanup_assignments();
void cleanup_channel_assignments(ChannelId /* channel */);
void cleanup_channel_temporary_assignment(ClientDbId /* client database id */, ChannelId /* channel */);
private:
struct ClientCache {
ClientDbId client_database_id{0};
size_t use_count{0};
std::deque<ChannelGroupAssignment> channel_group_assignments{};
std::deque<ServerGroupAssignment> server_group_assignments{};
};
GroupManager* manager_;
std::mutex client_cache_lock;
std::deque<std::unique_ptr<ClientCache>> client_cache{};
[[nodiscard]] sql::SqlManager* sql_manager();
[[nodiscard]] ServerId server_id();
};
}
}