public async Task ReloadConfig(ObsidianContext ctx) { if (Globals.FileWriter.IsUsable) { string path = Path.Combine(Globals.WorkingDirectory, "config.json"); if (!Globals.FileWriter.FileExists(path)) { await Globals.FileWriter.WriteAllTextAsync(path, JsonConvert.SerializeObject(new Config(), Formatting.Indented)); await ctx.Player.SendMessageAsync("&aNew config file was generated, please fill it up and reload plugin. &d/cc reload"); } try { Globals.Config = JsonConvert.DeserializeObject <Config>(Globals.FileReader.ReadAllText(path)); if (Globals.FileWriter.FileExists(path)) { await ctx.Player.SendMessageAsync("&aConfig reloaded successfully"); } } catch (Exception e) { await ctx.Player.SendMessageAsync($"&cThere was an error while reloading plugin:\n{e.Message}\n{e.StackTrace}"); Globals.Config = new Config(); } } else { await ctx.Player.SendMessageAsync("&cFile writer isn't usable"); } }
public override bool TryParseArgument(string input, ObsidianContext context, out Position result) { result = default; var splitted = input.Split(' '); var location = new Position(); int count = 0; var ctx = context; foreach (var text in splitted) { if (double.TryParse(text, out var doubleResult)) { switch (count) { case 0: location.X = doubleResult; break; case 1: location.Y = doubleResult; break; case 2: location.Z = doubleResult; break; default: throw new IndexOutOfRangeException("Count went out of range"); } } else if (text.Equals("~")) { var player = (Player)ctx.Player; switch (count) { case 0: location.X = player.Location.X; break; case 1: location.Y = player.Location.Y; break; case 2: location.Z = player.Location.Z; break; default: throw new IndexOutOfRangeException("Count went out of range"); } } count++; } result = location; return(true); }
public async Task ChatColor(ObsidianContext ctx) { var chatFormat = Globals.Config.ChatFormat .Replace("{PLAYER}", ctx.Player.Username) .Replace("{MESSAGE}", "Woop dee doo"); await ctx.Player.SendMessageAsync($"&dChatColor &av{Globals.PluginInfo.Version}\n" + $"&bCurrent chat format:&r {chatFormat}"); }
internal async Task ParseMessage(string message, Client source, sbyte position = 0) { if (!CommandUtilities.HasPrefix(message, '/', out string output)) { await this.BroadcastAsync($"<{source.Player.Username}> {message}", position); return; } //TODO command logging var context = new ObsidianContext(source, this, this.Services); IResult result = await Commands.ExecuteAsync(output, context); if (!result.IsSuccessful) { await context.Player.SendMessageAsync($"{ChatColor.Red}Command error: {(result as FailedResult).Reason}", position); } }
public async Task TestCmd(ObsidianContext ctx, string arg) { switch (arg) { case "reload": try { Globals.Config = await ConfigManager.LoadConfig(); await ctx.Player.SendMessageAsync($"§aConfig reloaded successfully"); await Broadcaster.StartBroadcasting(); } catch (Exception e) { await ctx.Player.SendMessageAsync($"§cAn error occurred when loading a config. Broadcasting stopped\n{e.Message}"); Broadcaster.StopBroadcasting(); } break; default: case "about": var msg = IChatMessage.CreateNew(); msg.Text = "§aObsidian Announcer §f- §dInterval auto announcement for JSON messages"; var clickComponent = ITextComponent.CreateNew(); clickComponent.Action = ETextAction.OpenUrl; clickComponent.Value = "https://github.com/roxxel/ObsidianAnnouncer"; var hoverComponent = ITextComponent.CreateNew(); hoverComponent.Action = ETextAction.ShowText; hoverComponent.Value = "§aPlugin github repo"; msg.HoverEvent = hoverComponent; msg.ClickEvent = clickComponent; await ctx.Player.SendMessageAsync(msg); break; } }
public override bool TryParseArgument(string input, ObsidianContext context, out IPlayer result) { var ctx = context; var server = (Server)ctx.Server; Player player = null; if (Guid.TryParse(input, out Guid guid)) { // is valid GUID, try find with guid server.OnlinePlayers.TryGetValue(guid, out player); } else { // is not valid guid, try find with name player = server.OnlinePlayers.FirstOrDefault(x => x.Value.Username == input).Value; } result = player; return(true); }
public override bool TryParseArgument(string input, ObsidianContext ctx, out string result) { result = input; return(true); }
public async Task ping(ObsidianContext ctx, int arg1, string arg2) { arg1out = arg1; arg2out = arg2; }
public async Task ping(ObsidianContext ctx, int arg1, string arg2, string arg3) { }
public async Task ping(ObsidianContext ctx, int arg1, int arg2) { }
public virtual async Task <bool> RunChecksAsync(ObsidianContext ctx) { throw new Exception($"RunChecksAsync was not implemented for {this.GetType().Name}!"); }
/// <summary> /// Executes this command. /// </summary> /// <typeparam name="T">Context type.</typeparam> /// <param name="Context">Execution context.</param> /// <returns></returns> public async Task ExecuteAsync(ObsidianContext context, string[] args) { // Find matching overload if (!this.Overloads.Any(x => x.GetParameters().Count() - 1 == args.Count() || x.GetParameters().Last().GetCustomAttribute <RemainingAttribute>() != null)) { throw new InvalidCommandOverloadException($"No such overload for command {this.GetQualifiedName()}"); } var method = this.Overloads.First(x => x.GetParameters().Count() - 1 == args.Count() || x.GetParameters().Last().GetCustomAttribute <RemainingAttribute>() != null); // create instance of declaring type to execute. var obj = Activator.CreateInstance(method.DeclaringType); // Get required params var methodparams = method.GetParameters().Skip(1).ToArray(); // Set first parameter to be the context. var parsedargs = new object[methodparams.Length + 1]; parsedargs[0] = context; // TODO comments for (int i = 0; i < methodparams.Length; i++) { // Current param and arg var paraminfo = methodparams[i]; var arg = args[i]; // This can only be true if we get a [Remaining] arg. Sets arg to remaining text. if (args.Length > methodparams.Length && i == methodparams.Length - 1) { arg = string.Join(' ', args.Skip(i)); } // Checks if there is any valid registered command handler if (this.Handler._argumentParsers.Any(x => x.GetType().BaseType.GetGenericArguments()[0] == paraminfo.ParameterType)) { // Gets parser var parsertype = this.Handler._argumentParsers.First(x => x.GetType().BaseType.GetGenericArguments()[0] == paraminfo.ParameterType).GetType(); var parser = Activator.CreateInstance(parsertype); // sets args for parser method var parseargs = new object[3] { (object)arg, (object)context, null }; // cast with reflection? if ((bool)parsertype.GetMethod("TryParseArgument").Invoke(parser, parseargs)) { // parse success! parsedargs[i + 1] = parseargs[2]; } else { // Argument can't be parsed to the parser's type. throw new CommandArgumentParsingException($"Argument '{arg}' was not parseable to {paraminfo.ParameterType.Name}!"); } } else { throw new NoSuchParserException($"No valid argumentparser found for type {paraminfo.ParameterType.Name}!"); } } // do execution checks var checks = method.GetCustomAttributes <BaseExecutionCheckAttribute>(); foreach (var c in checks) { if (!await c.RunChecksAsync(context)) { // A check failed. // TODO: Tell user what arg failed? throw new CommandExecutionCheckException($"One or more execution checks failed."); } } // await the command with it's args var task = (Task)method.Invoke(obj, parsedargs); await task; }
public override bool TryParseArgument(string input, ObsidianContext ctx, out decimal result) => decimal.TryParse(input, out result);
internal async Task ParseMessageAsync(string message, Client source, sbyte position = 0) { if (!message.StartsWith('/')) { await this.BroadcastAsync($"<{source.Player.Username}> {message}", position); return; } // TODO command logging // TODO error handling for commands var context = new ObsidianContext(message, source, this); try { await Commands.ProcessCommand(context); } catch (CommandArgumentParsingException) { await source.Player.SendMessageAsync(new ChatMessage() { Text = $"{ChatColor.Red}Invalid arguments! Parsing failed." }); } catch (CommandExecutionCheckException) { await source.Player.SendMessageAsync(new ChatMessage() { Text = $"{ChatColor.Red}You can not execute this command." }); } catch (CommandNotFoundException) { await source.Player.SendMessageAsync(new ChatMessage() { Text = $"{ChatColor.Red}No such command was found." }); } catch (NoSuchParserException) { await source.Player.SendMessageAsync(new ChatMessage() { Text = $"{ChatColor.Red}The command you executed has a argument that has no matching parser." }); } catch (InvalidCommandOverloadException) { await source.Player.SendMessageAsync(new ChatMessage() { Text = $"{ChatColor.Red}No such overload is available for this command." }); } catch (Exception e) { await source.Player.SendMessageAsync(new ChatMessage() { Text = $"{ChatColor.Red}Critically failed executing command: {e.Message}" }); Logger.LogError(e, e.Message); } }
public override bool TryParseArgument(string input, ObsidianContext ctx, out short result) => short.TryParse(input, out result);
public override bool TryParseArgument(string input, ObsidianContext ctx, out ulong result) => ulong.TryParse(input, out result);
public async Task ChatDeleteAsync(ObsidianContext Context, EChatDeleteArguments arg0) { var player = Context.Player; var chatMessage = new ChatMessage(); switch (arg0) { case EChatDeleteArguments.Delete: case EChatDeleteArguments.Clear: case EChatDeleteArguments.C: var clr_msg = Globals.Config.Messages.Clear.Split("{0}"); chatMessage = new ChatMessage(); chatMessage.AddExtra(new ChatMessage { Text = $"{clr_msg[0]}" }); //chatMessage.AddExtra(new ChatMessage { Text = $"{ChatColor.Gray}Chat successfully deleted by " }); var user = new ChatMessage { Text = $"{ChatColor.Red}{player.Username}{ChatColor.Gray}", HoverEvent = new TextComponent { Action = ETextAction.ShowText, Value = $"{DateTime.Now.ToShortDateString()}" } }; chatMessage.AddExtra(user); chatMessage.AddExtra(new ChatMessage { Text = $"{clr_msg[1]}" }); //chatMessage.AddExtra(new ChatMessage { Text = $"{ChatColor.Gray}." }); await Context.Server.BroadcastAsync(JsonConvert.SerializeObject(chatMessage)); break; case EChatDeleteArguments.Help: #region Command list var cmds = new Dictionary <String, String>(); cmds.Add("help", "Shows this list."); cmds.Add("clear", "Clears the chat."); cmds.Add("delete", "Clears the chat."); cmds.Add("reload", "Reload plugin configuration."); #endregion chatMessage = new ChatMessage(); chatMessage.AddExtra(new ChatMessage { Text = $"{Globals.Config.Prefix}{ChatColor.Gray}Plugin commands:" }); #region Build per command message. for (int i = 0; i < cmds.Count; i++) { var cmd = cmds.ToArray()[i]; var cmdargname = new ChatMessage { Text = $"{ChatColor.Red}/chatdelete {cmd.Key}{ChatColor.Reset} ", HoverEvent = new TextComponent { Action = ETextAction.ShowText, Value = $"{DateTime.Now.ToShortDateString()}" } }; chatMessage.AddExtra(cmdargname); var cmdargdesc = new ChatMessage { Text = $"{ChatColor.Gray}{cmd.Value}{ChatColor.Reset}\n", HoverEvent = new TextComponent { Action = ETextAction.ShowText, Value = $"{DateTime.Now.ToShortDateString()}" } }; chatMessage.AddExtra(cmdargdesc); } #endregion break; case EChatDeleteArguments.Reload: break; default: break; } }
public async Task MyCommandAsync(ObsidianContext ctx) { await ctx.Player.SendMessageAsync("Hello from plugin command!"); }
public override bool TryParseArgument(string input, ObsidianContext ctx, out Guid result) { return(Guid.TryParse(input, out result)); }