mirror of
				https://github.com/SikongJueluo/cc-utils.git
				synced 2025-11-04 19:27:50 +08:00 
			
		
		
		
	reconstruct the access control cli
This commit is contained in:
		@@ -6,7 +6,7 @@
 | 
			
		||||
    "groupName": "Admin",
 | 
			
		||||
    "groupUsers": ["Selcon"],
 | 
			
		||||
    "isAllowed": true,
 | 
			
		||||
    "isWarnTarget": true
 | 
			
		||||
    "isNotice": true
 | 
			
		||||
  },
 | 
			
		||||
  "defaultToastConfig": {
 | 
			
		||||
    "title": {
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
      "text": "Hello %groupName% %playerName%",
 | 
			
		||||
      "color": "green"
 | 
			
		||||
    },
 | 
			
		||||
    "prefix": "桃花源",
 | 
			
		||||
    "prefix": "Taohuayuan",
 | 
			
		||||
    "brackets": "[]",
 | 
			
		||||
    "bracketColor": ""
 | 
			
		||||
  },
 | 
			
		||||
@@ -39,19 +39,19 @@
 | 
			
		||||
      "groupName": "user",
 | 
			
		||||
      "groupUsers": [],
 | 
			
		||||
      "isAllowed": true,
 | 
			
		||||
      "isWarnTarget": true
 | 
			
		||||
      "isNotice": true
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "groupName": "VIP",
 | 
			
		||||
      "groupUsers": [],
 | 
			
		||||
      "isAllowed": true,
 | 
			
		||||
      "isWarnTarget": false
 | 
			
		||||
      "isNotice": false
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "groupName": "enemy",
 | 
			
		||||
      "groupUsers": [],
 | 
			
		||||
      "isAllowed": false,
 | 
			
		||||
      "isWarnTarget": false,
 | 
			
		||||
      "isNotice": false,
 | 
			
		||||
      "toastConfig": {
 | 
			
		||||
        "title": {
 | 
			
		||||
          "text": "Warn",
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,672 @@
 | 
			
		||||
import { CCLog } from "@/lib/ccLog";
 | 
			
		||||
import { AccessConfig, UserGroupConfig, saveConfig } from "./config";
 | 
			
		||||
import { ChatBoxEvent, pullEventAs } from "@/lib/event";
 | 
			
		||||
import { parseBoolean } from "@/lib/common";
 | 
			
		||||
 | 
			
		||||
// CLI命令接口
 | 
			
		||||
interface CLICommand {
 | 
			
		||||
  name: string;
 | 
			
		||||
  description: string;
 | 
			
		||||
  usage: string;
 | 
			
		||||
  execute: (args: string[], executor: string, context: CLIContext) => CLIResult;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CLI执行结果
 | 
			
		||||
interface CLIResult {
 | 
			
		||||
  success: boolean;
 | 
			
		||||
  message?: string;
 | 
			
		||||
  shouldSaveConfig?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CLI上下文
 | 
			
		||||
interface CLIContext {
 | 
			
		||||
  config: AccessConfig;
 | 
			
		||||
  configFilepath: string;
 | 
			
		||||
  log: CCLog;
 | 
			
		||||
  chatBox: any; // eslint-disable-line @typescript-eslint/no-explicit-any
 | 
			
		||||
  groupNames: string[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 基础命令处理器
 | 
			
		||||
class CLICommandProcessor {
 | 
			
		||||
  private commands = new Map<string, CLICommand>();
 | 
			
		||||
  private context: CLIContext;
 | 
			
		||||
 | 
			
		||||
  constructor(context: CLIContext) {
 | 
			
		||||
    this.context = context;
 | 
			
		||||
    this.initializeCommands();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private initializeCommands() {
 | 
			
		||||
    // 注册所有命令
 | 
			
		||||
    this.registerCommand(new AddCommand());
 | 
			
		||||
    this.registerCommand(new DelCommand());
 | 
			
		||||
    this.registerCommand(new ListCommand());
 | 
			
		||||
    this.registerCommand(new SetCommand());
 | 
			
		||||
    this.registerCommand(new CreateGroupCommand());
 | 
			
		||||
    this.registerCommand(new RemoveGroupCommand());
 | 
			
		||||
    this.registerCommand(new EditCommand());
 | 
			
		||||
    this.registerCommand(new ShowConfigCommand());
 | 
			
		||||
    this.registerCommand(new HelpCommand());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private registerCommand(command: CLICommand) {
 | 
			
		||||
    this.commands.set(command.name, command);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public processCommand(message: string, executor: string): CLIResult {
 | 
			
		||||
    const params = message.split(" ");
 | 
			
		||||
 | 
			
		||||
    // 移除 "@AC" 前缀
 | 
			
		||||
    if (params.length < 2) {
 | 
			
		||||
      return this.getHelpCommand().execute([], executor, this.context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const commandName = params[1].replace("/", ""); // 移除 "/" 前缀
 | 
			
		||||
    const args = params.slice(2);
 | 
			
		||||
 | 
			
		||||
    const command = this.commands.get(commandName);
 | 
			
		||||
    if (!command) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Unknown command: ${commandName}`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return command.execute(args, executor, this.context);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private getHelpCommand(): CLICommand {
 | 
			
		||||
    return this.commands.get("help")!;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public sendResponse(result: CLIResult, executor: string) {
 | 
			
		||||
    if (result.message != null && result.message.length > 0) {
 | 
			
		||||
      // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
 | 
			
		||||
      this.context.chatBox.sendMessageToPlayer(
 | 
			
		||||
        result.message,
 | 
			
		||||
        executor,
 | 
			
		||||
        "AccessControl",
 | 
			
		||||
        "[]",
 | 
			
		||||
        undefined,
 | 
			
		||||
        undefined,
 | 
			
		||||
        true,
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (result.shouldSaveConfig === true) {
 | 
			
		||||
      saveConfig(this.context.config, this.context.configFilepath);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 添加用户命令
 | 
			
		||||
class AddCommand implements CLICommand {
 | 
			
		||||
  name = "add";
 | 
			
		||||
  description = "Add player to group";
 | 
			
		||||
  usage = "add <userGroup> <playerName>";
 | 
			
		||||
 | 
			
		||||
  execute(args: string[], _executor: string, context: CLIContext): CLIResult {
 | 
			
		||||
    if (args.length !== 2) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Usage: ${this.usage}`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const [groupName, playerName] = args;
 | 
			
		||||
 | 
			
		||||
    if (groupName === "admin") {
 | 
			
		||||
      context.config.adminGroupConfig.groupUsers.push(playerName);
 | 
			
		||||
      return {
 | 
			
		||||
        success: true,
 | 
			
		||||
        message: `Add player ${playerName} to admin`,
 | 
			
		||||
        shouldSaveConfig: true,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!context.groupNames.includes(groupName)) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Invalid group: ${groupName}. Available groups: ${context.groupNames.join(", ")}`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const groupConfig = context.config.usersGroups.find(
 | 
			
		||||
      (value) => value.groupName === groupName,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (!groupConfig) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Group ${groupName} not found`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (groupConfig.groupUsers === undefined) {
 | 
			
		||||
      groupConfig.groupUsers = [playerName];
 | 
			
		||||
    } else {
 | 
			
		||||
      groupConfig.groupUsers.push(playerName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      success: true,
 | 
			
		||||
      message: `Add player ${playerName} to ${groupConfig.groupName}`,
 | 
			
		||||
      shouldSaveConfig: true,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 删除用户命令
 | 
			
		||||
class DelCommand implements CLICommand {
 | 
			
		||||
  name = "del";
 | 
			
		||||
  description = "Delete player from group";
 | 
			
		||||
  usage = "del <userGroup> <playerName>";
 | 
			
		||||
 | 
			
		||||
  execute(args: string[], _executor: string, context: CLIContext): CLIResult {
 | 
			
		||||
    if (args.length !== 2) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Usage: ${this.usage}`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const [groupName, playerName] = args;
 | 
			
		||||
 | 
			
		||||
    if (groupName === "admin") {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: "Could't delete admin, please edit config",
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!context.groupNames.includes(groupName)) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Invalid group: ${groupName}. Available groups: ${context.groupNames.join(", ")}`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const groupConfig = context.config.usersGroups.find(
 | 
			
		||||
      (value) => value.groupName === groupName,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (!groupConfig) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Group ${groupName} not found`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (groupConfig.groupUsers === undefined) {
 | 
			
		||||
      groupConfig.groupUsers = [];
 | 
			
		||||
    } else {
 | 
			
		||||
      groupConfig.groupUsers = groupConfig.groupUsers.filter(
 | 
			
		||||
        (user) => user !== playerName,
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      success: true,
 | 
			
		||||
      message: `Delete ${groupConfig.groupName} ${playerName}`,
 | 
			
		||||
      shouldSaveConfig: true,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 列表命令
 | 
			
		||||
class ListCommand implements CLICommand {
 | 
			
		||||
  name = "list";
 | 
			
		||||
  description = "List all players with their groups";
 | 
			
		||||
  usage = "list";
 | 
			
		||||
 | 
			
		||||
  execute(_args: string[], _executor: string, context: CLIContext): CLIResult {
 | 
			
		||||
    let message = `Admins : [ ${context.config.adminGroupConfig.groupUsers.join(", ")} ]\n`;
 | 
			
		||||
 | 
			
		||||
    for (const groupConfig of context.config.usersGroups) {
 | 
			
		||||
      const users = groupConfig.groupUsers ?? [];
 | 
			
		||||
      message += `${groupConfig.groupName} : [ ${users.join(", ")} ]\n`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      success: true,
 | 
			
		||||
      message: message.trim(),
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 设置命令
 | 
			
		||||
class SetCommand implements CLICommand {
 | 
			
		||||
  name = "set";
 | 
			
		||||
  description = "Config access control settings";
 | 
			
		||||
  usage = "set <option> <value>";
 | 
			
		||||
 | 
			
		||||
  execute(args: string[], _executor: string, context: CLIContext): CLIResult {
 | 
			
		||||
    if (args.length !== 2) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Usage: ${this.usage}\nOptions: warnInterval, detectInterval, detectRange`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const [option, valueStr] = args;
 | 
			
		||||
    const value = parseInt(valueStr);
 | 
			
		||||
 | 
			
		||||
    if (isNaN(value)) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Invalid value: ${valueStr}. Must be a number.`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (option) {
 | 
			
		||||
      case "warnInterval":
 | 
			
		||||
        context.config.warnInterval = value;
 | 
			
		||||
        return {
 | 
			
		||||
          success: true,
 | 
			
		||||
          message: `Set warn interval to ${context.config.warnInterval}`,
 | 
			
		||||
          shouldSaveConfig: true,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
      case "detectInterval":
 | 
			
		||||
        context.config.detectInterval = value;
 | 
			
		||||
        return {
 | 
			
		||||
          success: true,
 | 
			
		||||
          message: `Set detect interval to ${context.config.detectInterval}`,
 | 
			
		||||
          shouldSaveConfig: true,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
      case "detectRange":
 | 
			
		||||
        context.config.detectRange = value;
 | 
			
		||||
        return {
 | 
			
		||||
          success: true,
 | 
			
		||||
          message: `Set detect range to ${context.config.detectRange}`,
 | 
			
		||||
          shouldSaveConfig: true,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
        return {
 | 
			
		||||
          success: false,
 | 
			
		||||
          message: `Unknown option: ${option}. Available options: warnInterval, detectInterval, detectRange`,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 帮助命令
 | 
			
		||||
class HelpCommand implements CLICommand {
 | 
			
		||||
  name = "help";
 | 
			
		||||
  description = "Show command help";
 | 
			
		||||
  usage = "help";
 | 
			
		||||
 | 
			
		||||
  execute(_args: string[], _executor: string, context: CLIContext): CLIResult {
 | 
			
		||||
    const helpMessage = `
 | 
			
		||||
Command Usage: @AC /<Command> [args]
 | 
			
		||||
Commands:
 | 
			
		||||
  - add <userGroup> <playerName>
 | 
			
		||||
      add player to group
 | 
			
		||||
      userGroup: ${context.groupNames.join(", ")}
 | 
			
		||||
  - del <userGroup> <playerName>
 | 
			
		||||
      delete player in the group, except Admin
 | 
			
		||||
      userGroup: ${context.groupNames.join(", ")}
 | 
			
		||||
  - list
 | 
			
		||||
      list all of the player with its group
 | 
			
		||||
  - set <options> [params]
 | 
			
		||||
      config access control settings
 | 
			
		||||
      options: warnInterval, detectInterval, detectRange
 | 
			
		||||
  - creategroup <groupName> <isAllowed> <isNotice>
 | 
			
		||||
      create new user group
 | 
			
		||||
  - removegroup <groupName>
 | 
			
		||||
      remove user group (except admin groups)
 | 
			
		||||
  - edit <target> [args]
 | 
			
		||||
      edit various configurations
 | 
			
		||||
      targets: group (edit group properties)
 | 
			
		||||
      examples: edit group <groupName> <property> <value> (properties: isAllowed, isNotice)
 | 
			
		||||
  - showconfig [type]
 | 
			
		||||
      show configuration (type: groups/toast/all)
 | 
			
		||||
  - help
 | 
			
		||||
      show this help message
 | 
			
		||||
    `;
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      success: true,
 | 
			
		||||
      message: helpMessage.trim(),
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 创建用户组命令
 | 
			
		||||
class CreateGroupCommand implements CLICommand {
 | 
			
		||||
  name = "creategroup";
 | 
			
		||||
  description = "Create new user group";
 | 
			
		||||
  usage = "creategroup <groupName> <isAllowed> <isNotice>";
 | 
			
		||||
 | 
			
		||||
  execute(args: string[], _executor: string, context: CLIContext): CLIResult {
 | 
			
		||||
    if (args.length !== 3) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Usage: ${this.usage}\nExample: creategroup VIP2 true false`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const [groupName, isAllowedStr, isNoticeStr] = args;
 | 
			
		||||
 | 
			
		||||
    // 检查组名是否已存在
 | 
			
		||||
    if (context.groupNames.includes(groupName) || groupName === "admin") {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Group ${groupName} already exists`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const isAllowed = isAllowedStr.toLowerCase() === "true";
 | 
			
		||||
    const isNotice = isNoticeStr.toLowerCase() === "true";
 | 
			
		||||
 | 
			
		||||
    const newGroup: UserGroupConfig = {
 | 
			
		||||
      groupName,
 | 
			
		||||
      isAllowed,
 | 
			
		||||
      isNotice,
 | 
			
		||||
      groupUsers: [],
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    context.config.usersGroups.push(newGroup);
 | 
			
		||||
    context.groupNames.push(groupName);
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      success: true,
 | 
			
		||||
      message: `Created group ${groupName} (allowed: ${isAllowed}, notice: ${isNotice})`,
 | 
			
		||||
      shouldSaveConfig: true,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 删除用户组命令
 | 
			
		||||
class RemoveGroupCommand implements CLICommand {
 | 
			
		||||
  name = "removegroup";
 | 
			
		||||
  description = "Remove user group";
 | 
			
		||||
  usage = "removegroup <groupName>";
 | 
			
		||||
 | 
			
		||||
  execute(args: string[], _executor: string, context: CLIContext): CLIResult {
 | 
			
		||||
    if (args.length !== 1) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Usage: ${this.usage}`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const [groupName] = args;
 | 
			
		||||
 | 
			
		||||
    if (groupName === "admin") {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: "Cannot remove admin group",
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const groupIndex = context.config.usersGroups.findIndex(
 | 
			
		||||
      (group) => group.groupName === groupName,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (groupIndex === -1) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Group ${groupName} not found`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    context.config.usersGroups.splice(groupIndex, 1);
 | 
			
		||||
    const nameIndex = context.groupNames.indexOf(groupName);
 | 
			
		||||
    if (nameIndex > -1) {
 | 
			
		||||
      context.groupNames.splice(nameIndex, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      success: true,
 | 
			
		||||
      message: `Removed group ${groupName}`,
 | 
			
		||||
      shouldSaveConfig: true,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 统一编辑命令
 | 
			
		||||
class EditCommand implements CLICommand {
 | 
			
		||||
  name = "edit";
 | 
			
		||||
  description = "Edit various configurations (only group now)";
 | 
			
		||||
  usage = "edit <target> [args]";
 | 
			
		||||
 | 
			
		||||
  execute(args: string[], _executor: string, context: CLIContext): CLIResult {
 | 
			
		||||
    if (args.length < 1) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Usage: ${this.usage}\nTargets: group`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const [target, ...rest] = args;
 | 
			
		||||
 | 
			
		||||
    switch (target) {
 | 
			
		||||
      case "group":
 | 
			
		||||
        return this.editGroup(rest, context);
 | 
			
		||||
      default:
 | 
			
		||||
        return {
 | 
			
		||||
          success: false,
 | 
			
		||||
          message: `Unknown target: ${target}. Available: group`,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private editGroup(args: string[], context: CLIContext): CLIResult {
 | 
			
		||||
    if (args.length !== 3) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Usage: edit group <groupName> <property> <value>\nProperties: isAllowed, isNotice`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const [groupName, property, valueStr] = args;
 | 
			
		||||
 | 
			
		||||
    let groupConfig: UserGroupConfig | undefined;
 | 
			
		||||
 | 
			
		||||
    if (groupName === "admin") {
 | 
			
		||||
      groupConfig = context.config.adminGroupConfig;
 | 
			
		||||
    } else {
 | 
			
		||||
      groupConfig = context.config.usersGroups.find(
 | 
			
		||||
        (group) => group.groupName === groupName,
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!groupConfig) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: `Group ${groupName} not found`,
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (property) {
 | 
			
		||||
      case "isAllowed": {
 | 
			
		||||
        const val = parseBoolean(valueStr);
 | 
			
		||||
        if (val != undefined) {
 | 
			
		||||
          groupConfig.isAllowed = val;
 | 
			
		||||
          return {
 | 
			
		||||
            success: true,
 | 
			
		||||
            message: `Set ${groupName}.isAllowed to ${groupConfig.isAllowed}`,
 | 
			
		||||
            shouldSaveConfig: true,
 | 
			
		||||
          };
 | 
			
		||||
        } else {
 | 
			
		||||
          return {
 | 
			
		||||
            success: false,
 | 
			
		||||
            message: `Set ${groupName}.isAllowed failed`,
 | 
			
		||||
            shouldSaveConfig: false,
 | 
			
		||||
          };
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      case "isNotice": {
 | 
			
		||||
        const val = parseBoolean(valueStr);
 | 
			
		||||
        if (val != undefined) {
 | 
			
		||||
          groupConfig.isNotice = val;
 | 
			
		||||
          return {
 | 
			
		||||
            success: true,
 | 
			
		||||
            message: `Set ${groupName}.isNotice to ${groupConfig.isNotice}`,
 | 
			
		||||
            shouldSaveConfig: true,
 | 
			
		||||
          };
 | 
			
		||||
        } else {
 | 
			
		||||
          return {
 | 
			
		||||
            success: false,
 | 
			
		||||
            message: `Set ${groupName}.isAllowed failed`,
 | 
			
		||||
            shouldSaveConfig: false,
 | 
			
		||||
          };
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
        return {
 | 
			
		||||
          success: false,
 | 
			
		||||
          message: `Unknown property: ${property}. Available: isAllowed, isNotice`,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 显示配置命令
 | 
			
		||||
class ShowConfigCommand implements CLICommand {
 | 
			
		||||
  name = "showconfig";
 | 
			
		||||
  description = "Show configuration";
 | 
			
		||||
  usage = "showconfig [type]";
 | 
			
		||||
 | 
			
		||||
  execute(args: string[], _executor: string, context: CLIContext): CLIResult {
 | 
			
		||||
    const type = args[0] || "all";
 | 
			
		||||
 | 
			
		||||
    switch (type) {
 | 
			
		||||
      case "groups": {
 | 
			
		||||
        let groupsMessage = `Admin Group: ${context.config.adminGroupConfig.groupName}\n`;
 | 
			
		||||
        groupsMessage += `  Users: [${context.config.adminGroupConfig.groupUsers.join(", ")}]\n`;
 | 
			
		||||
        groupsMessage += `  Allowed: ${context.config.adminGroupConfig.isAllowed}\n`;
 | 
			
		||||
        groupsMessage += `  notice: ${context.config.adminGroupConfig.isNotice}\n\n`;
 | 
			
		||||
 | 
			
		||||
        for (const group of context.config.usersGroups) {
 | 
			
		||||
          groupsMessage += `Group: ${group.groupName}\n`;
 | 
			
		||||
          groupsMessage += `  Users: [${(group.groupUsers ?? []).join(", ")}]\n`;
 | 
			
		||||
          groupsMessage += `  Allowed: ${group.isAllowed}\n`;
 | 
			
		||||
          groupsMessage += `  Notice: ${group.isNotice}\n`;
 | 
			
		||||
          if (group.toastConfig !== undefined) {
 | 
			
		||||
            groupsMessage += `  Custom Toast Config:\n`;
 | 
			
		||||
            groupsMessage += `    Title: ${group.toastConfig.title.text}\n`;
 | 
			
		||||
            groupsMessage += `    Message: ${group.toastConfig.msg.text}\n`;
 | 
			
		||||
            if (group.toastConfig.prefix !== undefined) {
 | 
			
		||||
              groupsMessage += `    Prefix: ${group.toastConfig.prefix}\n`;
 | 
			
		||||
            }
 | 
			
		||||
            if (group.toastConfig.brackets !== undefined) {
 | 
			
		||||
              groupsMessage += `    Brackets: ${group.toastConfig.brackets}\n`;
 | 
			
		||||
            }
 | 
			
		||||
            if (group.toastConfig.bracketColor !== undefined) {
 | 
			
		||||
              groupsMessage += `    Bracket Color: ${group.toastConfig.bracketColor}\n`;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          groupsMessage += "\n";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
          success: true,
 | 
			
		||||
          message: groupsMessage.trim(),
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      case "toast": {
 | 
			
		||||
        let toastMessage = "Default Toast Config:\n";
 | 
			
		||||
        toastMessage += `  Title: ${context.config.defaultToastConfig.title.text}\n`;
 | 
			
		||||
        toastMessage += `  Message: ${context.config.defaultToastConfig.msg.text}\n`;
 | 
			
		||||
        toastMessage += `  Prefix: ${context.config.defaultToastConfig.prefix ?? "none"}\n`;
 | 
			
		||||
        toastMessage += `  Brackets: ${context.config.defaultToastConfig.brackets ?? "none"}\n`;
 | 
			
		||||
        toastMessage += `  Bracket Color: ${context.config.defaultToastConfig.bracketColor ?? "none"}\n\n`;
 | 
			
		||||
 | 
			
		||||
        toastMessage += "Warn Toast Config:\n";
 | 
			
		||||
        toastMessage += `  Title: ${context.config.warnToastConfig.title.text}\n`;
 | 
			
		||||
        toastMessage += `  Message: ${context.config.warnToastConfig.msg.text}\n`;
 | 
			
		||||
        toastMessage += `  Prefix: ${context.config.warnToastConfig.prefix ?? "none"}\n`;
 | 
			
		||||
        toastMessage += `  Brackets: ${context.config.warnToastConfig.brackets ?? "none"}\n`;
 | 
			
		||||
        toastMessage += `  Bracket Color: ${context.config.warnToastConfig.bracketColor ?? "none"}`;
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
          success: true,
 | 
			
		||||
          message: toastMessage,
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      case "all": {
 | 
			
		||||
        let allMessage = `Detect Range: ${context.config.detectRange}\n`;
 | 
			
		||||
        allMessage += `Detect Interval: ${context.config.detectInterval}\n`;
 | 
			
		||||
        allMessage += `Warn Interval: ${context.config.warnInterval}\n\n`;
 | 
			
		||||
        allMessage +=
 | 
			
		||||
          "Use 'showconfig groups' or 'showconfig toast' for detailed view";
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
          success: true,
 | 
			
		||||
          message: allMessage,
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
        return {
 | 
			
		||||
          success: false,
 | 
			
		||||
          message: `Invalid type: ${type}. Available: groups, toast, all`,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CLI循环处理器
 | 
			
		||||
export class AccessControlCLI {
 | 
			
		||||
  private processor: CLICommandProcessor;
 | 
			
		||||
  private context: CLIContext;
 | 
			
		||||
 | 
			
		||||
  constructor(context: CLIContext) {
 | 
			
		||||
    this.context = context;
 | 
			
		||||
    this.processor = new CLICommandProcessor(context);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public startConfigLoop() {
 | 
			
		||||
    while (true) {
 | 
			
		||||
      const ev = pullEventAs(ChatBoxEvent, "chat");
 | 
			
		||||
 | 
			
		||||
      if (ev === undefined) continue;
 | 
			
		||||
      if (
 | 
			
		||||
        !this.context.config.adminGroupConfig.groupUsers.includes(ev.username)
 | 
			
		||||
      )
 | 
			
		||||
        continue;
 | 
			
		||||
      if (!ev.message.startsWith("@AC")) continue;
 | 
			
		||||
 | 
			
		||||
      this.context.log.info(
 | 
			
		||||
        `Received command "${ev.message}" from admin ${ev.username}`,
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      const result = this.processor.processCommand(ev.message, ev.username);
 | 
			
		||||
      this.processor.sendResponse(result, ev.username);
 | 
			
		||||
 | 
			
		||||
      if (!result.success) {
 | 
			
		||||
        this.context.log.warn(`Command failed: ${result.message}`);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 导出类型和工厂函数
 | 
			
		||||
export { CLIContext, CLIResult, CLICommand };
 | 
			
		||||
 | 
			
		||||
export function createAccessControlCLI(
 | 
			
		||||
  config: AccessConfig,
 | 
			
		||||
  configFilepath: string,
 | 
			
		||||
  log: CCLog,
 | 
			
		||||
  chatBox: any, // eslint-disable-line @typescript-eslint/no-explicit-any
 | 
			
		||||
  groupNames: string[],
 | 
			
		||||
): AccessControlCLI {
 | 
			
		||||
  const context: CLIContext = {
 | 
			
		||||
    config,
 | 
			
		||||
    configFilepath,
 | 
			
		||||
    log,
 | 
			
		||||
    chatBox, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
 | 
			
		||||
    groupNames,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return new AccessControlCLI(context);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ interface ToastConfig {
 | 
			
		||||
interface UserGroupConfig {
 | 
			
		||||
  groupName: string;
 | 
			
		||||
  isAllowed: boolean;
 | 
			
		||||
  isWarnTarget: boolean;
 | 
			
		||||
  isNotice: boolean;
 | 
			
		||||
  groupUsers: string[];
 | 
			
		||||
  toastConfig?: ToastConfig;
 | 
			
		||||
}
 | 
			
		||||
@@ -37,26 +37,26 @@ const defaultConfig: AccessConfig = {
 | 
			
		||||
    groupName: "Admin",
 | 
			
		||||
    groupUsers: ["Selcon"],
 | 
			
		||||
    isAllowed: true,
 | 
			
		||||
    isWarnTarget: false,
 | 
			
		||||
    isNotice: false,
 | 
			
		||||
  },
 | 
			
		||||
  usersGroups: [
 | 
			
		||||
    {
 | 
			
		||||
      groupName: "user",
 | 
			
		||||
      groupUsers: [],
 | 
			
		||||
      isAllowed: true,
 | 
			
		||||
      isWarnTarget: true,
 | 
			
		||||
      isNotice: true,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      groupName: "VIP",
 | 
			
		||||
      groupUsers: [],
 | 
			
		||||
      isAllowed: true,
 | 
			
		||||
      isWarnTarget: false,
 | 
			
		||||
      isNotice: false,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      groupName: "enemies",
 | 
			
		||||
      groupUsers: [],
 | 
			
		||||
      isAllowed: false,
 | 
			
		||||
      isWarnTarget: false,
 | 
			
		||||
      isNotice: false,
 | 
			
		||||
      toastConfig: {
 | 
			
		||||
        title: {
 | 
			
		||||
          text: "Warn",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,33 +1,22 @@
 | 
			
		||||
import { CCLog, DAY } from "@/lib/ccLog";
 | 
			
		||||
import {
 | 
			
		||||
  ToastConfig,
 | 
			
		||||
  UserGroupConfig,
 | 
			
		||||
  loadConfig,
 | 
			
		||||
  saveConfig,
 | 
			
		||||
  setLog,
 | 
			
		||||
} from "./config";
 | 
			
		||||
import { ToastConfig, UserGroupConfig, loadConfig, setLog } from "./config";
 | 
			
		||||
import { createAccessControlCLI } from "./cli";
 | 
			
		||||
import * as peripheralManager from "../lib/PeripheralManager";
 | 
			
		||||
import { ChatBoxEvent, pullEventAs } from "@/lib/event";
 | 
			
		||||
import { quotestring } from "@sikongjueluo/dkjson-types";
 | 
			
		||||
 | 
			
		||||
const DEBUG = false;
 | 
			
		||||
const args = [...$vararg];
 | 
			
		||||
 | 
			
		||||
// Init Log
 | 
			
		||||
const log = new CCLog("accesscontrol.log", DAY);
 | 
			
		||||
setLog(log);
 | 
			
		||||
 | 
			
		||||
// Load Config
 | 
			
		||||
const configFilepath = `${shell.dir()}/access.config.json`;
 | 
			
		||||
const config = loadConfig(configFilepath);
 | 
			
		||||
log.info("Load config successfully!");
 | 
			
		||||
log.debug(textutils.serialise(config, { allow_repetitions: true }));
 | 
			
		||||
if (DEBUG) log.debug(textutils.serialise(config, { allow_repetitions: true }));
 | 
			
		||||
const groupNames = config.usersGroups.map((value) => value.groupName);
 | 
			
		||||
const warnTargetPlayers = config.adminGroupConfig.groupUsers.concat(
 | 
			
		||||
  config.usersGroups
 | 
			
		||||
    .filter((value) => value.isWarnTarget)
 | 
			
		||||
    .map((value) => value.groupUsers ?? [])
 | 
			
		||||
    .flat(),
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
let warnTargetPlayers: string[];
 | 
			
		||||
const playerDetector = peripheralManager.findByNameRequired("playerDetector");
 | 
			
		||||
const chatBox = peripheralManager.findByNameRequired("chatBox");
 | 
			
		||||
 | 
			
		||||
@@ -66,7 +55,7 @@ function sendToast(
 | 
			
		||||
      groupConfig?.groupName,
 | 
			
		||||
    ),
 | 
			
		||||
    player,
 | 
			
		||||
    quotestring(toastConfig.prefix ?? config.defaultToastConfig.prefix!),
 | 
			
		||||
    toastConfig.prefix ?? config.defaultToastConfig.prefix,
 | 
			
		||||
    toastConfig.brackets ?? config.defaultToastConfig.brackets,
 | 
			
		||||
    toastConfig.bracketColor ?? config.defaultToastConfig.bracketColor,
 | 
			
		||||
    undefined,
 | 
			
		||||
@@ -74,9 +63,15 @@ function sendToast(
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function sendWarn(player: string) {
 | 
			
		||||
function sendWarnAndNotice(player: string) {
 | 
			
		||||
  const playerPos = playerDetector.getPlayerPos(player);
 | 
			
		||||
  const onlinePlayers = playerDetector.getOnlinePlayers();
 | 
			
		||||
  warnTargetPlayers = config.adminGroupConfig.groupUsers.concat(
 | 
			
		||||
    config.usersGroups
 | 
			
		||||
      .filter((value) => value.isNotice)
 | 
			
		||||
      .map((value) => value.groupUsers ?? [])
 | 
			
		||||
      .flat(),
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const warnMsg = `Not Allowed Player ${player} Break in Home at Position ${playerPos?.x}, ${playerPos?.y}, ${playerPos?.z}`;
 | 
			
		||||
  log.warn(warnMsg);
 | 
			
		||||
@@ -108,43 +103,11 @@ function sendWarn(player: string) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function sendCommandHelp(targetPlayer: string) {
 | 
			
		||||
  chatBox.sendMessageToPlayer(
 | 
			
		||||
    `
 | 
			
		||||
      Command Usage: @AC /<Command> [args]
 | 
			
		||||
      Command:
 | 
			
		||||
        - add <userGroup> <playerName>
 | 
			
		||||
            add player to group
 | 
			
		||||
            userGroup: ${groupNames.join(", ")}
 | 
			
		||||
        - del <userGroup> <playerName>
 | 
			
		||||
            delete player in the group, except Admin
 | 
			
		||||
            userGroup: ${groupNames.join(", ")}
 | 
			
		||||
        - list
 | 
			
		||||
            list all of the player with its group
 | 
			
		||||
        - set <options> [params]
 | 
			
		||||
            config access control settins
 | 
			
		||||
            options:
 | 
			
		||||
              - warnInterval <number>
 | 
			
		||||
                  set the interval of warn, which is not allowed
 | 
			
		||||
              - detectInterval <number>
 | 
			
		||||
                  set the interval of detecting players
 | 
			
		||||
              - detectRange <number>
 | 
			
		||||
                  set the sphere range of detect
 | 
			
		||||
    `,
 | 
			
		||||
    targetPlayer,
 | 
			
		||||
    "AccessControl",
 | 
			
		||||
    "[]",
 | 
			
		||||
    undefined,
 | 
			
		||||
    undefined,
 | 
			
		||||
    true,
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function warnLoop() {
 | 
			
		||||
  while (true) {
 | 
			
		||||
    for (const player of notAllowedPlayers) {
 | 
			
		||||
      if (inRangePlayers.includes(player)) {
 | 
			
		||||
        sendWarn(player);
 | 
			
		||||
        // sendWarnAndNotice(player);
 | 
			
		||||
      } else {
 | 
			
		||||
        notAllowedPlayers = notAllowedPlayers.filter(
 | 
			
		||||
          (value) => value != player,
 | 
			
		||||
@@ -183,7 +146,7 @@ function mainLoop() {
 | 
			
		||||
        if (!userGroupConfig.groupUsers.includes(player)) continue;
 | 
			
		||||
 | 
			
		||||
        if (!userGroupConfig.isAllowed) {
 | 
			
		||||
          sendWarn(player);
 | 
			
		||||
          sendWarnAndNotice(player);
 | 
			
		||||
          notAllowedPlayers.push(player);
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
@@ -199,7 +162,7 @@ function mainLoop() {
 | 
			
		||||
      }
 | 
			
		||||
      if (inUserGroup) continue;
 | 
			
		||||
 | 
			
		||||
      sendWarn(player);
 | 
			
		||||
      sendWarnAndNotice(player);
 | 
			
		||||
      notAllowedPlayers.push(player);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -208,132 +171,25 @@ function mainLoop() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function configLoop() {
 | 
			
		||||
  while (true) {
 | 
			
		||||
    const ev = pullEventAs(ChatBoxEvent, "chat");
 | 
			
		||||
 | 
			
		||||
    if (ev == undefined) continue;
 | 
			
		||||
    if (!config.adminGroupConfig.groupUsers.includes(ev.username)) continue;
 | 
			
		||||
    if (!ev.message.startsWith("@AC")) continue;
 | 
			
		||||
    // log.info(`Received "${ev.message}" from admin ${ev.username}`);
 | 
			
		||||
 | 
			
		||||
    const params = ev.message.split(" ");
 | 
			
		||||
    if (params.length < 2) {
 | 
			
		||||
      sendCommandHelp(ev.username);
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (params[1] == "/add" && params.length == 4) {
 | 
			
		||||
      if (params[2] == "admin") {
 | 
			
		||||
        config.adminGroupConfig.groupUsers.push(params[3]);
 | 
			
		||||
        chatBox.sendMessageToPlayer(
 | 
			
		||||
          `Add player ${params[3]} to admin`,
 | 
			
		||||
          ev.username,
 | 
			
		||||
          "AccessControl",
 | 
			
		||||
        );
 | 
			
		||||
      } else if (groupNames.includes(params[2])) {
 | 
			
		||||
        const groupConfig = config.usersGroups.find(
 | 
			
		||||
          (value) => value.groupName == params[2],
 | 
			
		||||
        )!;
 | 
			
		||||
 | 
			
		||||
        if (groupConfig.groupUsers == undefined)
 | 
			
		||||
          groupConfig.groupUsers = [params[3]];
 | 
			
		||||
        else groupConfig.groupUsers.push(params[3]);
 | 
			
		||||
 | 
			
		||||
        chatBox.sendMessageToPlayer(
 | 
			
		||||
          `Add player ${params[3]} to ${groupConfig.groupName}`,
 | 
			
		||||
          ev.username,
 | 
			
		||||
          "AccessControl",
 | 
			
		||||
        );
 | 
			
		||||
      } else {
 | 
			
		||||
        sendCommandHelp(ev.username);
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
    } else if (params[1] == "/del" && params.length == 4) {
 | 
			
		||||
      if (params[2] == "admin") {
 | 
			
		||||
        chatBox.sendMessageToPlayer(
 | 
			
		||||
          `Could't delete admin, please edit config`,
 | 
			
		||||
          ev.username,
 | 
			
		||||
          "AccessControl",
 | 
			
		||||
        );
 | 
			
		||||
      } else if (groupNames.includes(params[2])) {
 | 
			
		||||
        const groupConfig = config.usersGroups.find(
 | 
			
		||||
          (value) => value.groupName == params[2],
 | 
			
		||||
        )!;
 | 
			
		||||
 | 
			
		||||
        if (groupConfig.groupUsers == undefined) groupConfig.groupUsers = [];
 | 
			
		||||
        else
 | 
			
		||||
          groupConfig.groupUsers = groupConfig.groupUsers.filter(
 | 
			
		||||
            (user) => user != params[3],
 | 
			
		||||
          );
 | 
			
		||||
 | 
			
		||||
        chatBox.sendMessageToPlayer(
 | 
			
		||||
          `Delete ${groupConfig.groupName} ${params[3]}`,
 | 
			
		||||
          ev.username,
 | 
			
		||||
          "AccessControl",
 | 
			
		||||
        );
 | 
			
		||||
      } else {
 | 
			
		||||
        sendCommandHelp(ev.username);
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
    } else if (params[1] == "/list") {
 | 
			
		||||
      chatBox.sendMessageToPlayer(
 | 
			
		||||
        `Admins : [ ${config.adminGroupConfig.groupUsers.join(", ")} ]`,
 | 
			
		||||
        ev.username,
 | 
			
		||||
        "AccessControl",
 | 
			
		||||
      );
 | 
			
		||||
      for (const groupConfig of config.usersGroups) {
 | 
			
		||||
        chatBox.sendMessageToPlayer(
 | 
			
		||||
          `${groupConfig.groupName} : [ ${config.adminGroupConfig.groupUsers.join(", ")} ]`,
 | 
			
		||||
          ev.username,
 | 
			
		||||
          "AccessControl",
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    } else if (params[1] == "/set" && params.length == 4) {
 | 
			
		||||
      if (params[2] == "warnInterval") {
 | 
			
		||||
        config.warnInterval = parseInt(params[3]);
 | 
			
		||||
        chatBox.sendMessageToPlayer(
 | 
			
		||||
          `Set warn interval to ${config.warnInterval}`,
 | 
			
		||||
          ev.username,
 | 
			
		||||
          "AccessControl",
 | 
			
		||||
        );
 | 
			
		||||
      } else if (params[2] == "detectInterval") {
 | 
			
		||||
        config.detectInterval = parseInt(params[3]);
 | 
			
		||||
        chatBox.sendMessageToPlayer(
 | 
			
		||||
          `Set detect interval to ${config.detectInterval}`,
 | 
			
		||||
          ev.username,
 | 
			
		||||
          "AccessControl",
 | 
			
		||||
        );
 | 
			
		||||
      } else if (params[2] == "detectRange") {
 | 
			
		||||
        config.detectRange = parseInt(params[3]);
 | 
			
		||||
        chatBox.sendMessageToPlayer(
 | 
			
		||||
          `Set detect range to ${config.detectRange}`,
 | 
			
		||||
          ev.username,
 | 
			
		||||
          "AccessControl",
 | 
			
		||||
        );
 | 
			
		||||
      } else {
 | 
			
		||||
        sendCommandHelp(ev.username);
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      sendCommandHelp(ev.username);
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    saveConfig(config, configFilepath);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function main(args: string[]) {
 | 
			
		||||
  log.debug("Starting access control system, get args: " + args.join(", "));
 | 
			
		||||
  log.info("Starting access control system, get args: " + args.join(", "));
 | 
			
		||||
  if (args.length == 1) {
 | 
			
		||||
    if (args[0] == "start") {
 | 
			
		||||
      // 创建CLI处理器
 | 
			
		||||
      const cli = createAccessControlCLI(
 | 
			
		||||
        config,
 | 
			
		||||
        configFilepath,
 | 
			
		||||
        log,
 | 
			
		||||
        chatBox,
 | 
			
		||||
        groupNames,
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      parallel.waitForAll(
 | 
			
		||||
        () => {
 | 
			
		||||
          mainLoop();
 | 
			
		||||
        },
 | 
			
		||||
        () => {
 | 
			
		||||
          configLoop();
 | 
			
		||||
          void cli.startConfigLoop();
 | 
			
		||||
        },
 | 
			
		||||
        () => {
 | 
			
		||||
          warnLoop();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								src/lib/common.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/lib/common.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
export function parseBoolean(obj: string): boolean | undefined {
 | 
			
		||||
  const str = obj.toLowerCase();
 | 
			
		||||
  if (str === "true") return true;
 | 
			
		||||
  else if (str === "false") return false;
 | 
			
		||||
  else return undefined;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user