From ac9ac9a3e38804ddd71e301e7bafbad3aca70720 Mon Sep 17 00:00:00 2001 From: Gerg-L Date: Thu, 6 Feb 2025 12:08:31 -0500 Subject: [PATCH 1/2] nix: add nix-community cache --- nixosModules/nix.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nixosModules/nix.nix b/nixosModules/nix.nix index 992d515..b1ec9d4 100644 --- a/nixosModules/nix.nix +++ b/nixosModules/nix.nix @@ -31,6 +31,12 @@ # Other nix settings # settings = { + substituters = [ + "https://nix-community.cachix.org" + ]; + trusted-public-keys = [ + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + ]; experimental-features = [ "auto-allocate-uids" "ca-derivations" From a5b0c2b27cd4535268c6de9678e7a41fd4640928 Mon Sep 17 00:00:00 2001 From: Gerg-L Date: Thu, 6 Feb 2025 12:09:22 -0500 Subject: [PATCH 2/2] Boot is dead, long live Boot --- .sops.yaml | 8 +- .../gerg-desktop/services/parrot.nix | 23 --- .../services/vocard/application.yml | 121 ++++++++++++++ .../gerg-desktop/services/vocard/secrets.yaml | 22 +++ .../services/vocard/settings.json | 157 ++++++++++++++++++ .../gerg-desktop/services/vocard/vocard.nix | 49 ++++++ packages/lavalink/package.nix | 37 +++++ packages/vocard/package.nix | 63 +++++++ packages/vocard/use_cwd.patch | 84 ++++++++++ 9 files changed, 537 insertions(+), 27 deletions(-) delete mode 100644 nixosConfigurations/gerg-desktop/services/parrot.nix create mode 100644 nixosConfigurations/gerg-desktop/services/vocard/application.yml create mode 100644 nixosConfigurations/gerg-desktop/services/vocard/secrets.yaml create mode 100644 nixosConfigurations/gerg-desktop/services/vocard/settings.json create mode 100644 nixosConfigurations/gerg-desktop/services/vocard/vocard.nix create mode 100644 packages/lavalink/package.nix create mode 100644 packages/vocard/package.nix create mode 100644 packages/vocard/use_cwd.patch diff --git a/.sops.yaml b/.sops.yaml index 9fc25c4..0b99558 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -2,12 +2,12 @@ keys: - &gerg-desktop age180y8kdtdlqelayyz9mq2c7xv248rh4gdfr3amjzvdcjrz6wdaqmsj762pp - &media-laptop age1vxx3qdsucv2v2slag67c4f0kwd8jtta4tue6m8d9xfl4ryrqvyusxgwl68 creation_rules: - - path_regex: nixosConfigurations/gerg-desktop/secrets.yaml$ - key_groups: - - age: - - *gerg-desktop - path_regex: nixosConfigurations/media-laptop/secrets.yaml$ key_groups: - age: - *media-laptop - *gerg-desktop + - path_regex: .*secrets.yaml$ + key_groups: + - age: + - *gerg-desktop diff --git a/nixosConfigurations/gerg-desktop/services/parrot.nix b/nixosConfigurations/gerg-desktop/services/parrot.nix deleted file mode 100644 index 76e828c..0000000 --- a/nixosConfigurations/gerg-desktop/services/parrot.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ - pkgs, - config, - lib, -}: -{ - sops.secrets.discordenv = { }; - - systemd.services.parrot = { - wantedBy = [ "multi-user.target" ]; - wants = [ "network-online.target" ]; - after = [ "network-online.target" ]; - - environment.SETTINGS_PATH = "/persist/services/parrot"; - - serviceConfig = { - ExecStart = lib.getExe pkgs.parrot; - EnvironmentFile = config.sops.secrets.discordenv.path; - Restart = "on-failure"; - RestartSec = "30s"; - }; - }; -} diff --git a/nixosConfigurations/gerg-desktop/services/vocard/application.yml b/nixosConfigurations/gerg-desktop/services/vocard/application.yml new file mode 100644 index 0000000..572e29a --- /dev/null +++ b/nixosConfigurations/gerg-desktop/services/vocard/application.yml @@ -0,0 +1,121 @@ +server: # REST and WS server + port: 2333 + address: 0.0.0.0 + http2: + enabled: false # Whether to enable HTTP/2 support +plugins: + youtube: + enabled: true + allowSearch: true # Whether "ytsearch:" and "ytmsearch:" can be used. + allowDirectVideoIds: true # Whether just video IDs can match. If false, only complete URLs will be loaded. + allowDirectPlaylistIds: true # Whether just playlist IDs can match. If false, only complete URLs will be loaded. + # The clients to use for track loading. See below for a list of valid clients. + # Clients are queried in the order they are given (so the first client is queried first and so on...) + clients: + - MUSIC + - ANDROID_VR + - WEB + - WEBEMBEDDED + oauth: + enabled: true + refreshToken: "" +# name: # Name of the plugin +# some_key: some_value # Some key-value pair for the plugin +# another_key: another_value +lavalink: + plugins: + - dependency: "dev.lavalink.youtube:youtube-plugin:1.11.4" + snapshot: false + # setting "enabled: true" is the bare minimum to get OAuth working. + enabled: true +# - dependency: "com.github.example:example-plugin:1.0.0" # required, the coordinates of your plugin +# repository: "https://maven.example.com/releases" # optional, defaults to the Lavalink releases repository by default +# snapshot: false # optional, defaults to false, used to tell Lavalink to use the snapshot repository instead of the release repository +# pluginsDir: "./plugins" # optional, defaults to "./plugins" +# defaultPluginRepository: "https://maven.lavalink.dev/releases" # optional, defaults to the Lavalink release repository +# defaultPluginSnapshotRepository: "https://maven.lavalink.dev/snapshots" # optional, defaults to the Lavalink snapshot repository + server: + password: "youshallnotpass" + sources: + # The default Youtube source is now deprecated and won't receive further updates. Please use https://github.com/lavalink-devs/youtube-source#plugin instead. + youtube: false + bandcamp: true + soundcloud: true + twitch: true + vimeo: true + nico: true + http: true # warning: keeping HTTP enabled without a proxy configured could expose your server's IP address. + local: false + filters: # All filters are enabled by default + volume: true + equalizer: true + karaoke: true + timescale: true + tremolo: true + vibrato: true + distortion: true + rotation: true + channelMix: true + lowPass: true + nonAllocatingFrameBuffer: false # Setting to true reduces the number of allocations made by each player at the expense of frame rebuilding (e.g. non-instantaneous volume changes) + bufferDurationMs: 400 # The duration of the NAS buffer. Higher values fare better against longer GC pauses. Duration <= 0 to disable JDA-NAS. Minimum of 40ms, lower values may introduce pauses. + frameBufferDurationMs: 5000 # How many milliseconds of audio to keep buffered + opusEncodingQuality: 10 # Opus encoder quality. Valid values range from 0 to 10, where 10 is best quality but is the most expensive on the CPU. + resamplingQuality: LOW # Quality of resampling operations. Valid values are LOW, MEDIUM and HIGH, where HIGH uses the most CPU. + trackStuckThresholdMs: 10000 # The threshold for how long a track can be stuck. A track is stuck if does not return any audio data. + useSeekGhosting: true # Seek ghosting is the effect where whilst a seek is in progress, the audio buffer is read from until empty, or until seek is ready. + youtubePlaylistLoadLimit: 6 # Number of pages at 100 each + playerUpdateInterval: 5 # How frequently to send player updates to clients, in seconds + youtubeSearchEnabled: true + soundcloudSearchEnabled: true + gc-warnings: true + #ratelimit: + #ipBlocks: ["1.0.0.0/8", "..."] # list of ip blocks + #excludedIps: ["...", "..."] # ips which should be explicit excluded from usage by lavalink + #strategy: "RotateOnBan" # RotateOnBan | LoadBalance | NanoSwitch | RotatingNanoSwitch + #searchTriggersFail: true # Whether a search 429 should trigger marking the ip as failing + #retryLimit: -1 # -1 = use default lavaplayer value | 0 = infinity | >0 = retry will happen this numbers times + #youtubeConfig: # Required for avoiding all age restrictions by YouTube, some restricted videos still can be played without. + #email: "" # Email of Google account + #password: "" # Password of Google account + #httpConfig: # Useful for blocking bad-actors from ip-grabbing your music node and attacking it, this way only the http proxy will be attacked + #proxyHost: "localhost" # Hostname of the proxy, (ip or domain) + #proxyPort: 3128 # Proxy port, 3128 is the default for squidProxy + #proxyUser: "" # Optional user for basic authentication fields, leave blank if you don't use basic auth + #proxyPassword: "" # Password for basic authentication + +metrics: + prometheus: + enabled: false + endpoint: /metrics + + +sentry: + dsn: "" + environment: "" +# tags: +# some_key: some_value +# another_key: another_value + +logging: + file: + path: ./logs/ + + level: + root: INFO + lavalink: INFO + dev.lavalink.youtube.http.YoutubeOauth2Handler: INFO + + request: + enabled: true + includeClientInfo: true + includeHeaders: false + includeQueryString: true + includePayload: true + maxPayloadLength: 10000 + + + logback: + rollingpolicy: + max-file-size: 1GB + max-history: 30 diff --git a/nixosConfigurations/gerg-desktop/services/vocard/secrets.yaml b/nixosConfigurations/gerg-desktop/services/vocard/secrets.yaml new file mode 100644 index 0000000..81f3bc8 --- /dev/null +++ b/nixosConfigurations/gerg-desktop/services/vocard/secrets.yaml @@ -0,0 +1,22 @@ +vocard: ENC[AES256_GCM,data:5tMsCU3eI9oTcbJf53paVi82TlEOTgAEUF0hYgnee97x/DZsoiCg5xhsedlp7vwJgWv+em3qiOah47EopR9x4uL8O/WFYAVrx6b03tUTzzk31NZMQ1xxSzbdJ+5BsheB2UYhpt99sHweVTjHsyy1gICa3zfk7W+SfzNJqTk1Sz2u+o9MS2y7UH+lddK/IEF9QlPI3pUJPKCjd2fjZaz/LS4ih3Hq0whpdeLpJ7G4NK2l50hRwDU0vuQgmMJZvEH/Mx7E7n7nHar//9nueE2JxPaKPkAJ7MnZ6GQppLX3zwExe4BEW3H449dVPV94eFcTCYO9QBE=,iv:5ieW16/MCK3BJshihfoeFfPcH83RmaAvy/kF4921zjk=,tag:t5ouiAwmVLl0SbRUEl8CnA==,type:str] +lavalink: ENC[AES256_GCM,data:p6FMF2uXwHqg9bGiU1/8TRCToGyDR3t0Kz4J1mCHu2beSpLZWV0Cy9BcwsE2rFMKh5bxzffh8FrMDJJ8cnLpBqCNDDdyHpRub9zuREiJ0yPUEvG6GhAQpvhMOQYAkDe2fVmSIWdF+s+v514rj7mjEkHpdNov7pEL,iv:9OYomvSLszkTYuDReRUyHauPwaZrzlZC6VvJ1sI6rhw=,tag:X2RpZxwnxU6ofo+19Q/DYQ==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age180y8kdtdlqelayyz9mq2c7xv248rh4gdfr3amjzvdcjrz6wdaqmsj762pp + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6OGxSNDVSNmNYbyt5MW5r + WnVRUnRPY2lPWnZUVXZSU09HMG03ZkJUZlFnClEvTHFUSTZ2c0xmejBIT3ZOSUo3 + bWZQa1dFNlZ0UFI4ZXZCY0ZzMS9ucWMKLS0tIDc0VGsxL09OL1hBeGhvTGhVNHdq + WC9NVmdtWjlWSWN6dUwwMFdPRmpxWG8Ka0i27kBbA4p835RWsEPIghFTwxo4elOz + PL0TnuMNnl66TJiD0x6oRMn8tb6wQIAqGxBt9Jb2lj24eXCtzfGbEg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-02-06T17:07:08Z" + mac: ENC[AES256_GCM,data:jVVU4F6GK8mf8lvH5BNbbU9UHJu/od4Y+jTTSBkFcH9SBy9AWlwm6YjNmotSH3IMuxUWe3vyLLoga2pLgla2TJlScDpok9ZTcZTmSybacrTfT2r3Xyt++R+v+i5fnhlnN7MfnPYx33tofoxpIKdvM0VCaBi+dY1EXXNQOSRdOiA=,iv:bz8+UdBJXSLI+/C48pFoYIHGF6CMaJIonvRMNmJhy7I=,tag:0DCcq2t7wcvzrXqtnAeXeg==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.3 diff --git a/nixosConfigurations/gerg-desktop/services/vocard/settings.json b/nixosConfigurations/gerg-desktop/services/vocard/settings.json new file mode 100644 index 0000000..2c96c50 --- /dev/null +++ b/nixosConfigurations/gerg-desktop/services/vocard/settings.json @@ -0,0 +1,157 @@ +{ + "token": "", + "client_id": "", + "spotify_client_id": "", + "spotify_client_secret": "", + "genius_token": "YOUR_GENIUS_TOKEN", + "mongodb_url": "0.0.0.0", + "mongodb_name": "vocard", + "nodes": { + "DEFAULT": { + "host": "0.0.0.0", + "port": 2333, + "password": "youshallnotpass", + "secure": false, + "identifier": "DEFAULT" + } + }, + "prefix": "?", + "activity": [ + { + "type": "listening", + "name": "/help", + "status": "online" + } + ], + "logging": { + "file": { + "path": "./logs", + "enable": false + }, + "level": { + "discord": "INFO", + "vocard": "INFO", + "ipc_client": "INFO" + }, + "max-history": 30 + }, + "bot_access_user": [], + "embed_color": "0xb3b3b3", + "default_max_queue": 1000, + "lyrics_platform": "lyrist", + "ipc_client": { + "host": "127.0.0.1", + "port": 8000, + "password": "YOUR_PASSWORD", + "secure": false, + "enable": false + }, + "sources_settings": { + "youtube": { + "emoji": "<:youtube:826661982760992778>", + "color": "0xFF0000" + }, + "youtube music": { + "emoji": "<:youtube:826661982760992778>", + "color": "0xFF0000" + }, + "spotify": { + "emoji": "<:spotify:826661996615172146>", + "color": "0x1DB954" + }, + "soundcloud": { + "emoji": "<:soundcloud:852729280027033632>", + "color": "0xFF7700" + }, + "twitch": { + "emoji": "<:twitch:852729278285086741>", + "color": "0x9B4AFF" + }, + "bandcamp": { + "emoji": "<:bandcamp:864694003811221526>", + "color": "0x6F98A7" + }, + "vimeo": { + "emoji": "<:vimeo:864694001919721473>", + "color": "0x1ABCEA" + }, + "apple": { + "emoji": "<:applemusic:994844332374884413>", + "color": "0xE298C4" + }, + "reddit": { + "emoji": "<:reddit:996007566863773717>", + "color": "0xFF5700" + }, + "tiktok": { + "emoji": "<:tiktok:996007689798811698>", + "color": "0x74ECE9" + } + }, + "default_controller": { + "embeds": { + "active": { + "description": "**Now Playing: ```[@@track_name@@]```\nLink: [Click Me](@@track_url@@) | Requester: @@requester@@ | DJ: @@dj@@**", + "footer": { + "text": "Queue Length: @@queue_length@@ | Duration: @@track_duration@@ | Volume: @@volume@@% {{loop_mode != 'Off' ?? | Repeat: @@loop_mode@@}}" + }, + "image": "@@track_thumbnail@@", + "author": { + "name": "Music Controller | @@channel_name@@", + "icon_url": "@@bot_icon@@" + }, + "color": "@@track_color@@" + }, + "inactive": { + "title": { + "name": "There are no songs playing right now" + }, + "description": "[Support](@@server_invite_link@@) | [Invite](@@invite_link@@) | [Questionnaire](https://forms.gle/Qm8vjBfg2kp13YGD7)", + "image": "https://i.imgur.com/dIFBwU7.png", + "color": "@@default_embed_color@@" + } + }, + "default_buttons": [ + [ + "back", + "resume", + "skip", + { + "stop": "red" + }, + "add" + ], + [ + "tracks" + ] + ], + "disableButtonText": false + }, + "default_voice_status_template": "{{@@track_name@@ != 'None' ?? @@track_source_emoji@@ Now Playing: @@track_name@@ // Waiting for song requests}}", + "cooldowns": { + "connect": [ + 2, + 30 + ], + "playlist view": [ + 1, + 30 + ] + }, + "aliases": { + "connect": [ + "join" + ], + "leave": [ + "stop", + "bye" + ], + "play": [ + "p" + ], + "view": [ + "v" + ] + }, + "version": "v2.6.9" +} diff --git a/nixosConfigurations/gerg-desktop/services/vocard/vocard.nix b/nixosConfigurations/gerg-desktop/services/vocard/vocard.nix new file mode 100644 index 0000000..55e66e6 --- /dev/null +++ b/nixosConfigurations/gerg-desktop/services/vocard/vocard.nix @@ -0,0 +1,49 @@ +{ + self', + lib, +}: +{ + systemd.tmpfiles.rules = [ + "d /persist/services/vocard - - - - -" + "d /persist/services/lavalink - - - - -" + ]; + + systemd.services = { + vocard = { + wantedBy = [ "multi-user.target" ]; + wants = [ + "network-online.target" + "lavalink.service" + "ferretdb.service" + ]; + after = [ + "syslog.target" + "network-online.target" + "lavalink.service" + "ferretdb.service" + ]; + serviceConfig = { + ExecStart = lib.getExe self'.packages.vocard; + WorkingDirectory = "/persist/services/vocard"; + Restart = "on-failure"; + RestartSec = "30s"; + }; + }; + + lavalink = { + wants = [ "network-online.target" ]; + after = [ + "syslog.target" + "network-online.target" + ]; + serviceConfig = { + ExecStart = lib.getExe self'.packages.lavalink; + WorkingDirectory = "/persist/services/lavalink"; + Restart = "on-failure"; + RestartSec = "30s"; + }; + }; + }; + + services.ferretdb.enable = true; +} diff --git a/packages/lavalink/package.nix b/packages/lavalink/package.nix new file mode 100644 index 0000000..1df4ea7 --- /dev/null +++ b/packages/lavalink/package.nix @@ -0,0 +1,37 @@ +{ + stdenvNoCC, + fetchurl, + makeBinaryWrapper, + jre_headless, +}: +stdenvNoCC.mkDerivation (finalAttrs: { + pname = "lavalink"; + version = "4.0.8"; + + src = fetchurl { + url = "https://github.com/lavalink-devs/Lavalink/releases/download/${finalAttrs.version}/Lavalink.jar"; + hash = "sha256-G4a9ltPq/L0vcazTQjStTlOOtwrBi37bYUNQHy5CV9Y="; + }; + + plugin = fetchurl { + url = "https://github.com/lavalink-devs/youtube-source/releases/download/1.11.4/youtube-plugin-1.11.4.jar"; + hash = "sha256-OznpsYoiWa6y+/8kukWN66leLi2mZU/1x+zN+uyIk1k="; + }; + + + dontUnpack = true; + + nativeBuildInputs = [ makeBinaryWrapper ]; + + buildCommand = '' + install -Dm644 "$src" "$out/lib/Lavalink.jar" + install -Dm644 "$plugin" "$out/plugins/youtube-plugin.jar" + + mkdir -p $out/bin + makeWrapper ${jre_headless}/bin/java $out/bin/lavalink \ + --add-flags "-jar -Xmx4G $out/lib/Lavalink.jar" + ''; + + meta.mainProgram = "lavalink"; + +}) diff --git a/packages/vocard/package.nix b/packages/vocard/package.nix new file mode 100644 index 0000000..5dc17c5 --- /dev/null +++ b/packages/vocard/package.nix @@ -0,0 +1,63 @@ +{ + lib, + fetchFromGitHub, + python3, + stdenv, + makeBinaryWrapper, +}: +let + version = "2.6.9"; + python = python3.withPackages (p: [ + p.discordpy + p.motor + p.dnspython + p.tldextract + p.validators + p.humanize + p.beautifulsoup4 + p.psutil + ]); +in +stdenv.mkDerivation { + pname = "vocard"; + inherit version; + + src = fetchFromGitHub { + owner = "ChocoMeow"; + repo = "Vocard"; + tag = "v${version}"; + hash = "sha256-21n+6LqXYVXc8ynS62IvWHxK76xxfatN8e99KDPueps="; + }; + + buildPhase = '' + runHook preBuild + + mkdir -p $out/lib + cp -r . $out/lib + + runHook postBuild + ''; + + patches = [ ./use_cwd.patch ]; + + nativeBuildInputs = [ + makeBinaryWrapper + ]; + + installPhase = '' + runHook preInstall + + makeWrapper '${python.interpreter}' "$out/bin/vocard" \ + --add-flags "-u ${placeholder "out"}/lib/main.py" + + runHook postInstall + ''; + + meta = { + description = "Vocard is a simple music bot. It leads to a comfortable experience which is user-friendly, It supports Youtube, Soundcloud, Spotify, Twitch and more"; + homepage = " https://github.com/ChocoMeow/Vocard"; + license = lib.licenses.mit; + mainProgram = "vocard"; + platforms = lib.platforms.all; + }; +} diff --git a/packages/vocard/use_cwd.patch b/packages/vocard/use_cwd.patch new file mode 100644 index 0000000..84617ca --- /dev/null +++ b/packages/vocard/use_cwd.patch @@ -0,0 +1,84 @@ +diff --git a/function.py b/function.py +index 6e09f5e..f0f6a11 100644 +--- a/function.py ++++ b/function.py +@@ -18,7 +18,7 @@ from motor.motor_asyncio import ( + + ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) + +-if not os.path.exists(os.path.join(ROOT_DIR, "settings.json")): ++if not os.path.exists(os.path.join(os.getcwd(), "settings.json")): + raise Exception("Settings file not set!") + + #--------------- Cache Var --------------- +@@ -52,7 +52,7 @@ ALLOWED_MENTIONS = discord.AllowedMentions().none() + #-------------- Vocard Functions -------------- + def open_json(path: str) -> dict: + try: +- with open(os.path.join(ROOT_DIR, path), encoding="utf8") as json_file: ++ with open(path, encoding="utf8") as json_file: + return json.load(json_file) + except: + return {} +@@ -64,7 +64,7 @@ def update_json(path: str, new_data: dict) -> None: + + data.update(new_data) + +- with open(os.path.join(ROOT_DIR, path), "w") as json_file: ++ with open(path, "w") as json_file: + json.dump(data, json_file, indent=4) + + def langs_setup() -> None: +@@ -74,7 +74,7 @@ def langs_setup() -> None: + + for language in os.listdir(os.path.join(ROOT_DIR, "local_langs")): + if language.endswith('.json'): +- LOCAL_LANGS[language[:-5]] = open_json(os.path.join("local_langs", language)) ++ LOCAL_LANGS[language[:-5]] = open_json(os.path.join(ROOT_DIR, "local_langs", language)) + + return + +@@ -130,7 +130,7 @@ def get_lang_non_async(guild_id: int, *keys) -> Union[list[str], str]: + settings = SETTINGS_BUFFER.get(guild_id, {}) + lang = settings.get("lang", "EN") + if lang in LANGS and not LANGS[lang]: +- LANGS[lang] = open_json(os.path.join("langs", f"{lang}.json")) ++ LANGS[lang] = open_json(os.path.join(ROOT_DIR, "langs", f"{lang}.json")) + + if len(keys) == 1: + return LANGS.get(lang, {}).get(keys[0], "Language pack not found!") +@@ -147,7 +147,7 @@ async def get_lang(guild_id:int, *keys) -> Union[list[str], str]: + settings = await get_settings(guild_id) + lang = settings.get("lang", "EN") + if lang in LANGS and not LANGS[lang]: +- LANGS[lang] = open_json(os.path.join("langs", f"{lang}.json")) ++ LANGS[lang] = open_json(os.path.join(ROOT_DIR, "langs", f"{lang}.json")) + + if len(keys) == 1: + return LANGS.get(lang, {}).get(keys[0], "Language pack not found!") +diff --git a/main.py b/main.py +index e2c6b9e..4ff7de6 100644 +--- a/main.py ++++ b/main.py +@@ -81,12 +81,6 @@ class Vocard(commands.Bot): + except Exception as e: + func.logger.error(f"Cannot connected to dashboard! - Reason: {e}") + +- if not func.settings.version or func.settings.version != update.__version__: +- func.update_json("settings.json", new_data={"version": update.__version__}) +- +- await self.tree.set_translator(Translator()) +- await self.tree.sync() +- + async def on_ready(self): + func.logger.info("------------------") + func.logger.info(f"Logging As {self.user}") +@@ -144,7 +138,7 @@ async def get_prefix(bot, message: discord.Message): + return settings.get("prefix", func.settings.bot_prefix) + + # Loading settings and logger +-func.settings = Settings(func.open_json("settings.json")) ++func.settings = Settings(func.open_json(os.path.join(os.getcwd(),"settings.json"))) + + LOG_SETTINGS = func.settings.logging + if (LOG_FILE := LOG_SETTINGS.get("file", {})).get("enable", True):