boxmoe_header_banner_img

菜就多练喵

文章导读

[C#][Untiy][Ib_Core]Ib_Cmd——输入命令在游戏内”作弊”


avatar
Ib_Mccf 2026年2月27日 12

功能:在输入框中输入指定命令,即可调用指定的方法。

特点:命令注册与命令框解耦。支持单词联想与默认值。

依赖:Unitask,ZLinq,Ib_Event,Ib_Aysnc

命令注册示例:

void Start()
{
    unitList = new();
    var unitInfos = ContentData.Default.GetAllUnitInfoConfig();
    for (int i = 0; i < unitInfos.Count; i++)
    {
        unitList.Add(unitInfos[i].Resource);
    }

    //注册"summon"命令,有三个参数,类型分别为string,int,int,CmdAssociationBox设置第一个参数会自动联想unitList中的字符。CmdDefaultValBox设置第二和第三参数的默认值为1。
    Ib_Cmd.RegisterCmd<string, int, int>("summon", Summon, "summon [string]prefabName [int]cnt=1 [int]level=1————生成单位", new Ib_Cmd.CmdAssociationBox(unitList, null, null, null, null), new Ib_Cmd.CmdDefaultValBox(null, "1", "1", null, null));
}

private void OnDestroy()
{
    //取消注册
    Ib_Cmd.DeregisterCmd("summon");
}

//"summon"对应执行的方法,生成一个单位
private string Summon(string prefabName, int cnt, int level = 1)
{
    if (!string.IsNullOrEmpty(prefabName))
    {
        int index = 0;
        for (int i = 0; i < cnt; i++)
        {
            var pos = Camera.main.GetComponent<MoveCamera>().CameraTarget.position;
            float len = 0.1f;
            pos += new Vector3(Random.Range(-len, len), 0, Random.Range(-len, len));
            UnityExtensions.SamplePosition(pos, out Vector3 samplePos);
            var unit = SXUnitCreator.CreateUnit(prefabName, level, samplePos, Quaternion.identity);
            if (!unit) return Ib_CmdTools.Output($"非法单位-{prefabName}-!", Ib_CmdTools.Ib_CmdOutputType.Error);
        }

        return $"-{prefabName}-生成成功!";
    }

    return Ib_CmdTools.Output($"非法单位-{prefabName}-!", Ib_CmdTools.Ib_CmdOutputType.Error);
}

源码:

UI部分:

using Cysharp.Threading.Tasks;
using Ib_Core;
using UnityEngine;

public class Ib_CmdManager : MonoBehaviour
{
    private void Start()
    {
        SwitchIbCmdPanel.InvokeNextFrame(false,this.GetCancellationTokenOnDestroy());
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Slash))
        {
            SwitchIbCmdPanel.Invoke(true);
        }else if (Input.GetKeyDown(KeyCode.Escape))
        {
            SwitchIbCmdPanel.Invoke(false);
        }
    }
}
using System;
using Cysharp.Threading.Tasks;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace Ib_Core
{
    using TMPro;
    using UnityEngine;
    using System.Text;

    public class SwitchIbCmdPanel : Ib_Event<SwitchIbCmdPanel,bool> { }
    public class Ib_CmdUI : MonoBehaviour
    {
        [SerializeField] private TMP_InputField inputField;
        [SerializeField] private TextMeshProUGUI outputTxt;
        [SerializeField] private TextMeshProUGUI cmdTipsTxt;
        [SerializeField] private TextMeshProUGUI cmdAssociationTxt;

        [SerializeField] private ScrollRect scrollRect;

        private void Start()
        {
            if (inputField == null || outputTxt == null)
            {
                Log.Error("Ib_CmdUI缺少关键组件!无法运行!");
                enabled = false;
                return;
            }

            outputTxt.text = string.Empty;
            inputField.onValueChanged.AddListener(OnInputFieldValueChanged);
            
            SwitchIbCmdPanel.Register(Show);
            OnClearCmdExecute.Register(ClearOutputTxt);
        }
        
        private void OnDestroy()
        {
            SwitchIbCmdPanel.Deregister(Show);
            OnClearCmdExecute.Deregister(ClearOutputTxt);
        }

        private void Show(bool show)
        {
            gameObject.SetActive(show);
            Ib_Async.DelayDoSomething(() => inputField.ActivateInputField(), this.GetCancellationTokenOnDestroy());
            UnityExtensions.TimeScale = show ? 0 : 1;
            if (GameModeSystem.ReadonlyGet())
            {
                GameModeSystem.ReadonlyGet().CanSetTimeScale = !show;
                GameModeSystem.ReadonlyGet().ConsoleTestOn = show;
            }
        }

        private void ClearOutputTxt()
        {
            outputTxt.text = string.Empty;
            Log.Info("清除面板");
        }
        private void Update()
        {
            // if(!inputField.isFocused)return;
            //输入
            if (Input.GetKeyDown(KeyCode.Return))
            {
                string inputStr = inputField.text;
                bool isCmd = inputStr.StartsWith("/");
                StringBuilder stringBuilder = new StringBuilder(outputTxt.text);
                stringBuilder.AppendFormat("[{0}] >> {1}\n",System.DateTime.Now,Ib_CmdTools.Output(inputField.text, isCmd ? Ib_CmdTools.Ib_CmdOutputType.Command : Ib_CmdTools.Ib_CmdOutputType.Text));
                //如果是命令,则执行
                if (isCmd)
                {
                    Ib_Cmd.ExecuteCmd(inputField.text, out var result,out var callback);
                    if (!string.IsNullOrEmpty(callback))
                    {
                        stringBuilder.AppendFormat("{0}\n",callback);
                    }
                    stringBuilder.AppendFormat(">> {0}\n",result);
                }
                stringBuilder.Append("\n");

                outputTxt.text = stringBuilder.ToString();
                inputField.text = "";
                inputField.ActivateInputField();
                if(scrollRect) Ib_Async.DelayDoSomething(()=>scrollRect.verticalNormalizedPosition = 0,scrollRect.GetCancellationTokenOnDestroy());
            }else if (Input.GetKeyDown(KeyCode.UpArrow))
            {
                if (Ib_Cmd.LastCmd(out var result))
                {
                    inputField.text = result;
                    inputField.caretPosition = result.Length;
                }
            }else if (Input.GetKeyDown(KeyCode.DownArrow))
            {
                if (Ib_Cmd.NextCmd(out var result))
                {
                    inputField.text = result;
                    inputField.caretPosition = result.Length;
                }
            }else if (Input.GetKeyDown(KeyCode.Tab))
            {
                if (cmdAssociationTxt && inputField.text.StartsWith("/"))
                {
                    inputField.text = cmdAssociationTxt.text;
                    inputField.caretPosition = cmdAssociationTxt.text.Length;
                }
            }
        }

        private void OnInputFieldValueChanged(string content)
        {
            if (content.StartsWith("/"))
            {
                var tokens = content.Substring(1, content.Length - 1).Split(" ");
                if (tokens.Length >= 1)
                {
                    if (cmdTipsTxt) cmdTipsTxt.text = GetCmdTips(tokens[0]);
                    if (cmdAssociationTxt)
                    {
                        StringBuilder stringBuilder = new();
                        stringBuilder.AppendFormat("{0}{1}", content.Substring(0, content.Length - tokens[^1].Length), GetCmdAssociation(tokens[0], tokens.Length - 1, tokens[^1]));
                        cmdAssociationTxt.text = stringBuilder.ToString();
                    }
                    return;
                }
            }
            if (cmdAssociationTxt) cmdAssociationTxt.text = string.Empty;
            if(cmdTipsTxt)cmdTipsTxt.text = string.Empty;  
        }
        private string GetCmdTips(string cmd)
        {
            return Ib_Cmd.GetCmdTips(cmd);
        }
        private string GetCmdAssociation(string cmd,int index, string str)
        {
            return Ib_Cmd.GetCmdAssociation(cmd,index,str);
        }
    }
}

