private bool API_AddGroup(string group)
        {
            if (ChatGroup.Find(group) != null)
            {
                return(false);
            }

            ChatGroups.Add(new ChatGroup(group));
            SaveData(ChatGroups);

            return(true);
        }
        private void CmdChat(IPlayer player, string cmd, string[] args)
        {
            cmd = player.LastCommand == CommandType.Console ? cmd : $"/{cmd}";

            if (args.Length == 0)
            {
                player.Reply($"{cmd} <group|user>");
                return;
            }

            string argsStr = string.Join(" ", args);

            var commands = new Dictionary <string, Action <string[]> >
            {
                ["group add"] = a => {
                    if (a.Length != 1)
                    {
                        player.Reply($"Syntax: {cmd} group add <group>");
                        return;
                    }

                    string groupName = a[0].ToLower();

                    if (ChatGroup.Find(groupName) != null)
                    {
                        player.ReplyLang("Group Already Exists", new KeyValuePair <string, string>("group", groupName));
                        return;
                    }

                    ChatGroup group = new ChatGroup(groupName);

                    ChatGroups.Add(group);

                    if (!permission.GroupExists(group.GroupName))
                    {
                        permission.CreateGroup(group.GroupName, string.Empty, 0);
                    }

                    SaveData(ChatGroups);

                    player.ReplyLang("Group Added", new KeyValuePair <string, string>("group", groupName));
                },
                ["group remove"] = a => {
                    if (a.Length != 1)
                    {
                        player.Reply($"Syntax: {cmd} group remove <group>");
                        return;
                    }

                    string    groupName = a[0].ToLower();
                    ChatGroup group     = ChatGroup.Find(groupName);

                    if (group == null)
                    {
                        player.ReplyLang("Group Does Not Exist", new KeyValuePair <string, string>("group", groupName));
                        return;
                    }

                    ChatGroups.Remove(group);
                    SaveData(ChatGroups);

                    player.ReplyLang("Group Removed", new KeyValuePair <string, string>("group", groupName));
                },
                ["group set"] = a => {
                    if (a.Length != 3)
                    {
                        player.Reply($"Syntax: {cmd} group set <group> <field> <value>");
                        player.Reply($"Fields:{Environment.NewLine}{string.Join(", ", ChatGroup.Fields.Select(kvp => $"({kvp.Value.UserFriendyType}) {kvp.Key}").ToArray())}");
                        return;
                    }

                    string    groupName = a[0].ToLower();
                    ChatGroup group     = ChatGroup.Find(groupName);

                    if (group == null)
                    {
                        player.ReplyLang("Group Does Not Exist", new KeyValuePair <string, string>("group", groupName));
                        return;
                    }

                    string field    = a[1];
                    string strValue = a[2];

                    switch (group.SetField(field, strValue))
                    {
                    case ChatGroup.Field.SetValueResult.Success:
                        SaveData(ChatGroups);
                        player.ReplyLang("Group Field Changed", new Dictionary <string, string> {
                            ["group"] = group.GroupName, ["field"] = field, ["value"] = strValue
                        });
                        break;

                    case ChatGroup.Field.SetValueResult.InvalidField:
                        player.ReplyLang("Invalid Field", new KeyValuePair <string, string>("field", field));
                        break;

                    case ChatGroup.Field.SetValueResult.InvalidValue:
                        player.ReplyLang("Invalid Value", new Dictionary <string, string> {
                            ["field"] = field, ["value"] = strValue, ["type"] = ChatGroup.Fields[field].UserFriendyType
                        });
                        break;
                    }
                },
                ["group list"] = a =>
                {
                    player.Reply(string.Join(", ", ChatGroups.Select(g => g.GroupName).ToArray()));
                },
                ["group"]    = a => player.Reply($"Syntax: {cmd} group <add|remove|set|list>"),
                ["user add"] = a => {
                    if (a.Length != 2)
                    {
                        player.Reply($"Syntax: {cmd} user add <username|id> <group>");
                        return;
                    }

                    IPlayer targetPlayer = GetPlayer(a[0], player);

                    if (targetPlayer == null)
                    {
                        return;
                    }

                    string    groupName = a[1].ToLower();
                    ChatGroup group     = ChatGroup.Find(groupName);

                    if (group == null)
                    {
                        player.ReplyLang("Group Does Not Exist", new KeyValuePair <string, string>("group", groupName));
                        return;
                    }

                    if (permission.UserHasGroup(targetPlayer.Id, groupName))
                    {
                        player.ReplyLang("Player Already In Group", new Dictionary <string, string> {
                            ["player"] = targetPlayer.Name, ["group"] = groupName
                        });
                        return;
                    }

                    group.AddUser(targetPlayer);
                    player.ReplyLang("Added To Group", new Dictionary <string, string> {
                        ["player"] = targetPlayer.Name, ["group"] = groupName
                    });
                },
                ["user remove"] = a => {
                    if (a.Length != 2)
                    {
                        player.Reply($"Syntax: {cmd} user remove <username|id> <group>");
                        return;
                    }

                    IPlayer targetPlayer = GetPlayer(a[0], player);

                    if (targetPlayer == null)
                    {
                        return;
                    }

                    string    groupName = a[1].ToLower();
                    ChatGroup group     = ChatGroup.Find(groupName);

                    if (group == null)
                    {
                        player.ReplyLang("Group Does Not Exist", new KeyValuePair <string, string>("group", groupName));
                        return;
                    }

                    if (!permission.UserHasGroup(targetPlayer.Id, groupName))
                    {
                        player.ReplyLang("Player Not In Group", new Dictionary <string, string> {
                            ["player"] = targetPlayer.Name, ["group"] = groupName
                        });
                        return;
                    }

                    group.RemoveUser(targetPlayer);
                    player.ReplyLang("Removed From Group", new Dictionary <string, string> {
                        ["player"] = targetPlayer.Name, ["group"] = groupName
                    });
                },
                ["user"] = a => player.Reply($"Syntax: {cmd} user <add|remove>")
            };

            var    command       = commands.First(c => argsStr.ToLower().StartsWith(c.Key));
            string remainingArgs = argsStr.Remove(0, command.Key.Length);

            command.Value(remainingArgs.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray());
        }
 private Dictionary <string, object> API_GetGroupFields(string group) => ChatGroup.Find(group)?.GetFields() ?? new Dictionary <string, object>();
 private ChatGroup.Field.SetValueResult?API_SetGroupField(string group, string field, string value) => ChatGroup.Find(group)?.SetField(field, value);
 private bool API_GroupExists(string group) => ChatGroup.Find(group) != null;