mirror of
https://github.com/SikongJueluo/cc-utils.git
synced 2025-11-04 19:27:50 +08:00
fix: wrong type, chat manager unicode string; feature: accesscontrol welcome message and chinese support
This commit is contained in:
@@ -14,7 +14,9 @@ export interface AppContext {
|
|||||||
configFilepath: string;
|
configFilepath: string;
|
||||||
reloadConfig: () => void;
|
reloadConfig: () => void;
|
||||||
logger: CCLog;
|
logger: CCLog;
|
||||||
print: (message: string) => void;
|
print: (
|
||||||
|
message: string | MinecraftTextComponent | MinecraftTextComponent[],
|
||||||
|
) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGroupNames(config: AccessConfig) {
|
function getGroupNames(config: AccessConfig) {
|
||||||
@@ -25,14 +27,14 @@ function getGroupNames(config: AccessConfig) {
|
|||||||
|
|
||||||
const addCommand: Command<AppContext> = {
|
const addCommand: Command<AppContext> = {
|
||||||
name: "add",
|
name: "add",
|
||||||
description: "Add player to group",
|
description: "添加玩家到用户组",
|
||||||
args: [
|
args: [
|
||||||
{
|
{
|
||||||
name: "userGroup",
|
name: "userGroup",
|
||||||
description: "Group to add player to",
|
description: "要添加到的用户组",
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{ name: "playerName", description: "Player to add", required: true },
|
{ name: "playerName", description: "要添加的玩家", required: true },
|
||||||
],
|
],
|
||||||
action: ({ args, context }) => {
|
action: ({ args, context }) => {
|
||||||
const [groupName, playerName] = [
|
const [groupName, playerName] = [
|
||||||
@@ -49,9 +51,11 @@ const addCommand: Command<AppContext> = {
|
|||||||
const group = config.usersGroups.find((g) => g.groupName === groupName);
|
const group = config.usersGroups.find((g) => g.groupName === groupName);
|
||||||
if (!group) {
|
if (!group) {
|
||||||
const groupNames = getGroupNames(config);
|
const groupNames = getGroupNames(config);
|
||||||
context.print(
|
context.print({
|
||||||
`Invalid group: ${groupName}. Available groups: ${groupNames.join(", ")}`,
|
text: `无效的用户组: ${groupName}. 可用用户组: ${groupNames.join(
|
||||||
);
|
", ",
|
||||||
|
)}`,
|
||||||
|
});
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
}
|
}
|
||||||
group.groupUsers ??= [];
|
group.groupUsers ??= [];
|
||||||
@@ -62,21 +66,21 @@ const addCommand: Command<AppContext> = {
|
|||||||
|
|
||||||
saveConfig(config, context.configFilepath);
|
saveConfig(config, context.configFilepath);
|
||||||
context.reloadConfig();
|
context.reloadConfig();
|
||||||
context.print(`Added player ${playerName} to ${groupName}`);
|
context.print({ text: `已添加玩家 ${playerName} 到 ${groupName}` });
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const delCommand: Command<AppContext> = {
|
const delCommand: Command<AppContext> = {
|
||||||
name: "del",
|
name: "del",
|
||||||
description: "Delete player from group",
|
description: "从用户组删除玩家",
|
||||||
args: [
|
args: [
|
||||||
{
|
{
|
||||||
name: "userGroup",
|
name: "userGroup",
|
||||||
description: "Group to delete player from",
|
description: "要从中删除玩家的用户组",
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{ name: "playerName", description: "Player to delete", required: true },
|
{ name: "playerName", description: "要删除的玩家", required: true },
|
||||||
],
|
],
|
||||||
action: ({ args, context }) => {
|
action: ({ args, context }) => {
|
||||||
const [groupName, playerName] = [
|
const [groupName, playerName] = [
|
||||||
@@ -85,7 +89,7 @@ const delCommand: Command<AppContext> = {
|
|||||||
];
|
];
|
||||||
|
|
||||||
if (groupName === "admin") {
|
if (groupName === "admin") {
|
||||||
context.print("Could not delete admin, please edit config file.");
|
context.print({ text: "无法删除管理员, 请直接编辑配置文件。" });
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,9 +98,11 @@ const delCommand: Command<AppContext> = {
|
|||||||
|
|
||||||
if (!group) {
|
if (!group) {
|
||||||
const groupNames = getGroupNames(config);
|
const groupNames = getGroupNames(config);
|
||||||
context.print(
|
context.print({
|
||||||
`Invalid group: ${groupName}. Available groups: ${groupNames.join(", ")}`,
|
text: `无效的用户组: ${groupName}. 可用用户组: ${groupNames.join(
|
||||||
);
|
", ",
|
||||||
|
)}`,
|
||||||
|
});
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,43 +112,45 @@ const delCommand: Command<AppContext> = {
|
|||||||
|
|
||||||
saveConfig(config, context.configFilepath);
|
saveConfig(config, context.configFilepath);
|
||||||
context.reloadConfig();
|
context.reloadConfig();
|
||||||
context.print(`Deleted player ${playerName} from ${groupName}`);
|
context.print({ text: `已从 ${groupName} 中删除玩家 ${playerName}` });
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const listCommand: Command<AppContext> = {
|
const listCommand: Command<AppContext> = {
|
||||||
name: "list",
|
name: "list",
|
||||||
description: "List all players with their groups",
|
description: "列出所有玩家及其所在的用户组",
|
||||||
action: ({ context }) => {
|
action: ({ context }) => {
|
||||||
const config = loadConfig(context.configFilepath)!;
|
const config = loadConfig(context.configFilepath)!;
|
||||||
let message = `Admins : [ ${config.adminGroupConfig.groupUsers.join(", ")} ]\n`;
|
let message = `管理员 : [ ${config.adminGroupConfig.groupUsers.join(
|
||||||
|
", ",
|
||||||
|
)} ]\n`;
|
||||||
for (const groupConfig of config.usersGroups) {
|
for (const groupConfig of config.usersGroups) {
|
||||||
const users = groupConfig.groupUsers ?? [];
|
const users = groupConfig.groupUsers ?? [];
|
||||||
message += `${groupConfig.groupName} : [ ${users.join(", ")} ]\n`;
|
message += `${groupConfig.groupName} : [ ${users.join(", ")} ]\n`;
|
||||||
}
|
}
|
||||||
context.print(message.trim());
|
context.print({ text: message.trim() });
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const setCommand: Command<AppContext> = {
|
const setCommand: Command<AppContext> = {
|
||||||
name: "set",
|
name: "set",
|
||||||
description: "Config access control settings",
|
description: "配置访问控制设置",
|
||||||
args: [
|
args: [
|
||||||
{
|
{
|
||||||
name: "option",
|
name: "option",
|
||||||
description: "Option to set (warnInterval, detectInterval, detectRange)",
|
description: "要设置的选项 (warnInterval, detectInterval, detectRange)",
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{ name: "value", description: "Value to set", required: true },
|
{ name: "value", description: "要设置的值", required: true },
|
||||||
],
|
],
|
||||||
action: ({ args, context }) => {
|
action: ({ args, context }) => {
|
||||||
const [option, valueStr] = [args.option as string, args.value as string];
|
const [option, valueStr] = [args.option as string, args.value as string];
|
||||||
const value = parseInt(valueStr);
|
const value = parseInt(valueStr);
|
||||||
|
|
||||||
if (isNaN(value)) {
|
if (isNaN(value)) {
|
||||||
context.print(`Invalid value: ${valueStr}. Must be a number.`);
|
context.print({ text: `无效的值: ${valueStr}. 必须是一个数字。` });
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,45 +160,45 @@ const setCommand: Command<AppContext> = {
|
|||||||
switch (option) {
|
switch (option) {
|
||||||
case "warnInterval":
|
case "warnInterval":
|
||||||
config.watchInterval = value;
|
config.watchInterval = value;
|
||||||
message = `Set warn interval to ${value}`;
|
message = `已设置警告间隔为 ${value}`;
|
||||||
break;
|
break;
|
||||||
case "detectInterval":
|
case "detectInterval":
|
||||||
config.detectInterval = value;
|
config.detectInterval = value;
|
||||||
message = `Set detect interval to ${value}`;
|
message = `已设置检测间隔为 ${value}`;
|
||||||
break;
|
break;
|
||||||
case "detectRange":
|
case "detectRange":
|
||||||
config.detectRange = value;
|
config.detectRange = value;
|
||||||
message = `Set detect range to ${value}`;
|
message = `已设置检测范围为 ${value}`;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
context.print(
|
context.print({
|
||||||
`Unknown option: ${option}. Available: warnInterval, detectInterval, detectRange`,
|
text: `未知选项: ${option}. 可用选项: warnInterval, detectInterval, detectRange`,
|
||||||
);
|
});
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveConfig(config, context.configFilepath);
|
saveConfig(config, context.configFilepath);
|
||||||
context.reloadConfig();
|
context.reloadConfig();
|
||||||
context.print(message);
|
context.print({ text: message });
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const editGroupCommand: Command<AppContext> = {
|
const editGroupCommand: Command<AppContext> = {
|
||||||
name: "group",
|
name: "group",
|
||||||
description: "Edit group properties",
|
description: "编辑用户组属性",
|
||||||
args: [
|
args: [
|
||||||
{
|
{
|
||||||
name: "groupName",
|
name: "groupName",
|
||||||
description: "Name of the group to edit",
|
description: "要编辑的用户组名称",
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "property",
|
name: "property",
|
||||||
description: "Property to change (isAllowed, isNotice)",
|
description: "要更改的属性 (isAllowed, isNotice)",
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{ name: "value", description: "New value (true/false)", required: true },
|
{ name: "value", description: "新值 (true/false)", required: true },
|
||||||
],
|
],
|
||||||
action: ({ args, context }) => {
|
action: ({ args, context }) => {
|
||||||
const [groupName, property, valueStr] = [
|
const [groupName, property, valueStr] = [
|
||||||
@@ -208,15 +216,15 @@ const editGroupCommand: Command<AppContext> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!groupConfig) {
|
if (!groupConfig) {
|
||||||
context.print(`Group ${groupName} not found`);
|
context.print({ text: `用户组 ${groupName} 未找到` });
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
const boolValue = parseBoolean(valueStr);
|
const boolValue = parseBoolean(valueStr);
|
||||||
if (boolValue === undefined) {
|
if (boolValue === undefined) {
|
||||||
context.print(
|
context.print({
|
||||||
`Invalid boolean value: ${valueStr}. Use 'true' or 'false'.`,
|
text: `无效的布尔值: ${valueStr}. 请使用 'true' 或 'false'.`,
|
||||||
);
|
});
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,63 +232,65 @@ const editGroupCommand: Command<AppContext> = {
|
|||||||
switch (property) {
|
switch (property) {
|
||||||
case "isAllowed":
|
case "isAllowed":
|
||||||
groupConfig.isAllowed = boolValue;
|
groupConfig.isAllowed = boolValue;
|
||||||
message = `Set ${groupName}.isAllowed to ${boolValue}`;
|
message = `已设置 ${groupName}.isAllowed 为 ${boolValue}`;
|
||||||
break;
|
break;
|
||||||
case "isNotice":
|
case "isNotice":
|
||||||
groupConfig.isNotice = boolValue;
|
groupConfig.isNotice = boolValue;
|
||||||
message = `Set ${groupName}.isNotice to ${boolValue}`;
|
message = `已设置 ${groupName}.isNotice 为 ${boolValue}`;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
context.print(
|
context.print({
|
||||||
`Unknown property: ${property}. Available: isAllowed, isNotice`,
|
text: `未知属性: ${property}. 可用属性: isAllowed, isNotice`,
|
||||||
);
|
});
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveConfig(config, context.configFilepath);
|
saveConfig(config, context.configFilepath);
|
||||||
context.reloadConfig();
|
context.reloadConfig();
|
||||||
context.print(message);
|
context.print({ text: message });
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const editCommand: Command<AppContext> = {
|
const editCommand: Command<AppContext> = {
|
||||||
name: "edit",
|
name: "edit",
|
||||||
description: "Edit various configurations",
|
description: "编辑各项配置",
|
||||||
subcommands: new Map([["group", editGroupCommand]]),
|
subcommands: new Map([["group", editGroupCommand]]),
|
||||||
};
|
};
|
||||||
|
|
||||||
const showConfigCommand: Command<AppContext> = {
|
const showConfigCommand: Command<AppContext> = {
|
||||||
name: "showconfig",
|
name: "showconfig",
|
||||||
description: "Show configuration",
|
description: "显示配置",
|
||||||
options: new Map([
|
options: new Map([
|
||||||
[
|
[
|
||||||
"type",
|
"type",
|
||||||
{
|
{
|
||||||
name: "type",
|
name: "type",
|
||||||
description: "Type of config to show (groups, toast, all)",
|
description: "要显示的配置类型 (groups, toast, all)",
|
||||||
required: false,
|
required: false,
|
||||||
defaultValue: "all",
|
defaultValue: "all",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
action: ({ args, context }) => {
|
action: ({ options, context }) => {
|
||||||
const type = args.type as string;
|
const type = options.type as string;
|
||||||
const config = loadConfig(context.configFilepath)!;
|
const config = loadConfig(context.configFilepath)!;
|
||||||
let message = "";
|
let message = "";
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "groups": {
|
case "groups": {
|
||||||
let groupsMessage = `Admin Group: ${config.adminGroupConfig.groupName}\n`;
|
let groupsMessage = `管理员组: ${config.adminGroupConfig.groupName}\n`;
|
||||||
groupsMessage += ` Users: [${config.adminGroupConfig.groupUsers.join(", ")}]\n`;
|
groupsMessage += ` 用户: [${config.adminGroupConfig.groupUsers.join(
|
||||||
groupsMessage += ` Allowed: ${config.adminGroupConfig.isAllowed}\n`;
|
", ",
|
||||||
groupsMessage += ` notice: ${config.adminGroupConfig.isNotice}\n\n`;
|
)}]\n`;
|
||||||
|
groupsMessage += ` 允许: ${config.adminGroupConfig.isAllowed}\n`;
|
||||||
|
groupsMessage += ` 通知: ${config.adminGroupConfig.isNotice}\n\n`;
|
||||||
|
|
||||||
for (const group of config.usersGroups) {
|
for (const group of config.usersGroups) {
|
||||||
groupsMessage += `Group: ${group.groupName}\n`;
|
groupsMessage += `用户组: ${group.groupName}\n`;
|
||||||
groupsMessage += ` Users: [${(group.groupUsers ?? []).join(", ")}]\n`;
|
groupsMessage += ` 用户: [${(group.groupUsers ?? []).join(", ")}]\n`;
|
||||||
groupsMessage += ` Allowed: ${group.isAllowed}\n`;
|
groupsMessage += ` 允许: ${group.isAllowed}\n`;
|
||||||
groupsMessage += ` Notice: ${group.isNotice}\n`;
|
groupsMessage += ` 通知: ${group.isNotice}\n`;
|
||||||
groupsMessage += "\n";
|
groupsMessage += "\n";
|
||||||
}
|
}
|
||||||
message = groupsMessage.trim();
|
message = groupsMessage.trim();
|
||||||
@@ -288,38 +298,48 @@ const showConfigCommand: Command<AppContext> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "toast": {
|
case "toast": {
|
||||||
let toastMessage = "Default Toast Config:\n";
|
let toastMessage = "默认 Toast 配置:\n";
|
||||||
toastMessage += ` Title: ${config.welcomeToastConfig.title.text}\n`;
|
toastMessage += ` 标题: ${config.welcomeToastConfig.title.text}\n`;
|
||||||
toastMessage += ` Message: ${config.welcomeToastConfig.msg.text}\n`;
|
toastMessage += ` 消息: ${config.welcomeToastConfig.msg.text}\n`;
|
||||||
toastMessage += ` Prefix: ${config.welcomeToastConfig.prefix ?? "none"}\n`;
|
toastMessage += ` 前缀: ${
|
||||||
toastMessage += ` Brackets: ${config.welcomeToastConfig.brackets ?? "none"}\n`;
|
config.welcomeToastConfig.prefix ?? "none"
|
||||||
toastMessage += ` Bracket Color: ${config.welcomeToastConfig.bracketColor ?? "none"}\n\n`;
|
}\n`;
|
||||||
|
toastMessage += ` 括号: ${
|
||||||
|
config.welcomeToastConfig.brackets ?? "none"
|
||||||
|
}\n`;
|
||||||
|
toastMessage += ` 括号颜色: ${
|
||||||
|
config.welcomeToastConfig.bracketColor ?? "none"
|
||||||
|
}\n\n`;
|
||||||
|
|
||||||
toastMessage += "Warn Toast Config:\n";
|
toastMessage += "警告 Toast 配置:\n";
|
||||||
toastMessage += ` Title: ${config.warnToastConfig.title.text}\n`;
|
toastMessage += ` 标题: ${config.warnToastConfig.title.text}\n`;
|
||||||
toastMessage += ` Message: ${config.warnToastConfig.msg.text}\n`;
|
toastMessage += ` 消息: ${config.warnToastConfig.msg.text}\n`;
|
||||||
toastMessage += ` Prefix: ${config.warnToastConfig.prefix ?? "none"}\n`;
|
toastMessage += ` 前缀: ${config.warnToastConfig.prefix ?? "none"}\n`;
|
||||||
toastMessage += ` Brackets: ${config.warnToastConfig.brackets ?? "none"}\n`;
|
toastMessage += ` 括号: ${
|
||||||
toastMessage += ` Bracket Color: ${config.warnToastConfig.bracketColor ?? "none"}`;
|
config.warnToastConfig.brackets ?? "none"
|
||||||
|
}\n`;
|
||||||
|
toastMessage += ` 括号颜色: ${
|
||||||
|
config.warnToastConfig.bracketColor ?? "none"
|
||||||
|
}`;
|
||||||
message = toastMessage;
|
message = toastMessage;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "all": {
|
case "all": {
|
||||||
let allMessage = `Detect Range: ${config.detectRange}\n`;
|
let allMessage = `检测范围: ${config.detectRange}\n`;
|
||||||
allMessage += `Detect Interval: ${config.detectInterval}\n`;
|
allMessage += `检测间隔: ${config.detectInterval}\n`;
|
||||||
allMessage += `Warn Interval: ${config.watchInterval}\n\n`;
|
allMessage += `警告间隔: ${config.watchInterval}\n\n`;
|
||||||
allMessage +=
|
allMessage +=
|
||||||
"Use 'showconfig groups' or 'showconfig toast' for detailed view";
|
"使用 'showconfig --type groups' 或 'showconfig --type toast' 查看详细信息";
|
||||||
message = allMessage;
|
message = allMessage;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
message = `Invalid type: ${type}. Available: groups, toast, all`;
|
message = `无效类型: ${type}. 可用类型: groups, toast, all`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
context.print(message);
|
context.print({ text: message });
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -327,7 +347,7 @@ const showConfigCommand: Command<AppContext> = {
|
|||||||
// Root command
|
// Root command
|
||||||
const rootCommand: Command<AppContext> = {
|
const rootCommand: Command<AppContext> = {
|
||||||
name: "@AC",
|
name: "@AC",
|
||||||
description: "Access Control command line interface",
|
description: "访问控制命令行界面",
|
||||||
subcommands: new Map([
|
subcommands: new Map([
|
||||||
["add", addCommand],
|
["add", addCommand],
|
||||||
["del", delCommand],
|
["del", delCommand],
|
||||||
@@ -337,7 +357,25 @@ const rootCommand: Command<AppContext> = {
|
|||||||
["showconfig", showConfigCommand],
|
["showconfig", showConfigCommand],
|
||||||
]),
|
]),
|
||||||
action: ({ context }) => {
|
action: ({ context }) => {
|
||||||
context.print("Welcome to Access Control CLI");
|
context.print([
|
||||||
|
{
|
||||||
|
text: "请使用 ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "@AC --help",
|
||||||
|
clickEvent: {
|
||||||
|
action: "copy_to_clipboard",
|
||||||
|
value: "@AC --help",
|
||||||
|
},
|
||||||
|
hoverEvent: {
|
||||||
|
action: "show_text",
|
||||||
|
value: "点击复制命令",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: " 获取门禁系统更详细的命令说明😊😊😊",
|
||||||
|
},
|
||||||
|
]);
|
||||||
return Ok.EMPTY;
|
return Ok.EMPTY;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ interface UserGroupConfig {
|
|||||||
groupName: string;
|
groupName: string;
|
||||||
isAllowed: boolean;
|
isAllowed: boolean;
|
||||||
isNotice: boolean;
|
isNotice: boolean;
|
||||||
|
isWelcome: boolean;
|
||||||
groupUsers: string[];
|
groupUsers: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +40,7 @@ const defaultConfig: AccessConfig = {
|
|||||||
groupUsers: ["Selcon"],
|
groupUsers: ["Selcon"],
|
||||||
isAllowed: true,
|
isAllowed: true,
|
||||||
isNotice: true,
|
isNotice: true,
|
||||||
|
isWelcome: true,
|
||||||
},
|
},
|
||||||
usersGroups: [
|
usersGroups: [
|
||||||
{
|
{
|
||||||
@@ -46,57 +48,60 @@ const defaultConfig: AccessConfig = {
|
|||||||
groupUsers: [],
|
groupUsers: [],
|
||||||
isAllowed: true,
|
isAllowed: true,
|
||||||
isNotice: true,
|
isNotice: true,
|
||||||
|
isWelcome: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
groupName: "VIP",
|
groupName: "VIP",
|
||||||
groupUsers: [],
|
groupUsers: [],
|
||||||
isAllowed: true,
|
isAllowed: true,
|
||||||
isNotice: false,
|
isNotice: false,
|
||||||
|
isWelcome: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
groupName: "enemies",
|
groupName: "enemies",
|
||||||
groupUsers: [],
|
groupUsers: [],
|
||||||
isAllowed: false,
|
isAllowed: false,
|
||||||
isNotice: false,
|
isNotice: false,
|
||||||
|
isWelcome: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
welcomeToastConfig: {
|
welcomeToastConfig: {
|
||||||
title: {
|
title: {
|
||||||
text: "Welcome",
|
text: "欢迎",
|
||||||
color: "green",
|
color: "green",
|
||||||
},
|
},
|
||||||
msg: {
|
msg: {
|
||||||
text: "Hello User %playerName%",
|
text: "欢迎 %playerName% 参观桃源星喵~",
|
||||||
color: "green",
|
color: "#EDC8DA",
|
||||||
},
|
},
|
||||||
prefix: "Taohuayuan",
|
prefix: "桃源星",
|
||||||
brackets: "[]",
|
brackets: "<>",
|
||||||
bracketColor: "",
|
bracketColor: "",
|
||||||
},
|
},
|
||||||
noticeToastConfig: {
|
noticeToastConfig: {
|
||||||
title: {
|
title: {
|
||||||
text: "Notice",
|
text: "警告",
|
||||||
color: "red",
|
color: "red",
|
||||||
},
|
},
|
||||||
msg: {
|
msg: {
|
||||||
text: "Unfamiliar player %playerName% appeared at Position %playerPosX%, %playerPosY%, %playerPosZ%",
|
text: "陌生玩家 %playerName% 出现在 %playerPosX%, %playerPosY%, %playerPosZ%",
|
||||||
color: "red",
|
color: "red",
|
||||||
},
|
},
|
||||||
prefix: "Taohuayuan",
|
prefix: "桃源星",
|
||||||
brackets: "[]",
|
brackets: "<>",
|
||||||
bracketColor: "",
|
bracketColor: "",
|
||||||
},
|
},
|
||||||
warnToastConfig: {
|
warnToastConfig: {
|
||||||
title: {
|
title: {
|
||||||
text: "Attention!!!",
|
text: "注意",
|
||||||
color: "red",
|
color: "red",
|
||||||
},
|
},
|
||||||
msg: {
|
msg: {
|
||||||
text: "%playerName% you are not allowed to be here",
|
text: "%playerName% 你已经进入桃源星领地",
|
||||||
color: "red",
|
color: "red",
|
||||||
},
|
},
|
||||||
prefix: "Taohuayuan",
|
prefix: "桃源星",
|
||||||
brackets: "[]",
|
brackets: "<>",
|
||||||
bracketColor: "",
|
bracketColor: "",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { deepCopy } from "@/lib/common";
|
|||||||
import { ReadWriteLock } from "@/lib/mutex/ReadWriteLock";
|
import { ReadWriteLock } from "@/lib/mutex/ReadWriteLock";
|
||||||
import { ChatManager } from "@/lib/ChatManager";
|
import { ChatManager } from "@/lib/ChatManager";
|
||||||
import { gTimerManager } from "@/lib/TimerManager";
|
import { gTimerManager } from "@/lib/TimerManager";
|
||||||
|
import { KeyEvent, pullEventAs } from "@/lib/event";
|
||||||
|
|
||||||
const args = [...$vararg];
|
const args = [...$vararg];
|
||||||
|
|
||||||
@@ -25,17 +26,20 @@ logger.info("Load config successfully!");
|
|||||||
logger.debug(textutils.serialise(config, { allow_repetitions: true }));
|
logger.debug(textutils.serialise(config, { allow_repetitions: true }));
|
||||||
|
|
||||||
// Peripheral
|
// Peripheral
|
||||||
const playerDetector = peripheralManager.findByNameRequired("playerDetector");
|
const playerDetector = peripheral.find(
|
||||||
const chatBox = peripheralManager.findByNameRequired("chatBox");
|
"playerDetector",
|
||||||
|
)[0] as PlayerDetectorPeripheral;
|
||||||
|
const chatBox = peripheral.find("chatBox")[0] as ChatBoxPeripheral;
|
||||||
const chatManager: ChatManager = new ChatManager([chatBox]);
|
const chatManager: ChatManager = new ChatManager([chatBox]);
|
||||||
|
|
||||||
// Global
|
// Global
|
||||||
let inRangePlayers: string[] = [];
|
let gInRangePlayers: string[] = [];
|
||||||
let watchPlayersInfo: { name: string; hasNoticeTimes: number }[] = [];
|
let gWatchPlayersInfo: { name: string; hasNoticeTimes: number }[] = [];
|
||||||
|
let gIsRunning = true;
|
||||||
|
|
||||||
interface ParseParams {
|
interface ParseParams {
|
||||||
name?: string;
|
playerName?: string;
|
||||||
group?: string;
|
groupName?: string;
|
||||||
info?: PlayerInfo;
|
info?: PlayerInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,8 +51,8 @@ function reloadConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
config = loadConfig(configFilepath)!;
|
config = loadConfig(configFilepath)!;
|
||||||
inRangePlayers = [];
|
gInRangePlayers = [];
|
||||||
watchPlayersInfo = [];
|
gWatchPlayersInfo = [];
|
||||||
releaser.release();
|
releaser.release();
|
||||||
logger.info("Reload config successfully!");
|
logger.info("Reload config successfully!");
|
||||||
}
|
}
|
||||||
@@ -56,7 +60,7 @@ function reloadConfig() {
|
|||||||
function safeParseTextComponent(
|
function safeParseTextComponent(
|
||||||
component: MinecraftTextComponent,
|
component: MinecraftTextComponent,
|
||||||
params?: ParseParams,
|
params?: ParseParams,
|
||||||
): string {
|
): MinecraftTextComponent {
|
||||||
const newComponent = deepCopy(component);
|
const newComponent = deepCopy(component);
|
||||||
|
|
||||||
if (newComponent.text == undefined) {
|
if (newComponent.text == undefined) {
|
||||||
@@ -64,11 +68,11 @@ function safeParseTextComponent(
|
|||||||
} else if (newComponent.text.includes("%")) {
|
} else if (newComponent.text.includes("%")) {
|
||||||
newComponent.text = newComponent.text.replace(
|
newComponent.text = newComponent.text.replace(
|
||||||
"%playerName%",
|
"%playerName%",
|
||||||
params?.name ?? "UnknowPlayer",
|
params?.playerName ?? "UnknowPlayer",
|
||||||
);
|
);
|
||||||
newComponent.text = newComponent.text.replace(
|
newComponent.text = newComponent.text.replace(
|
||||||
"%groupName%",
|
"%groupName%",
|
||||||
params?.group ?? "UnknowGroup",
|
params?.groupName ?? "UnknowGroup",
|
||||||
);
|
);
|
||||||
newComponent.text = newComponent.text.replace(
|
newComponent.text = newComponent.text.replace(
|
||||||
"%playerPosX%",
|
"%playerPosX%",
|
||||||
@@ -83,7 +87,34 @@ function safeParseTextComponent(
|
|||||||
params?.info?.z.toString() ?? "UnknowPosZ",
|
params?.info?.z.toString() ?? "UnknowPosZ",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return textutils.serialiseJSON(newComponent);
|
return newComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendMessage(
|
||||||
|
toastConfig: ToastConfig,
|
||||||
|
targetPlayer: string,
|
||||||
|
params: ParseParams,
|
||||||
|
) {
|
||||||
|
let releaser = configLock.tryAcquireRead();
|
||||||
|
while (releaser === undefined) {
|
||||||
|
sleep(0.1);
|
||||||
|
releaser = configLock.tryAcquireRead();
|
||||||
|
}
|
||||||
|
|
||||||
|
chatManager.sendMessage({
|
||||||
|
message: safeParseTextComponent(
|
||||||
|
toastConfig.msg ?? config.welcomeToastConfig.msg,
|
||||||
|
params,
|
||||||
|
),
|
||||||
|
prefix: toastConfig.prefix ?? config.welcomeToastConfig.prefix,
|
||||||
|
brackets: toastConfig.brackets ?? config.welcomeToastConfig.brackets,
|
||||||
|
bracketColor:
|
||||||
|
toastConfig.bracketColor ?? config.welcomeToastConfig.bracketColor,
|
||||||
|
targetPlayer: targetPlayer,
|
||||||
|
utf8Support: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
releaser.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendToast(
|
function sendToast(
|
||||||
@@ -134,7 +165,7 @@ function sendNotice(player: string, playerInfo?: PlayerInfo) {
|
|||||||
for (const targetPlayer of noticeTargetPlayers) {
|
for (const targetPlayer of noticeTargetPlayers) {
|
||||||
if (!onlinePlayers.includes(targetPlayer)) continue;
|
if (!onlinePlayers.includes(targetPlayer)) continue;
|
||||||
sendToast(config.noticeToastConfig, targetPlayer, {
|
sendToast(config.noticeToastConfig, targetPlayer, {
|
||||||
name: player,
|
playerName: player,
|
||||||
info: playerInfo,
|
info: playerInfo,
|
||||||
});
|
});
|
||||||
sleep(1);
|
sleep(1);
|
||||||
@@ -152,10 +183,10 @@ function sendWarn(player: string) {
|
|||||||
releaser = configLock.tryAcquireRead();
|
releaser = configLock.tryAcquireRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
sendToast(config.warnToastConfig, player, { name: player });
|
sendToast(config.warnToastConfig, player, { playerName: player });
|
||||||
chatManager.sendMessage({
|
chatManager.sendMessage({
|
||||||
message: safeParseTextComponent(config.warnToastConfig.msg, {
|
message: safeParseTextComponent(config.warnToastConfig.msg, {
|
||||||
name: player,
|
playerName: player,
|
||||||
}),
|
}),
|
||||||
targetPlayer: player,
|
targetPlayer: player,
|
||||||
prefix: "AccessControl",
|
prefix: "AccessControl",
|
||||||
@@ -166,18 +197,18 @@ function sendWarn(player: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function watchLoop() {
|
function watchLoop() {
|
||||||
while (true) {
|
while (gIsRunning) {
|
||||||
const releaser = configLock.tryAcquireRead();
|
const releaser = configLock.tryAcquireRead();
|
||||||
if (releaser === undefined) {
|
if (releaser === undefined) {
|
||||||
os.sleep(1);
|
os.sleep(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const watchPlayerNames = watchPlayersInfo.flatMap((value) => value.name);
|
const watchPlayerNames = gWatchPlayersInfo.flatMap((value) => value.name);
|
||||||
logger.debug(`Watch Players [ ${watchPlayerNames.join(", ")} ]`);
|
logger.debug(`Watch Players [ ${watchPlayerNames.join(", ")} ]`);
|
||||||
for (const player of watchPlayersInfo) {
|
for (const player of gWatchPlayersInfo) {
|
||||||
const playerInfo = playerDetector.getPlayerPos(player.name);
|
const playerInfo = playerDetector.getPlayerPos(player.name);
|
||||||
if (inRangePlayers.includes(player.name)) {
|
if (gInRangePlayers.includes(player.name)) {
|
||||||
// Notice
|
// Notice
|
||||||
if (player.hasNoticeTimes < config.noticeTimes) {
|
if (player.hasNoticeTimes < config.noticeTimes) {
|
||||||
sendNotice(player.name, playerInfo);
|
sendNotice(player.name, playerInfo);
|
||||||
@@ -193,7 +224,7 @@ function watchLoop() {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Get rid of player from list
|
// Get rid of player from list
|
||||||
watchPlayersInfo = watchPlayersInfo.filter(
|
gWatchPlayersInfo = gWatchPlayersInfo.filter(
|
||||||
(value) => value.name != player.name,
|
(value) => value.name != player.name,
|
||||||
);
|
);
|
||||||
logger.info(
|
logger.info(
|
||||||
@@ -209,7 +240,7 @@ function watchLoop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mainLoop() {
|
function mainLoop() {
|
||||||
while (true) {
|
while (gIsRunning) {
|
||||||
const releaser = configLock.tryAcquireRead();
|
const releaser = configLock.tryAcquireRead();
|
||||||
if (releaser === undefined) {
|
if (releaser === undefined) {
|
||||||
os.sleep(0.1);
|
os.sleep(0.1);
|
||||||
@@ -221,20 +252,31 @@ function mainLoop() {
|
|||||||
logger.debug(`Detected ${players.length} players: ${playersList}`);
|
logger.debug(`Detected ${players.length} players: ${playersList}`);
|
||||||
|
|
||||||
for (const player of players) {
|
for (const player of players) {
|
||||||
if (inRangePlayers.includes(player)) continue;
|
if (gInRangePlayers.includes(player)) continue;
|
||||||
|
|
||||||
|
// Get player Info
|
||||||
|
const playerInfo = playerDetector.getPlayerPos(player);
|
||||||
|
|
||||||
if (config.adminGroupConfig.groupUsers.includes(player)) {
|
if (config.adminGroupConfig.groupUsers.includes(player)) {
|
||||||
logger.info(`Admin ${player} appear`);
|
logger.info(
|
||||||
|
`Admin ${player} appear at ${playerInfo?.x}, ${playerInfo?.y}, ${playerInfo?.z}`,
|
||||||
|
);
|
||||||
|
if (config.adminGroupConfig.isWelcome)
|
||||||
|
sendMessage(config.welcomeToastConfig, player, {
|
||||||
|
playerName: player,
|
||||||
|
groupName: "Admin",
|
||||||
|
info: playerInfo,
|
||||||
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// New player appear
|
// New player appear
|
||||||
const playerInfo = playerDetector.getPlayerPos(player);
|
|
||||||
let groupConfig: UserGroupConfig = {
|
let groupConfig: UserGroupConfig = {
|
||||||
groupName: "Unfamiliar",
|
groupName: "Unfamiliar",
|
||||||
groupUsers: [],
|
groupUsers: [],
|
||||||
isAllowed: false,
|
isAllowed: false,
|
||||||
isNotice: false,
|
isNotice: false,
|
||||||
|
isWelcome: false,
|
||||||
};
|
};
|
||||||
for (const userGroupConfig of config.usersGroups) {
|
for (const userGroupConfig of config.usersGroups) {
|
||||||
if (userGroupConfig.groupUsers == undefined) continue;
|
if (userGroupConfig.groupUsers == undefined) continue;
|
||||||
@@ -247,28 +289,37 @@ function mainLoop() {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.adminGroupConfig.isWelcome)
|
||||||
|
sendMessage(config.welcomeToastConfig, player, {
|
||||||
|
playerName: player,
|
||||||
|
groupName: groupConfig.groupName,
|
||||||
|
info: playerInfo,
|
||||||
|
});
|
||||||
if (groupConfig.isAllowed) continue;
|
if (groupConfig.isAllowed) continue;
|
||||||
|
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`${groupConfig.groupName} ${player} appear at ${playerInfo?.x}, ${playerInfo?.y}, ${playerInfo?.z}`,
|
`${groupConfig.groupName} ${player} appear at ${playerInfo?.x}, ${playerInfo?.y}, ${playerInfo?.z}`,
|
||||||
);
|
);
|
||||||
if (config.isWarn) sendWarn(player);
|
if (config.isWarn) sendWarn(player);
|
||||||
watchPlayersInfo = [
|
gWatchPlayersInfo = [
|
||||||
...watchPlayersInfo,
|
...gWatchPlayersInfo,
|
||||||
{ name: player, hasNoticeTimes: 0 },
|
{ name: player, hasNoticeTimes: 0 },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
inRangePlayers = players;
|
gInRangePlayers = players;
|
||||||
releaser.release();
|
releaser.release();
|
||||||
os.sleep(config.detectInterval);
|
os.sleep(config.detectInterval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function keyboardLoop() {
|
function keyboardLoop() {
|
||||||
while (true) {
|
while (gIsRunning) {
|
||||||
const [eventType, key] = os.pullEvent("key");
|
const event = pullEventAs(KeyEvent, "key");
|
||||||
if (eventType === "key" && key === keys.c) {
|
if (event === undefined) continue;
|
||||||
|
|
||||||
|
if (event.key === keys.c) {
|
||||||
logger.info("Launching Access Control TUI...");
|
logger.info("Launching Access Control TUI...");
|
||||||
try {
|
try {
|
||||||
logger.setInTerminal(false);
|
logger.setInTerminal(false);
|
||||||
@@ -280,7 +331,12 @@ function keyboardLoop() {
|
|||||||
logger.setInTerminal(true);
|
logger.setInTerminal(true);
|
||||||
reloadConfig();
|
reloadConfig();
|
||||||
}
|
}
|
||||||
|
} else if (event.key === keys.r) {
|
||||||
|
reloadConfig();
|
||||||
}
|
}
|
||||||
|
// else if (event.key === keys.q) {
|
||||||
|
// gIsRunning = false;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,7 +356,7 @@ function cliLoop() {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
while (true) {
|
while (gIsRunning) {
|
||||||
const result = chatManager.getReceivedMessage();
|
const result = chatManager.getReceivedMessage();
|
||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
sleep(0.5);
|
sleep(0.5);
|
||||||
@@ -342,9 +398,11 @@ function main(args: string[]) {
|
|||||||
logger.info("Starting access control system, get args: " + args.join(", "));
|
logger.info("Starting access control system, get args: " + args.join(", "));
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
if (args[0] == "start") {
|
if (args[0] == "start") {
|
||||||
print(
|
const tutorial: string[] = [];
|
||||||
"Access Control System started. Press 'c' to open configuration TUI.",
|
tutorial.push("Access Control System started.");
|
||||||
);
|
tutorial.push("\tPress 'c' to open configuration TUI.");
|
||||||
|
tutorial.push("\tPress 'r' to reload configuration.");
|
||||||
|
print(tutorial.join("\n"));
|
||||||
parallel.waitForAll(
|
parallel.waitForAll(
|
||||||
() => mainLoop(),
|
() => mainLoop(),
|
||||||
() => gTimerManager.run(),
|
() => gTimerManager.run(),
|
||||||
|
|||||||
@@ -355,6 +355,34 @@ const AccessControlTUI = () => {
|
|||||||
{ class: "flex flex-col ml-2" },
|
{ class: "flex flex-col ml-2" },
|
||||||
label({}, () => `Group: ${getSelectedGroup().groupName}`),
|
label({}, () => `Group: ${getSelectedGroup().groupName}`),
|
||||||
|
|
||||||
|
div(
|
||||||
|
{ class: "flex flex-row" },
|
||||||
|
label({}, "Is Welcome:"),
|
||||||
|
input({
|
||||||
|
type: "checkbox",
|
||||||
|
checked: () => getSelectedGroup().isWelcome,
|
||||||
|
onChange: (checked) => {
|
||||||
|
const groupIndex = selectedGroupIndex();
|
||||||
|
if (groupIndex === 0) {
|
||||||
|
const currentAdmin = config().adminGroupConfig;
|
||||||
|
setConfig("adminGroupConfig", {
|
||||||
|
...currentAdmin,
|
||||||
|
isWelcome: checked,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const actualIndex = groupIndex - 1;
|
||||||
|
const currentGroups = config().usersGroups;
|
||||||
|
const currentGroup = currentGroups[actualIndex];
|
||||||
|
const newGroups = [...currentGroups];
|
||||||
|
newGroups[actualIndex] = {
|
||||||
|
...currentGroup,
|
||||||
|
isWelcome: checked,
|
||||||
|
};
|
||||||
|
setConfig("usersGroups", newGroups);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
),
|
||||||
div(
|
div(
|
||||||
{ class: "flex flex-row" },
|
{ class: "flex flex-row" },
|
||||||
label({}, "Is Allowed:"),
|
label({}, "Is Allowed:"),
|
||||||
@@ -541,7 +569,12 @@ const AccessControlTUI = () => {
|
|||||||
label({}, "Prefix:"),
|
label({}, "Prefix:"),
|
||||||
input({
|
input({
|
||||||
type: "text",
|
type: "text",
|
||||||
value: () => getTempToastConfig().prefix,
|
value: () => {
|
||||||
|
const str = textutils.serialiseJSON(getTempToastConfig().prefix, {
|
||||||
|
unicode_strings: true,
|
||||||
|
});
|
||||||
|
return str.substring(1, str.length - 1);
|
||||||
|
},
|
||||||
onInput: (value) =>
|
onInput: (value) =>
|
||||||
setTempToastConfig({ ...getTempToastConfig(), prefix: value }),
|
setTempToastConfig({ ...getTempToastConfig(), prefix: value }),
|
||||||
onFocusChanged: () => {
|
onFocusChanged: () => {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export interface ChatToast extends ChatBasicMessage {
|
|||||||
/** Target player username to send the toast to */
|
/** Target player username to send the toast to */
|
||||||
targetPlayer: string;
|
targetPlayer: string;
|
||||||
/** Title of the toast notification */
|
/** Title of the toast notification */
|
||||||
title: string;
|
title: string | MinecraftTextComponent | MinecraftTextComponent[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,9 +224,13 @@ export class ChatManager {
|
|||||||
// Send private message to specific player
|
// Send private message to specific player
|
||||||
if (typeof message.message === "string") {
|
if (typeof message.message === "string") {
|
||||||
[success, errorMsg] = chatbox.sendMessageToPlayer(
|
[success, errorMsg] = chatbox.sendMessageToPlayer(
|
||||||
message.message,
|
textutils.serialiseJSON(message.message, {
|
||||||
|
unicode_strings: message.utf8Support,
|
||||||
|
}),
|
||||||
message.targetPlayer,
|
message.targetPlayer,
|
||||||
message.prefix,
|
textutils.serialiseJSON(message.prefix ?? "AP", {
|
||||||
|
unicode_strings: message.utf8Support,
|
||||||
|
}),
|
||||||
message.brackets,
|
message.brackets,
|
||||||
message.bracketColor,
|
message.bracketColor,
|
||||||
message.range,
|
message.range,
|
||||||
@@ -236,11 +240,13 @@ export class ChatManager {
|
|||||||
// Handle MinecraftTextComponent for private message
|
// Handle MinecraftTextComponent for private message
|
||||||
[success, errorMsg] = chatbox.sendFormattedMessageToPlayer(
|
[success, errorMsg] = chatbox.sendFormattedMessageToPlayer(
|
||||||
textutils.serialiseJSON(message.message, {
|
textutils.serialiseJSON(message.message, {
|
||||||
unicode_strings: true,
|
unicode_strings: message.utf8Support,
|
||||||
allow_repetitions: true,
|
allow_repetitions: true,
|
||||||
}),
|
}),
|
||||||
message.targetPlayer,
|
message.targetPlayer,
|
||||||
message.prefix,
|
textutils.serialiseJSON(message.prefix ?? "AP", {
|
||||||
|
unicode_strings: message.utf8Support,
|
||||||
|
}),
|
||||||
message.brackets,
|
message.brackets,
|
||||||
message.bracketColor,
|
message.bracketColor,
|
||||||
message.range,
|
message.range,
|
||||||
@@ -251,8 +257,12 @@ export class ChatManager {
|
|||||||
// Send global message
|
// Send global message
|
||||||
if (typeof message.message === "string") {
|
if (typeof message.message === "string") {
|
||||||
[success, errorMsg] = chatbox.sendMessage(
|
[success, errorMsg] = chatbox.sendMessage(
|
||||||
message.message,
|
textutils.serialiseJSON(message.message, {
|
||||||
message.prefix,
|
unicode_strings: message.utf8Support,
|
||||||
|
}),
|
||||||
|
textutils.serialiseJSON(message.prefix ?? "AP", {
|
||||||
|
unicode_strings: message.utf8Support,
|
||||||
|
}),
|
||||||
message.brackets,
|
message.brackets,
|
||||||
message.bracketColor,
|
message.bracketColor,
|
||||||
message.range,
|
message.range,
|
||||||
@@ -262,10 +272,12 @@ export class ChatManager {
|
|||||||
// Handle MinecraftTextComponent for global message
|
// Handle MinecraftTextComponent for global message
|
||||||
[success, errorMsg] = chatbox.sendFormattedMessage(
|
[success, errorMsg] = chatbox.sendFormattedMessage(
|
||||||
textutils.serialiseJSON(message.message, {
|
textutils.serialiseJSON(message.message, {
|
||||||
unicode_strings: true,
|
unicode_strings: message.utf8Support,
|
||||||
allow_repetitions: true,
|
allow_repetitions: true,
|
||||||
}),
|
}),
|
||||||
message.prefix,
|
textutils.serialiseJSON(message.prefix ?? "AP", {
|
||||||
|
unicode_strings: message.utf8Support,
|
||||||
|
}),
|
||||||
message.brackets,
|
message.brackets,
|
||||||
message.bracketColor,
|
message.bracketColor,
|
||||||
message.range,
|
message.range,
|
||||||
@@ -321,10 +333,16 @@ export class ChatManager {
|
|||||||
typeof toast.title === "string"
|
typeof toast.title === "string"
|
||||||
) {
|
) {
|
||||||
[success, errorMsg] = chatbox.sendToastToPlayer(
|
[success, errorMsg] = chatbox.sendToastToPlayer(
|
||||||
toast.message,
|
textutils.serialiseJSON(toast.message, {
|
||||||
toast.title,
|
unicode_strings: toast.utf8Support,
|
||||||
|
}),
|
||||||
|
textutils.serialiseJSON(toast.title, {
|
||||||
|
unicode_strings: toast.utf8Support,
|
||||||
|
}),
|
||||||
toast.targetPlayer,
|
toast.targetPlayer,
|
||||||
toast.prefix,
|
textutils.serialiseJSON(toast.prefix ?? "AP", {
|
||||||
|
unicode_strings: toast.utf8Support,
|
||||||
|
}),
|
||||||
toast.brackets,
|
toast.brackets,
|
||||||
toast.bracketColor,
|
toast.bracketColor,
|
||||||
toast.range,
|
toast.range,
|
||||||
@@ -337,21 +355,23 @@ export class ChatManager {
|
|||||||
? toast.message
|
? toast.message
|
||||||
: textutils.serialiseJSON(toast.message, {
|
: textutils.serialiseJSON(toast.message, {
|
||||||
unicode_strings: true,
|
unicode_strings: true,
|
||||||
allow_repetitions: true,
|
allow_repetitions: toast.utf8Support,
|
||||||
});
|
});
|
||||||
const titleJson =
|
const titleJson =
|
||||||
typeof toast.title === "string"
|
typeof toast.title === "string"
|
||||||
? toast.title
|
? toast.title
|
||||||
: textutils.serialiseJSON(toast.title, {
|
: textutils.serialiseJSON(toast.title, {
|
||||||
unicode_strings: true,
|
unicode_strings: true,
|
||||||
allow_repetitions: true,
|
allow_repetitions: toast.utf8Support,
|
||||||
});
|
});
|
||||||
|
|
||||||
[success, errorMsg] = chatbox.sendFormattedToastToPlayer(
|
[success, errorMsg] = chatbox.sendFormattedToastToPlayer(
|
||||||
messageJson,
|
messageJson,
|
||||||
titleJson,
|
titleJson,
|
||||||
toast.targetPlayer,
|
toast.targetPlayer,
|
||||||
toast.prefix,
|
textutils.serialiseJSON(toast.prefix ?? "AP", {
|
||||||
|
unicode_strings: toast.utf8Support,
|
||||||
|
}),
|
||||||
toast.brackets,
|
toast.brackets,
|
||||||
toast.bracketColor,
|
toast.bracketColor,
|
||||||
toast.range,
|
toast.range,
|
||||||
|
|||||||
2
types/advanced-peripherals/shared.d.ts
vendored
2
types/advanced-peripherals/shared.d.ts
vendored
@@ -30,7 +30,7 @@ declare type MinecraftColor =
|
|||||||
| "light_purple"
|
| "light_purple"
|
||||||
| "yellow"
|
| "yellow"
|
||||||
| "white"
|
| "white"
|
||||||
| "reset"; // RGB color in #RRGGBB format
|
| `#${string}`;
|
||||||
|
|
||||||
declare type MinecraftFont =
|
declare type MinecraftFont =
|
||||||
| "minecraft:default"
|
| "minecraft:default"
|
||||||
|
|||||||
20
types/craftos/index.d.ts
vendored
20
types/craftos/index.d.ts
vendored
@@ -925,10 +925,22 @@ declare namespace textutils {
|
|||||||
function pagedTabulate(...args: (LuaTable | Object | Color)[]): void;
|
function pagedTabulate(...args: (LuaTable | Object | Color)[]): void;
|
||||||
function serialize(tab: object, options?: SerializeOptions): string;
|
function serialize(tab: object, options?: SerializeOptions): string;
|
||||||
function serialise(tab: object, options?: SerializeOptions): string;
|
function serialise(tab: object, options?: SerializeOptions): string;
|
||||||
function serializeJSON(tab: object, nbtStyle?: boolean): string;
|
function serializeJSON(
|
||||||
function serializeJSON(tab: object, options: SerializeJSONOptions): string;
|
tab: object | string | number | boolean,
|
||||||
function serialiseJSON(tab: object, nbtStyle?: boolean): string;
|
nbtStyle?: boolean,
|
||||||
function serialiseJSON(tab: object, options: SerializeJSONOptions): string;
|
): string;
|
||||||
|
function serializeJSON(
|
||||||
|
tab: object | string | number | boolean,
|
||||||
|
options: SerializeJSONOptions,
|
||||||
|
): string;
|
||||||
|
function serialiseJSON(
|
||||||
|
tab: object | string | number | boolean,
|
||||||
|
nbtStyle?: boolean,
|
||||||
|
): string;
|
||||||
|
function serialiseJSON(
|
||||||
|
tab: object | string | number | boolean,
|
||||||
|
options: SerializeJSONOptions,
|
||||||
|
): string;
|
||||||
function unserialize(str: string): unknown;
|
function unserialize(str: string): unknown;
|
||||||
function unserialise(str: string): unknown;
|
function unserialise(str: string): unknown;
|
||||||
function unserializeJSON(
|
function unserializeJSON(
|
||||||
|
|||||||
Reference in New Issue
Block a user