核心——命令处理:

using System.Threading;
using JetBrains.Annotations;
using ZLinq;

namespace Ib_Core
{
    using System;
    using System.Collections.Generic;
    using System.Text;

    public class OnClearCmdExecute : Ib_Event<OnClearCmdExecute> { }

    public static partial class Ib_Cmd
    {
        public struct CmdDefaultValBox
        {
            public string arg1DefaultVal;
            public string arg2DefaultVal;
            public string arg3DefaultVal;
            public string arg4DefaultVal;
            public string arg5DefaultVal;

            public CmdDefaultValBox(string arg1,string arg2,string arg3,string arg4,string arg5)
            {
                arg1DefaultVal = arg1;
                arg2DefaultVal = arg2;
                arg3DefaultVal = arg3;
                arg4DefaultVal = arg4;
                arg5DefaultVal = arg5;
            }
        }
        /// <summary>
        /// 至多五个参数的联想列表
        /// </summary>
        public struct CmdAssociationBox
        {
            public List<string> arg1Association;
            public List<string> arg2Association;
            public List<string> arg3Association;
            public List<string> arg4Association;
            public List<string> arg5Association;

            public CmdAssociationBox(List<string> arg1, List<string> arg2, List<string> arg3, List<string> arg4, List<string> arg5)
            {
                arg1Association = arg1 ?? new List<string>();
                arg2Association = arg2 ?? new List<string>();
                arg3Association = arg3 ?? new List<string>();
                arg4Association = arg4 ?? new List<string>();
                arg5Association = arg5 ?? new List<string>();
            }
        
