diff --git a/flake.nix b/flake.nix index d7a7738..3b79faf 100644 --- a/flake.nix +++ b/flake.nix @@ -3,8 +3,15 @@ nixCargoIntegration.url = "github:yusdacra/nix-cargo-integration"; }; - outputs = inputs: - (inputs.nixCargoIntegration.lib.makeOutputs { root = ./.; }) // { - nixosModules.glados = { imports = [ ./glados-module.nix ]; }; + outputs = inputs@{ self, nixCargoIntegration, ... }: + (nixCargoIntegration.lib.makeOutputs { root = ./.; }) // { + nixosModules.glados = { + imports = [ ./glados-module.nix ]; + config.nixpkgs.overlays = [ self.overlays.glados ]; + }; + + overlays.glados = final: prev: { + glados = self.packages.${final.system}.glados; + }; }; } diff --git a/glados-module.nix b/glados-module.nix index d33ac15..bcd464f 100644 --- a/glados-module.nix +++ b/glados-module.nix @@ -7,105 +7,21 @@ in { options.services.glados = { enable = lib.mkEnableOption "GLaDOS systemd service"; - discord = { - guildId = lib.mkOption { - type = lib.types.str; - description = "Discord guild ID"; - example = "000000000000000000"; - }; - - ownerIds = lib.mkOption { - type = lib.types.listOf lib.types.str; - description = "Discord guild owner IDs"; - example = "[ 000000000000000000 ]"; - }; - - adminChannel = lib.mkOption { - type = lib.types.str; - description = "Discord Admin channel ID"; - example = "000000000000000000"; - }; - - infoChannel = lib.mkOption { - type = lib.types.str; - description = "Discord Info channel ID"; - example = "000000000000000000"; - }; - - botToken = lib.mkOption { - type = lib.types.str; - description = "Discord bot token"; - example = "AAAAAAAAAAAAAAAAAAAAAAAA.AAAAAA.AAAAAAAAAAAAAAAAAAA-AAAAAAA"; - }; - - camRole = lib.mkOption { - type = lib.types.str; - description = "Role used for Minecraft cam accounts"; - example = "000000000000000000"; - }; + envFile = lib.mkOption { + type = lib.types.str; + description = "Path to the environment configuration"; + example = "/run/secrets/my-env"; }; - - influx = { - host = lib.mkOption { - type = lib.types.str; - description = "Influx db host url"; - example = "localhost:8000"; - }; - - database = lib.mkOption { - type = lib.types.str; - description = "Influx database to store time series in"; - example = "minecraft"; - }; - - user = lib.mkOption { - type = lib.types.str; - description = "Influx database user"; - example = "minecraft"; - }; - - password = lib.mkOption { - type = lib.types.str; - description = "Influx database user password"; - example = "minecraft"; - }; - }; - - rcon = { - address = lib.mkOption { - type = lib.types.str; - description = "RCON address"; - example = "your-host.com:12345"; - }; - - password = lib.mkOption { - type = lib.types.str; - description = "RCON password"; - example = "your-secret-password"; - }; - }; - }; config = lib.mkIf cfg.enable { systemd.services.glados = { wantedBy = [ "default.target" ]; serviceConfig = { - ExecStart = '' - ${pkgs.glados}/bin/glados - --guild-id ${cfg.discord.guildId} - ${ownerArgs cfg.discord.ownerIds} - --admin-channel ${cfg.discord.adminChannel} - --info-channel ${cfg.discord.infoChannel} - --discord-token ${cfg.discord.botToken} - --cam-group-name ${cfg.discord.camRole} - --influx-host ${cfg.influx.host} - --influx-db ${cfg.influx.database} - --influx-user ${cfg.influx.user} - --influx-password ${cfg.influx.password} - --rcon-address ${cfg.rcon.address} - --rcon-password ${cfg.rcon.password} - ''; + ExecStart = "${pkgs.glados}/bin/glados --db $STATE_DIRECTORY/state.yml"; + EnvironmentFile = "${cfg.envFile}"; + Environment = "RUST_LOG=warn"; + StateDirectory = "glados"; }; }; }; diff --git a/src/main.rs b/src/main.rs index c0b3148..d2d7fe9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ mod tracking; use discord::Bot; use error::Result; -type UUID<'s> = &'s str; +type Uuid<'s> = &'s str; #[tokio::main(flavor = "current_thread")] async fn main() { diff --git a/src/rcon.rs b/src/rcon.rs index 98f1476..04dea0a 100644 --- a/src/rcon.rs +++ b/src/rcon.rs @@ -66,7 +66,7 @@ impl RconHandle { .as_mut() // We must be connected here .unwrap() - .cmd(&cmd) + .cmd(cmd) .await } diff --git a/src/rcon/commands/luckperms_info.rs b/src/rcon/commands/luckperms_info.rs index a3ef440..b4bf472 100644 --- a/src/rcon/commands/luckperms_info.rs +++ b/src/rcon/commands/luckperms_info.rs @@ -1,8 +1,8 @@ -use crate::{error::Result, rcon::RconCommand, UUID}; +use crate::{error::Result, rcon::RconCommand, Uuid}; type ParentGroup = String; -pub struct LuckPermsParentOfCmd<'s>(pub UUID<'s>); +pub struct LuckPermsParentOfCmd<'s>(pub Uuid<'s>); impl RconCommand for LuckPermsParentOfCmd<'_> { type Output = ParentGroup; diff --git a/src/rcon/commands/whois.rs b/src/rcon/commands/whois.rs index 6b1ade5..36a4d9c 100644 --- a/src/rcon/commands/whois.rs +++ b/src/rcon/commands/whois.rs @@ -1,8 +1,9 @@ use nom::{ branch::alt, bytes::complete::{is_not, tag}, - combinator::{map, value}, - sequence::{preceded, tuple}, + character::complete::{char, space1}, + combinator::{map, opt, value}, + sequence::{delimited, preceded, terminated, tuple}, IResult, Parser, }; @@ -38,6 +39,7 @@ impl RconCommand for WhoIsCmd<'_> { // §6 ====== WhoIs:§c gloom_17 §6======\n§6 - Nick:§r gloom_17\n§6 - UUID:§r 1fea9fa1-7ee0-4c5f-b4d8-97185709cf33\n§6 - Health:§r 18.56/20\n§6 - Hunger:§r 16/20 (+0 saturation)\n§6 - Exp:§r 1,545 (Level 31)\n§6 - Location:§r (world, 443, 64, 73)\n§6 - Playtime:§r 2 days 2 hours 32 minutes\n§6 - Money:§r $0\n§6 - IP Address:§r /213.142.97.187\n§6 - Gamemode:§r survival\n§6 - God mode:§r §4false§r\n§6 - OP:§r §4false§r\n§6 - Fly mode:§r §4false§r (not flying)\n§6 - Speed:§r 0.2\n§6 - AFK:§r §4false§r\n§6 - Jail:§r §4false§r\n§6 - Muted:§r §4false§r\n pub fn parse_whois_result(inp: &str) -> IResult<&str, WhoIs> { + dbg!(inp); let list = tuple(( prop("Nick", parse_string), prop("UUID", parse_string), @@ -53,7 +55,7 @@ pub fn parse_whois_result(inp: &str) -> IResult<&str, WhoIs> { prop("OP", ignore), prop("Fly mode", ignore), prop("Speed", ignore), - prop("AFK", parse_bool), + prop("AFK", parse_afk), prop("Jail", ignore), prop("Muted", ignore), )); @@ -95,5 +97,15 @@ pub fn ignore(inp: &str) -> IResult<&str, ()> { } pub fn parse_bool(inp: &str) -> IResult<&str, bool> { - alt((value(true, tag("§4true§r")), value(false, tag("§4false§r"))))(inp) + alt((value(true, tag("§atrue§r")), value(false, tag("§4false§r"))))(inp) +} + +pub fn parse_afk(inp: &str) -> IResult<&str, bool> { + terminated( + parse_bool, + opt(tuple(( + space1, + delimited(char('('), is_not(")"), char(')')), + ))), + )(inp) }