Cleaned and fixed permission service #393
This commit is contained in:
parent
eb3eb24e81
commit
76d94c0f60
@ -8,7 +8,6 @@ from bot_data.model.server import Server
|
|||||||
from bot_data.model.technician_config import TechnicianConfig
|
from bot_data.model.technician_config import TechnicianConfig
|
||||||
from bot_data.service.server_config_seeder import ServerConfigSeeder
|
from bot_data.service.server_config_seeder import ServerConfigSeeder
|
||||||
from bot_data.service.technician_config_seeder import TechnicianConfigSeeder
|
from bot_data.service.technician_config_seeder import TechnicianConfigSeeder
|
||||||
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigService:
|
class ConfigService:
|
||||||
@ -45,6 +44,3 @@ class ConfigService:
|
|||||||
self._config.add_configuration(
|
self._config.add_configuration(
|
||||||
f"{type(server_config).__name__}_{server_config.server.discord_id}", server_config
|
f"{type(server_config).__name__}_{server_config.server.discord_id}", server_config
|
||||||
)
|
)
|
||||||
|
|
||||||
permissions: PermissionServiceABC = self._services.get_service(PermissionServiceABC)
|
|
||||||
permissions.on_ready()
|
|
||||||
|
@ -183,4 +183,3 @@ class ServerConfigMutation(QueryABC):
|
|||||||
self._server_configs.add_server_team_role_id_config(role_id)
|
self._server_configs.add_server_team_role_id_config(role_id)
|
||||||
|
|
||||||
self._bot.loop.create_task(self._config_service.reload_server_config(new_config.server))
|
self._bot.loop.create_task(self._config_service.reload_server_config(new_config.server))
|
||||||
self._permissions.on_ready()
|
|
||||||
|
@ -12,7 +12,6 @@ from bot_data.model.technician_id_config import TechnicianIdConfig
|
|||||||
from bot_data.model.technician_ping_url_config import TechnicianPingUrlConfig
|
from bot_data.model.technician_ping_url_config import TechnicianPingUrlConfig
|
||||||
from bot_data.model.user_role_enum import UserRoleEnum
|
from bot_data.model.user_role_enum import UserRoleEnum
|
||||||
from bot_graphql.abc.query_abc import QueryABC
|
from bot_graphql.abc.query_abc import QueryABC
|
||||||
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
|
||||||
|
|
||||||
|
|
||||||
class TechnicianConfigMutation(QueryABC):
|
class TechnicianConfigMutation(QueryABC):
|
||||||
@ -23,7 +22,6 @@ class TechnicianConfigMutation(QueryABC):
|
|||||||
servers: ServerRepositoryABC,
|
servers: ServerRepositoryABC,
|
||||||
technician_configs: TechnicianConfigRepositoryABC,
|
technician_configs: TechnicianConfigRepositoryABC,
|
||||||
db: DatabaseContextABC,
|
db: DatabaseContextABC,
|
||||||
permissions: PermissionServiceABC,
|
|
||||||
config_service: ConfigService,
|
config_service: ConfigService,
|
||||||
):
|
):
|
||||||
QueryABC.__init__(self, "TechnicianConfigMutation")
|
QueryABC.__init__(self, "TechnicianConfigMutation")
|
||||||
@ -33,7 +31,6 @@ class TechnicianConfigMutation(QueryABC):
|
|||||||
self._servers = servers
|
self._servers = servers
|
||||||
self._technician_configs = technician_configs
|
self._technician_configs = technician_configs
|
||||||
self._db = db
|
self._db = db
|
||||||
self._permissions = permissions
|
|
||||||
self._config_service = config_service
|
self._config_service = config_service
|
||||||
|
|
||||||
self.set_field("updateTechnicianConfig", self.resolve_update_technician_config)
|
self.set_field("updateTechnicianConfig", self.resolve_update_technician_config)
|
||||||
@ -114,4 +111,3 @@ class TechnicianConfigMutation(QueryABC):
|
|||||||
self._technician_configs.add_technician_id_config(TechnicianIdConfig(technician_id))
|
self._technician_configs.add_technician_id_config(TechnicianIdConfig(technician_id))
|
||||||
|
|
||||||
self._bot.loop.create_task(self._config_service.reload_technician_config())
|
self._bot.loop.create_task(self._config_service.reload_technician_config())
|
||||||
self._permissions.on_ready()
|
|
||||||
|
@ -8,42 +8,14 @@ class PermissionServiceABC(ABC):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def on_ready(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def on_member_update(self, before: discord.Member, after: discord.Member):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_admin_role_ids(self, g_id: int) -> list[int]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_admin_roles(self, g_id: int) -> list[discord.Role]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_admins(self, g_id: int) -> list[discord.Member]:
|
def get_admins(self, g_id: int) -> list[discord.Member]:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_moderator_role_ids(self, g_id: int) -> list[int]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_moderator_roles(self, g_id: int) -> list[discord.Role]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_moderators(self, g_id: int) -> list[discord.Member]:
|
def get_moderators(self, g_id: int) -> list[discord.Member]:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_technicians(self) -> list[discord.Member]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def is_member_admin(self, member: discord.Member) -> bool:
|
def is_member_admin(self, member: discord.Member) -> bool:
|
||||||
pass
|
pass
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
bot sh-edraft.de Discord bot
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Discord bot for customers of sh-edraft.de
|
|
||||||
|
|
||||||
:copyright: (c) 2022 - 2023 sh-edraft.de
|
|
||||||
:license: MIT, see LICENSE for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
__title__ = "modules.permission.events"
|
|
||||||
__author__ = "Sven Heidemann"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
|
|
||||||
__version__ = "1.1.9"
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# imports:
|
|
||||||
|
|
||||||
VersionInfo = namedtuple("VersionInfo", "major minor micro")
|
|
||||||
version_info = VersionInfo(major="1", minor="1", micro="9")
|
|
@ -1,30 +0,0 @@
|
|||||||
import discord
|
|
||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.logging import LoggerABC
|
|
||||||
from cpl_discord.events import OnMemberUpdateABC
|
|
||||||
|
|
||||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
|
||||||
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
|
||||||
from bot_data.model.server_config import ServerConfig
|
|
||||||
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
|
||||||
|
|
||||||
|
|
||||||
class PermissionOnMemberUpdateEvent(OnMemberUpdateABC):
|
|
||||||
def __init__(self, config: ConfigurationABC, logger: LoggerABC, permission_service: PermissionServiceABC):
|
|
||||||
OnMemberUpdateABC.__init__(self)
|
|
||||||
self._config = config
|
|
||||||
self._logger = logger
|
|
||||||
self._permission_service = permission_service
|
|
||||||
|
|
||||||
async def on_member_update(self, before: discord.Member, after: discord.Member):
|
|
||||||
if before.guild is not None:
|
|
||||||
server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{before.guild.id}")
|
|
||||||
if not FeatureFlagsSettings.get_flag_from_dict(
|
|
||||||
server_config.feature_flags, FeatureFlagsEnum.permission_module
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Module {type(self)} started")
|
|
||||||
|
|
||||||
if before.roles != after.roles:
|
|
||||||
self._permission_service.on_member_update(before, after)
|
|
@ -1,22 +0,0 @@
|
|||||||
from cpl_core.logging import LoggerABC
|
|
||||||
from cpl_discord.events import OnReadyABC
|
|
||||||
|
|
||||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
|
||||||
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
|
||||||
from bot_data.model.technician_config import TechnicianConfig
|
|
||||||
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
|
||||||
|
|
||||||
|
|
||||||
class PermissionOnReadyEvent(OnReadyABC):
|
|
||||||
def __init__(self, logger: LoggerABC, permission_service: PermissionServiceABC, tech_config: TechnicianConfig):
|
|
||||||
OnReadyABC.__init__(self)
|
|
||||||
self._logger = logger
|
|
||||||
self._permission_service = permission_service
|
|
||||||
self._tech_config = tech_config
|
|
||||||
|
|
||||||
async def on_ready(self):
|
|
||||||
if not FeatureFlagsSettings.get_flag_from_dict(
|
|
||||||
self._tech_config.feature_flags, FeatureFlagsEnum.permission_module
|
|
||||||
):
|
|
||||||
return
|
|
||||||
self._permission_service.on_ready()
|
|
@ -1,16 +1,11 @@
|
|||||||
from cpl_core.configuration import ConfigurationABC
|
from cpl_core.configuration import ConfigurationABC
|
||||||
from cpl_core.dependency_injection import ServiceCollectionABC
|
from cpl_core.dependency_injection import ServiceCollectionABC
|
||||||
from cpl_core.environment import ApplicationEnvironmentABC
|
from cpl_core.environment import ApplicationEnvironmentABC
|
||||||
from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum
|
|
||||||
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
||||||
|
|
||||||
from bot_core.abc.module_abc import ModuleABC
|
from bot_core.abc.module_abc import ModuleABC
|
||||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||||
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
||||||
from modules.permission.events.permission_on_member_update_event import (
|
|
||||||
PermissionOnMemberUpdateEvent,
|
|
||||||
)
|
|
||||||
from modules.permission.events.permission_on_ready_event import PermissionOnReadyEvent
|
|
||||||
from modules.permission.service.permission_service import PermissionService
|
from modules.permission.service.permission_service import PermissionService
|
||||||
|
|
||||||
|
|
||||||
@ -25,5 +20,3 @@ class PermissionModule(ModuleABC):
|
|||||||
services.add_singleton(PermissionServiceABC, PermissionService)
|
services.add_singleton(PermissionServiceABC, PermissionService)
|
||||||
# commands
|
# commands
|
||||||
# events
|
# events
|
||||||
self._dc.add_event(DiscordEventTypesEnum.on_ready.value, PermissionOnReadyEvent)
|
|
||||||
self._dc.add_event(DiscordEventTypesEnum.on_member_update.value, PermissionOnMemberUpdateEvent)
|
|
||||||
|
@ -3,146 +3,55 @@ from cpl_core.configuration import ConfigurationABC
|
|||||||
from cpl_core.logging import LoggerABC
|
from cpl_core.logging import LoggerABC
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
from cpl_discord.service import DiscordBotServiceABC
|
||||||
|
|
||||||
from bot_data.model.server_config import ServerConfig
|
from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC
|
||||||
|
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||||
|
from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC
|
||||||
|
from bot_data.model.server_team_role_ids_config import ServerTeamRoleIdsConfig
|
||||||
from bot_data.model.team_member_type_enum import TeamMemberTypeEnum
|
from bot_data.model.team_member_type_enum import TeamMemberTypeEnum
|
||||||
from bot_data.model.technician_config import TechnicianConfig
|
|
||||||
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
from modules.permission.abc.permission_service_abc import PermissionServiceABC
|
||||||
|
|
||||||
|
|
||||||
class PermissionService(PermissionServiceABC):
|
class PermissionService(PermissionServiceABC):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
technician_settings: TechnicianConfig,
|
|
||||||
logger: LoggerABC,
|
logger: LoggerABC,
|
||||||
bot: DiscordBotServiceABC,
|
bot: DiscordBotServiceABC,
|
||||||
config: ConfigurationABC,
|
config: ConfigurationABC,
|
||||||
|
servers: ServerRepositoryABC,
|
||||||
|
server_configs: ServerConfigRepositoryABC,
|
||||||
|
technician_configs: TechnicianConfigRepositoryABC,
|
||||||
):
|
):
|
||||||
PermissionServiceABC.__init__(self)
|
PermissionServiceABC.__init__(self)
|
||||||
self._logger = logger
|
self._logger = logger
|
||||||
self._bot = bot
|
self._bot = bot
|
||||||
self._config = config
|
self._config = config
|
||||||
self._technician_settings = technician_settings
|
self._servers = servers
|
||||||
|
self._server_configs = server_configs
|
||||||
|
self._technician_configs = technician_configs
|
||||||
|
|
||||||
self._admin_role_ids: dict[int, list[int]] = {}
|
def _team_role_members(self, guild_id: int, team_role_type: TeamMemberTypeEnum):
|
||||||
self._admin_roles: dict[int, list[discord.Role]] = {}
|
guild = self._bot.get_guild(guild_id)
|
||||||
self._admins: dict[int, list[discord.Member]] = {}
|
server = self._servers.get_server_by_discord_id(guild_id)
|
||||||
|
config = self._server_configs.get_server_config_by_server(server.id)
|
||||||
self._moderator_role_ids: dict[int, list[int]] = {}
|
|
||||||
self._moderator_roles: dict[int, list[discord.Role]] = {}
|
|
||||||
self._moderators: dict[int, list[discord.Member]] = {}
|
|
||||||
|
|
||||||
self._technician_ids: list[int] = technician_settings.technician_ids.to_list()
|
|
||||||
self._technicians: list[discord.Member] = []
|
|
||||||
|
|
||||||
def on_ready(self):
|
|
||||||
for guild in self._bot.guilds:
|
|
||||||
guild: discord.Guild = guild
|
|
||||||
self._logger.debug(__name__, f"Validate permission settings")
|
|
||||||
|
|
||||||
for technician_id in self._technician_ids:
|
|
||||||
technician = guild.get_member(technician_id)
|
|
||||||
if technician is None:
|
|
||||||
continue
|
|
||||||
self._technicians.append(technician)
|
|
||||||
|
|
||||||
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}")
|
|
||||||
if settings is None:
|
|
||||||
self._logger.error(__name__, "Server settings not found")
|
|
||||||
return
|
|
||||||
|
|
||||||
self._admin_role_ids[guild.id] = (
|
|
||||||
settings.team_role_ids.where(lambda x: x.team_member_type == TeamMemberTypeEnum.admin)
|
|
||||||
.select(lambda x: x.role_id)
|
|
||||||
.to_list()
|
|
||||||
)
|
|
||||||
self._moderator_role_ids[guild.id] = (
|
|
||||||
settings.team_role_ids.where(lambda x: x.team_member_type == TeamMemberTypeEnum.moderator)
|
|
||||||
.select(lambda x: x.role_id)
|
|
||||||
.to_list()
|
|
||||||
)
|
|
||||||
|
|
||||||
admin_roles = []
|
|
||||||
admins = []
|
admins = []
|
||||||
|
for role_id in config.team_role_ids.where(lambda x: x.team_member_type == team_role_type):
|
||||||
|
role_id: ServerTeamRoleIdsConfig = role_id
|
||||||
|
admins = guild.get_role(role_id.role_id).members
|
||||||
|
|
||||||
mod_roles = []
|
return admins
|
||||||
mods = []
|
|
||||||
|
|
||||||
for role in guild.roles:
|
|
||||||
role: discord.Role = role
|
|
||||||
|
|
||||||
if role.id in self._admin_role_ids[guild.id]:
|
|
||||||
admin_roles.append(role)
|
|
||||||
self._logger.trace(__name__, f"Added admin role {role}")
|
|
||||||
|
|
||||||
for member in role.members:
|
|
||||||
admins.append(member)
|
|
||||||
self._logger.trace(__name__, f"Added admin {member}")
|
|
||||||
|
|
||||||
if role.id in self._moderator_role_ids[guild.id]:
|
|
||||||
mod_roles.append(role)
|
|
||||||
self._logger.trace(__name__, f"Added moderator role {role}")
|
|
||||||
|
|
||||||
for member in role.members:
|
|
||||||
mods.append(member)
|
|
||||||
self._logger.trace(__name__, f"Added moderator {member}")
|
|
||||||
|
|
||||||
self._admin_roles[guild.id] = admin_roles
|
|
||||||
self._admins[guild.id] = admins
|
|
||||||
self._moderator_roles[guild.id] = mod_roles
|
|
||||||
self._moderators[guild.id] = mods
|
|
||||||
|
|
||||||
def on_member_update(self, before: discord.Member, after: discord.Member):
|
|
||||||
g_id = after.guild.id
|
|
||||||
|
|
||||||
for admin_role in self._admin_roles[g_id]:
|
|
||||||
if admin_role in before.roles and admin_role not in after.roles:
|
|
||||||
self._admins[g_id].remove(after)
|
|
||||||
self._logger.trace(__name__, f"Removed {after.id} from admins")
|
|
||||||
|
|
||||||
elif admin_role in after.roles and admin_role not in before.roles:
|
|
||||||
self._admins[g_id].append(after)
|
|
||||||
self._logger.trace(__name__, f"Added {after.id} to admins")
|
|
||||||
|
|
||||||
for moderator_role in self._moderator_roles[g_id]:
|
|
||||||
if moderator_role in before.roles and moderator_role not in after.roles:
|
|
||||||
self._moderators[g_id].remove(after)
|
|
||||||
self._logger.trace(__name__, f"Removed {after.id} from moderators")
|
|
||||||
|
|
||||||
elif moderator_role in after.roles and moderator_role not in before.roles:
|
|
||||||
self._moderators[g_id].append(after)
|
|
||||||
self._logger.trace(__name__, f"Added {after.id} to moderators")
|
|
||||||
|
|
||||||
def get_admin_role_ids(self, g_id: int) -> list[int]:
|
|
||||||
return self._admin_role_ids[g_id]
|
|
||||||
|
|
||||||
def get_admin_roles(self, g_id: int) -> list[discord.Role]:
|
|
||||||
return self._admin_roles[g_id]
|
|
||||||
|
|
||||||
def get_admins(self, g_id: int) -> list[discord.Member]:
|
def get_admins(self, g_id: int) -> list[discord.Member]:
|
||||||
return self._admins[g_id]
|
return self._team_role_members(g_id, TeamMemberTypeEnum.admin)
|
||||||
|
|
||||||
def get_moderator_role_ids(self, g_id: int) -> list[int]:
|
|
||||||
return self._moderator_role_ids[g_id]
|
|
||||||
|
|
||||||
def get_moderator_roles(self, g_id: int) -> list[discord.Role]:
|
|
||||||
return self._moderator_roles[g_id]
|
|
||||||
|
|
||||||
def get_moderators(self, g_id: int) -> list[discord.Member]:
|
def get_moderators(self, g_id: int) -> list[discord.Member]:
|
||||||
return self._moderators[g_id]
|
return self._team_role_members(g_id, TeamMemberTypeEnum.moderator)
|
||||||
|
|
||||||
def get_technicians(self) -> list[discord.Member]:
|
|
||||||
return self._technicians
|
|
||||||
|
|
||||||
def is_member_admin(self, member: discord.Member) -> bool:
|
def is_member_admin(self, member: discord.Member) -> bool:
|
||||||
return member is not None and member.guild.id in self._admins and member in self._admins[member.guild.id]
|
return member in self.get_admins(member.guild.id)
|
||||||
|
|
||||||
def is_member_moderator(self, member: discord.Member) -> bool:
|
def is_member_moderator(self, member: discord.Member) -> bool:
|
||||||
return (
|
return member in self.get_admins(member.guild.id) or member in self.get_moderators(member.guild.id)
|
||||||
member is not None
|
|
||||||
and member.guild.id in self._moderators
|
|
||||||
and member in self._moderators[member.guild.id]
|
|
||||||
or self.is_member_admin(member)
|
|
||||||
)
|
|
||||||
|
|
||||||
def is_member_technician(self, member: discord.Member) -> bool:
|
def is_member_technician(self, member: discord.Member) -> bool:
|
||||||
return member is not None and member in self._technicians
|
config = self._technician_configs.get_technician_config()
|
||||||
|
return str(member.id) in config.technician_ids.select(lambda x: str(x))
|
||||||
|
@ -200,15 +200,13 @@ export class SidebarService {
|
|||||||
|
|
||||||
if (this.server) {
|
if (this.server) {
|
||||||
this.serverMenu.visible = true;
|
this.serverMenu.visible = true;
|
||||||
this.serverMembers.visible = isTechnician || !!user?.isModerator;
|
this.serverMembers.visible = isTechnician || user?.isModerator;
|
||||||
console.log(isTechnician, this.hasFeature("AutoRoleModule") && !!user?.isModerator)
|
this.serverAutoRoles.visible = isTechnician || this.hasFeature("AutoRoleModule") && user?.isModerator;
|
||||||
this.serverAutoRoles.visible = isTechnician || this.hasFeature("AutoRoleModule") && !!user?.isModerator;
|
this.serverLevels.visible = isTechnician || this.hasFeature("LevelModule") && user?.isModerator;
|
||||||
this.serverLevels.visible = isTechnician || this.hasFeature("LevelModule") && !!user?.isModerator;
|
this.serverAchievements.visible = isTechnician || this.hasFeature("AchievementsModule") && user?.isModerator;
|
||||||
this.serverAchievements.visible = isTechnician || this.hasFeature("AchievementsModule") && !!user?.isModerator;
|
this.serverShortRoleNames.visible = isTechnician || this.hasFeature("ShortRoleName") && user?.isAdmin;
|
||||||
this.serverShortRoleNames.visible = isTechnician || this.hasFeature("ShortRoleName") && !!user?.isAdmin;
|
|
||||||
|
|
||||||
console.log(isTechnician, this.serverAutoRoles.visible)
|
this.serverConfig.visible = isTechnician || user?.isAdmin;
|
||||||
this.serverConfig.visible = isTechnician || !!user?.isAdmin;
|
|
||||||
} else {
|
} else {
|
||||||
this.serverMenu.visible = false;
|
this.serverMenu.visible = false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user