            /// <summary>
            /// 索引器
            /// </summary>
            /// <param name="index"></param>
            /// <exception cref="ArgumentOutOfRangeException"></exception>
            public List<string> this[int index]
            {
                get
                {
                    return index switch
                    {
                        1 => arg1Association,
                        2 => arg2Association,
                        3 => arg3Association,
                        4 => arg4Association,
                        5 => arg5Association,
                        _ => throw new ArgumentOutOfRangeException(nameof(index), "Index must be between 1 and 5")
                    };
                }
                set
                {
                    switch (index)
                    {
                        case 1:
                            arg1Association = value;
                            break;
                        case 2:
                            arg2Association = value;
                            break;
                        case 3:
                            arg3Association = value;
                            break;
                        case 4:
                            arg4Association = value;
                            break;
                        case 5:
                            arg5Association = value;
                            break;
                        default: throw new ArgumentOutOfRangeException(nameof(index), "Index must be between 1 and 5");
                    }
                }
            }
        }
        internal struct CmdBox
        {
            public IFuncInvoker func;
            public string desc;
            public CmdAssociationBox CmdAssociationBox;
            public CmdDefaultValBox CmdDefaultValBox;
        }
        
        /// <summary>
        /// 存储所有可执行命令
        /// </summary>
        private static Dictionary<string, CmdBox> cmdDict = new()
        {
            {
                "help", 
                new CmdBox()
                {
                    func = new FuncInvoker(ShowHelpList),
                    desc = "help——查看帮助"
                }
            },
            {
                "clr", 
                new CmdBox()
                {
                    func = new FuncInvoker(ClearOutput),
                    desc = "clr——清除面板内容"
                }
            }
        };
        
        private static List<string> recordCmdList = new();
        private static int recordIndex = 0;
        private const int MaxRecordCmdCnt = 999;
        private const int MaxCmdTipsCnt = 10;

        /// <summary>
        /// 处理命令
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static bool ExecuteCmd(string cmd, out string result,out string callback)
        {
            callback = string.Empty;
            cmd = cmd.Trim();
            if (string.IsNullOrEmpty(cmd))
            {
                result = Ib_CmdTools.Output("请输入命令!", Ib_CmdTools.Ib_CmdOutputType.Error);
                return false;
            }
            if(recordCmdList.Count >= MaxRecordCmdCnt)recordCmdList.RemoveAt(0);
            recordCmdList.Add(cmd);
            recordIndex = recordCmdList.Count;

            var cmdTokens = cmd.Substring(1, cmd.Length -1).Split(" ");
            if (cmdTokens.Length > 0 && cmdDict.ContainsKey(cmdTokens[0]))
            {
                FuncInvokerBox funcInvokerBox = new FuncInvokerBox();
                if (cmdTokens.Length > 1) funcInvokerBox.arg1 = cmdTokens[1];
                if (cmdTokens.Length > 2) funcInvokerBox.arg2 = cmdTokens[2];
                if (cmdTokens.Length > 3) funcInvokerBox.arg3 = cmdTokens[3];
                if (cmdTokens.Length > 4) funcInvokerBox.arg4 = cmdTokens[4];
                
                //填入默认值
                var defaultValBox = cmdDict[cmdTokens[0]].CmdDefaultValBox;
                if (string.IsNullOrEmpty(funcInvokerBox.arg1)) funcInvokerBox.arg1 = defaultValBox.arg1DefaultVal ?? string.Empty;
                if (string.IsNullOrEmpty(funcInvokerBox.arg2)) funcInvokerBox.arg2 = defaultValBox.arg2DefaultVal ?? string.Empty;
                if (string.IsNullOrEmpty(funcInvokerBox.arg3)) funcInvokerBox.arg3 = defaultValBox.arg3DefaultVal ?? string.Empty;
                if (string.IsNullOrEmpty(funcInvokerBox.arg4)) funcInvokerBox.arg4 = defaultValBox.arg4DefaultVal ?? string.Empty;

                callback = cmdDict[cmdTokens[0]].func.Invoke(funcInvokerBox);
                result = Ib_CmdTools.Output("执行成功!", Ib_CmdTools.Ib_CmdOutputType.Success);
                return true;
            }
            
            result = Ib_CmdTools.Output("无效命令!请输入/help查看命令列表!", Ib_CmdTools.Ib_CmdOutputType.Error);
            return false;
        }

        public static bool LastCmd(out string result)
        {
            if (recordIndex - 1 >= 0 && recordCmdList.Count > 0)
            {
                recordIndex--;
                result = recordCmdList[recordIndex];
                return true;
            }
            result = string.Empty;
            return false;
        }

        public static bool NextCmd(out string result)
        {
            if (recordCmdList.Count == 0)
            {
                result = string.Empty;
                return false;
            }
            if (recordIndex + 1 < recordCmdList.Count)
            {
                recordIndex++;
                result = recordCmdList[recordIndex];
                return true;
            }
            else
            {
                // 允许回到“新命令”状态
                recordIndex = recordCmdList.Count; 
                result = string.Empty;
                return true;
            }
        }
        /// <summary>
        /// 获取相似命令提示
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        public static string GetCmdTips(string cmd)
        {
            List<string> tipsList = new();
            foreach (var item in cmdDict)
            {
                if (item.Key.StartsWith(cmd))
                {
                    if(!string.IsNullOrEmpty(item.Value.desc))
                        tipsList.Add(item.Value.desc);
                }     
            }
            tipsList.Sort();
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < tipsList.Count; i++)
            {
                if (i >= MaxCmdTipsCnt) break;
                stringBuilder.Append(tipsList[i]);
                if(i != tipsList.Count - 1)stringBuilder.Append("\n");
            }
            return stringBuilder.ToString();
        }
        /// <summary>
        /// 获取命令参数的联想
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="index"></param>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetCmdAssociation(string cmd,int index,string str)
        {
            if (cmdDict.TryGetValue(cmd, out var cmdBox) && index >= 1 && index <= 5)
            {
                var associations = cmdBox.CmdAssociationBox[index];
                if (associations != null)
                {
                    var association = associations.AsValueEnumerable().Where(t => t.StartsWith(str)).OrderBy(t => t).FirstOrDefault();
                    if (association != null)
                    {
                        return association;
                    }
                }
            }
            else if(index  == 0)
            {
                var association = cmdDict.Keys.AsValueEnumerable().Where(t => t.StartsWith(cmd)).OrderBy(t => t).FirstOrDefault();
                if (association != null)
                {
                    return association;
                }
            }
            return string.Empty;
        }
        #region 默认Cmd命令实现
        /// <summary>
        /// help命令显示当前所有的可执行命令描述
        /// </summary>
        /// <returns></returns>
        private static string ShowHelpList()
        {
            List<string> re = new(cmdDict.Count);
            foreach (var item in cmdDict)
            {
                if (!string.IsNullOrEmpty(item.Value.desc))
                    re.Add(item.Value.desc);
            }
            re.Sort();
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < re.Count; i++)
            {
                stringBuilder.Append(Ib_CmdTools.Output(re[i],Ib_CmdTools.Ib_CmdOutputType.Help));
                if(i != re.Count -1)stringBuilder.Append("\n");
            }
            return stringBuilder.ToString();
        }

        private static string ClearOutput()
        {
            OnClearCmdExecute.InvokeNextFrame(CancellationToken.None);
            return string.Empty;
        }

        #endregion
        
    }

    public static partial class Ib_Cmd
    {
        #region Func多参数结构体
        internal struct FuncInvokerBox
        {
            public string arg1;
            public string arg2;
            public string arg3;
            public string arg4;
        }
        internal interface IFuncInvoker
        {
            public string Invoke(FuncInvokerBox funcInvokerBox);
        }

        internal struct FuncInvoker : IFuncInvoker
        {
            private readonly Func<string> _func;
            public FuncInvoker(Func<string> func) => _func = func;
            public string Invoke(FuncInvokerBox funcInvokerBox) => _func.Invoke();
        }
        internal struct FuncInvoker<T> : IFuncInvoker
        {
            private readonly Func<T,string> _func;
            public FuncInvoker(Func<T,string> func) => _func = func;
            public string Invoke(FuncInvokerBox funcInvokerBox)
            {
                StringBuilder stringBuilder = new StringBuilder();
                try
                {
                    if (!Ib_CmdTools.TryConvert(funcInvokerBox.arg1, out T arg, out string callback)) return callback;
                    if(!string.IsNullOrEmpty(callback))stringBuilder.AppendFormat("{0}\n", callback);
                    string result = _func.Invoke(arg);
                    if(!string.IsNullOrEmpty(result))stringBuilder.AppendFormat("{0}",result);
                    return stringBuilder.ToString();
                }
                catch (Exception ex)
                {
                    // 可以返回更详细的错误,比如参数类型不匹配
                    stringBuilder.AppendFormat("{0}\n", Ib_CmdTools.Output($"参数类型不匹配! Details: {ex.Message}", Ib_CmdTools.Ib_CmdOutputType.Error));
                }
                return stringBuilder.ToString();
            }
        }
              // 2 个参数
        internal struct FuncInvoker<T1, T2> : IFuncInvoker
        {
            private readonly Func<T1, T2, string> _func;
            public FuncInvoker(Func<T1, T2, string> func) => _func = func;
            public string Invoke(FuncInvokerBox funcInvokerBox)
            {
                StringBuilder stringBuilder = new StringBuilder();
                try
                {
                    if (!Ib_CmdTools.TryConvert(funcInvokerBox.arg1, out T1 arg1, out string callback1)) return callback1;
                    if(!string.IsNullOrEmpty(callback1))stringBuilder.AppendFormat("{0}\n", callback1);
                    if (!Ib_CmdTools.TryConvert(funcInvokerBox.arg2, out T2 arg2, out string callback2)) return callback2;
                    if(!string.IsNullOrEmpty(callback2))stringBuilder.AppendFormat("{0}\n", callback2);
                    string result = _func.Invoke(arg1, arg2);
                    if(!string.IsNullOrEmpty(result))stringBuilder.AppendFormat("{0}", result);
                    return stringBuilder.ToString();
                }
                catch (Exception ex)
                {
                    // 可以返回更详细的错误,比如参数类型不匹配
                    stringBuilder.AppendFormat("{0}\n",  Ib_CmdTools.Output($"转换失败! Details: {ex.Message}", Ib_CmdTools.Ib_CmdOutputType.Error));
                }
                return stringBuilder.ToString();
            }
        }
        
        // 3 个参数
        internal struct FuncInvoker<T1, T2, T3> : IFuncInvoker
        {
            private readonly Func<T1, T2, T3, string> _func;
            public FuncInvoker(Func<T1, T2, T3, string> func) => _func = func;
            public string Invoke(FuncInvokerBox funcInvokerBox)
            {
                StringBuilder stringBuilder = new StringBuilder();
                try
                {
                    if (!Ib_CmdTools.TryConvert(funcInvokerBox.arg1, out T1 arg1, out string callback1)) return callback1;
                    if(!string.IsNullOrEmpty(callback1))stringBuilder.AppendFormat("{0}\n", callback1);
                    if (!Ib_CmdTools.TryConvert(funcInvokerBox.arg2, out T2 arg2, out string callback2)) return callback2;
                    if(!string.IsNullOrEmpty(callback2))stringBuilder.AppendFormat("{0}\n", callback2);
                    if (!Ib_CmdTools.TryConvert(funcInvokerBox.arg3, out T3 arg3, out string callback3)) return callback3;
                    if(!string.IsNullOrEmpty(callback3))stringBuilder.AppendFormat("{0}\n", callback3);
                    string result = _func.Invoke(arg1, arg2, arg3);
                    if(!string.IsNullOrEmpty(result))stringBuilder.AppendFormat("{0}", result);
                    return stringBuilder.ToString();
                }
                catch (Exception ex)
                {
                    // 可以返回更详细的错误,比如参数类型不匹配
                    stringBuilder.AppendFormat("{0}\n", Ib_CmdTools.Output($"转换失败! Details: {ex.Message}", Ib_CmdTools.Ib_CmdOutputType.Error));
                }
                return stringBuilder.ToString();
            }
        }
        
        // 4 个参数
        internal struct FuncInvoker<T1, T2, T3, T4> : IFuncInvoker
        {
            private readonly Func<T1, T2, T3, T4, string> _func;
            public FuncInvoker(Func<T1, T2, T3, T4, string> func) => _func = func;
            public string Invoke(FuncInvokerBox funcInvokerBox)
            {
                StringBuilder stringBuilder = new StringBuilder();
                try
                {
                    if (!Ib_CmdTools.TryConvert(funcInvokerBox.arg1, out T1 arg1, out string callback1)) return callback1;
                    if(!string.IsNullOrEmpty(callback1))stringBuilder.AppendFormat("{0}\n", callback1);
                    if (!Ib_CmdTools.TryConvert(funcInvokerBox.arg2, out T2 arg2, out string callback2)) return callback2;
                    if(!string.IsNullOrEmpty(callback2))stringBuilder.AppendFormat("{0}\n", callback2);
                    if (!Ib_CmdTools.TryConvert(funcInvokerBox.arg3, out T3 arg3, out string callback3)) return callback3;
                    if(!string.IsNullOrEmpty(callback3))stringBuilder.AppendFormat("{0}\n", callback3);
                    if (!Ib_CmdTools.TryConvert(funcInvokerBox.arg4, out T4 arg4, out string callback4)) return callback4;
                    if(!string.IsNullOrEmpty(callback4))stringBuilder.AppendFormat("{0}\n", callback4);
                    string result = _func.Invoke(arg1, arg2, arg3, arg4);
                    if(!string.IsNullOrEmpty(result))stringBuilder.AppendFormat("{0}", result);
                    return stringBuilder.ToString();
                }
                catch (Exception ex)
                {
                    // 可以返回更详细的错误,比如参数类型不匹配
                    stringBuilder.AppendFormat("{0}\n", Ib_CmdTools.Output($"转换失败! Details: {ex.Message}", Ib_CmdTools.Ib_CmdOutputType.Error));
                }
                return stringBuilder.ToString();
            }
        }
        
        #endregion

        #region 命令注册与销毁

        public static void RegisterCmd(string cmd, Func<string> func,string desc,CmdAssociationBox cmdAssociationBox = default,CmdDefaultValBox cmdDefaultValBox = default)
        {
            if (cmdDict.ContainsKey(cmd))
            {
                Log.Warn($"请勿重复添加命令!{cmd}");
                return;
            }

            CmdBox cmdBox = new CmdBox();
            cmdBox.func = new FuncInvoker(func);
            cmdBox.desc = desc;
            cmdBox.CmdAssociationBox = cmdAssociationBox;
            cmdBox.CmdDefaultValBox = cmdDefaultValBox;
            cmdDict.Add(cmd,cmdBox);
        }
        
        public static void RegisterCmd<T>(string cmd, Func<T,string> func,string desc,CmdAssociationBox cmdAssociationBox = default,CmdDefaultValBox cmdDefaultValBox = default)  
        {
            if (cmdDict.ContainsKey(cmd))
            {
                Log.Warn($"请勿重复添加命令!{cmd}");
                return;
            }

            CmdBox cmdBox = new CmdBox();
            cmdBox.func = new FuncInvoker<T>(func);
            cmdBox.desc = desc;
            cmdBox.CmdAssociationBox = cmdAssociationBox;
            cmdBox.CmdDefaultValBox = cmdDefaultValBox;

            cmdDict.Add(cmd,cmdBox);
        }
        // 2 个参数
        public static void RegisterCmd<T1, T2>(string cmd, Func<T1, T2, string> func, string desc,CmdAssociationBox cmdAssociationBox = default,CmdDefaultValBox cmdDefaultValBox = default) 
        {
            if (cmdDict.ContainsKey(cmd))
            {
                Log.Warn($"请勿重复添加命令!{cmd}");
                return;
            }

            CmdBox cmdBox = new CmdBox();
            cmdBox.func = new FuncInvoker<T1, T2>(func);
            cmdBox.desc = desc;
            cmdBox.CmdAssociationBox = cmdAssociationBox;
            cmdBox.CmdDefaultValBox = cmdDefaultValBox;

            cmdDict.Add(cmd, cmdBox);
        }
        
        // 3 个参数
        public static void RegisterCmd<T1, T2, T3>(string cmd, Func<T1, T2, T3, string> func, string desc,CmdAssociationBox cmdAssociationBox = default,CmdDefaultValBox cmdDefaultValBox = default) 
        {
            if (cmdDict.ContainsKey(cmd))
            {
                Log.Warn($"请勿重复添加命令!{cmd}");
                return;
            }

            CmdBox cmdBox = new CmdBox();
            cmdBox.func = new FuncInvoker<T1, T2, T3>(func);
            cmdBox.desc = desc;
            cmdBox.CmdAssociationBox = cmdAssociationBox;
            cmdBox.CmdDefaultValBox = cmdDefaultValBox;

            cmdDict.Add(cmd, cmdBox);
        }
        
        // 4 个参数
        public static void RegisterCmd<T1, T2, T3, T4>(string cmd, Func<T1, T2, T3, T4, string> func, string desc,CmdAssociationBox cmdAssociationBox = default,CmdDefaultValBox cmdDefaultValBox = default) 
        {
            if (cmdDict.ContainsKey(cmd))
            {
                Log.Warn($"请勿重复添加命令!{cmd}");
                return;
            }

            CmdBox cmdBox = new CmdBox();
            cmdBox.func = new FuncInvoker<T1, T2, T3, T4>(func);
            cmdBox.desc = desc;
            cmdBox.CmdAssociationBox = cmdAssociationBox;
            cmdBox.CmdDefaultValBox = cmdDefaultValBox;

            cmdDict.Add(cmd, cmdBox);
        }

        public static void DeregisterCmd(string cmd)
        {
            cmdDict.Remove(cmd);
        }
        
        #endregion
    }
}

拓展方法:

namespace Ib_Core
{
    using System;
    using System.Collections.Generic;
    using System.Text;

    public static class Ib_CmdTools
    {
        public enum Ib_CmdOutputType
        {
            Command = 0,
            Error = 1,
            Help = 2,
            Text = 3,
            Success = 4,
        }

        public static string Output(string content, Ib_CmdOutputType outputType)
        {
            StringBuilder re = new StringBuilder();
            switch (outputType)
            {
                case Ib_CmdOutputType.Command:
                    re.AppendFormat("{0}{1}{2}", "<color=#32CD32>", content, "</color>");
                    break;
                case Ib_CmdOutputType.Error:
                    re.AppendFormat("{0}{1}{2}", "<color=#FF6A6A>", content, "</color>");
                    break;
                case Ib_CmdOutputType.Help:
                    re.AppendFormat("{0}{1}{2}", "<color=#e0d646>", content, "</color>");
                    break;
                case Ib_CmdOutputType.Text:
                    re.AppendFormat("{0}{1}{2}", "<color=#BFBFBF>", content, "</color>");
                    break;
                case Ib_CmdOutputType.Success:
                    re.AppendFormat("{0}{1}{2}", "<color=#FFC83C>", content, "</color>");
                    break;
                default:
                    re.Append(content);
                    break;
            }

            return re.ToString();
        }

        public static bool TryConvert<T>(string input, out T result, out string callback)
        {
            callback = string.Empty;
            result = (T)default;
            if (string.IsNullOrEmpty(input))
            {
                callback = Output("错误: 缺少参数!", Ib_CmdOutputType.Error);
                return false;
            }

            string cleanArg = input.Trim();
            try
            {
                result = (T)Convert.ChangeType(cleanArg, typeof(T));
                return true;
            }
            catch (Exception ex)
            {
                callback = Output($"参数 '{cleanArg}' 无法转换为所需的类型 '{typeof(T).Name}'", Ib_CmdOutputType.Error);
            }

            return false;
        }
    }
}


评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字

插入代码