Skip to content
55 changes: 35 additions & 20 deletions Essentials/AutoCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,6 @@ public string Name
set => SetValue(ref _name, value);
}

//[Display(Name = "Scheduled Time", GroupName = "Schedule", Description = "Sets a time of day for this command to be run. Format is HH:MM:SS. MUST use 24 hour format! Will be reset to zero if Interval is set.")]
[Display(Visible = false)]
public string ScheduledTime
{
get => _scheduledTime.ToString();
set
{
_scheduledTime = TimeSpan.Parse(value);
OnPropertyChanged();
}
}

[Display(Order = 2, Description = "Sets an interval/Time for this command to be repeated. Format is HH:MM:SS.")]
public string Interval
{
Expand All @@ -79,7 +67,6 @@ public string Interval
OnPropertyChanged();
if (CommandTrigger == Trigger.Timed)
{
//ScheduledTime = TimeSpan.Zero.ToString(); //I hate myself for this **FIXED!!!***
_nextRun = DateTime.Now + _interval;
}

Expand Down Expand Up @@ -157,6 +144,7 @@ public void Update()

if (_currentStep < Steps.Count) return;
_currentStep = 0;
_cTokenSource?.Dispose();
_nextRun = _trigger == Trigger.Scheduled
? DateTime.Now.Date + _interval + TimeSpan.FromDays(1)
: _nextRun = DateTime.Now + _interval;
Expand Down Expand Up @@ -204,26 +192,54 @@ public override string ToString()
}
}

private CancellationTokenSource _cTokenSource;

/// <summary>
/// Runs the command and all steps immediately, in a new thread
/// </summary>
internal void RunNow()
internal async void RunNow()
{
Task.Run(() =>
_cTokenSource = new CancellationTokenSource();
var token = _cTokenSource.Token;

await Task.Run(() =>
{
foreach (var step in Steps)
while (!token.IsCancellationRequested)
{
step.RunStep();
Thread.Sleep(step.DelaySpan);
foreach (var step in Steps)
{
if (token.IsCancellationRequested)
{
break;
}
step.RunStep();
Thread.Sleep(step.DelaySpan);
}
}
});
}, token);

_cTokenSource.Dispose();
}

internal void Cancel()
{
Log.Info($"Cancelling autocommand {_name}");
_cTokenSource?.Cancel();
_currentStep = 0;
_nextRun = _trigger == Trigger.Scheduled
? DateTime.Now.Date + _interval + TimeSpan.FromDays(1)
: _nextRun = DateTime.Now + _interval;
}

public override string ToString()
{
return $"{Name} : {_trigger.ToString()} : {Steps.Count}";
}

internal bool IsRunning()
{
return _currentStep > 0 || _cTokenSource != null && _cTokenSource?.IsCancellationRequested == false;
}
}

public enum Gtl
Expand All @@ -233,7 +249,6 @@ public enum Gtl
Equal
}

//TODO Remove Scheduled
public enum Trigger
{
Disabled,
Expand Down
9 changes: 5 additions & 4 deletions Essentials/AutoCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,16 @@ public void Start()

private bool CanRun(AutoCommand command)
{
if (MySession.Static?.Ready == false) return false;

switch (command.CommandTrigger)
{
case Trigger.Disabled:
return false;
case Trigger.OnStart:
if (command.Completed || MySession.Static?.Ready == false)break;
if (command.Completed)break;
command.Completed = true;
command.RunNow();

break;
case Trigger.Vote:
break;
Expand All @@ -73,11 +74,11 @@ private bool CanRun(AutoCommand command)

if (command.Compare == GreaterThan)
{
return MySession.Static.Players.GetOnlinePlayerCount() > command.TriggerCount;
return MySession.Static?.Players.GetOnlinePlayerCount() > command.TriggerCount;
}
else if (command.Compare == LessThan)
{
return MySession.Static.Players.GetOnlinePlayerCount() < command.TriggerCount;
return MySession.Static?.Players.GetOnlinePlayerCount() < command.TriggerCount;
}
break;

Expand Down
105 changes: 102 additions & 3 deletions Essentials/Commands/AdminModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,119 @@ public void ListPlayers()
}


[Command("runauto", "Runs the auto command with the given name immediately")]
[Command("runauto", "Runs the auto command with the given commandName immediately")]
[Permission(MyPromoteLevel.Admin)]
public void RunAuto(string name)
{
var command = EssentialsPlugin.Instance.Config.AutoCommands.FirstOrDefault(c => c.Name.Equals(name));
if (command == null)
{
Context.Respond($"Couldn't find an auto command with the name {name}");
Context.Respond($"Couldn't find an auto command with the commandName {name}");
return;
}

Context.Respond($"Running the autocommand {command.Name}");
command.RunNow();
}

[Command("cancelauto", "Cancels the auto command with the given commandName immediately")]
[Permission(MyPromoteLevel.Admin)]
public void EndAuto(string commandName)
{
var command = EssentialsPlugin.Instance.Config.AutoCommands.FirstOrDefault(c => c.Name.Equals(commandName));
if (command == null)
{
Context.Respond($"Couldn't find an auto command with the commandName {commandName}");
return;
}
Context.Respond($"AutoCommand {command.Name} cancelled");
command.Cancel();
}

[Command("cancelautobyindex", "Cancels the auto command with the given index immediately")]
[Permission(MyPromoteLevel.Admin)]
public void EndByOrder(int commandNumber = 0)
{
var commands = new List<AutoCommand>(EssentialsPlugin.Instance.Config.AutoCommands.Where(x=>x.IsRunning()));

if (commands.Count == 0)
{
Context.Respond("No active autocommand found");
return;
}

if (commandNumber < 1 || commandNumber > commands.Count)
{
Context.Respond($"{commandNumber} number is out of range");
return;
}
var command = commands[commandNumber - 1];
if (command == null)
{
Context.Respond($"Couldn't find an auto command from provided number");
return;
}
Context.Respond($"AutoCommand {command.Name} cancelled");
command.Cancel();
}

[Command("listauto", "Lists all detected autocommands ")]
[Permission(MyPromoteLevel.Admin)]
public void ListAuto()
{
var commands = EssentialsPlugin.Instance.Config.AutoCommands;
StringBuilder sb = new StringBuilder();
int count = 1;

foreach (var command in commands)
{
sb.AppendLine((count++) + " " + command.Name);
}

if (Context.Player == null)
{
Context.Respond("Current AutoCommands:");
Context.Respond(sb.ToString());

}

else
{
ModCommunication.SendMessageTo(new DialogMessage("Current AutoCommands",$"Found {commands.Count} Commands",sb.ToString()), Context.Player.SteamUserId);
}
}

[Command("listrunningauto", "Lists all running autocommands ")]
[Permission(MyPromoteLevel.Admin)]
public void ListAutoRunning()
{
var commands = new List<AutoCommand>(EssentialsPlugin.Instance.Config.AutoCommands.Where(x=>x.IsRunning()));

if (commands.Count == 0)
{
Context.Respond("No active autocommand found");
return;
}
StringBuilder sb = new StringBuilder();
int count = 1;

foreach (var command in commands)
{
sb.AppendLine((count++) + " " + command.Name);
}

if (Context.Player == null)
{
Context.Respond("Current AutoCommands:");
Context.Respond(sb.ToString());

}

else
{
ModCommunication.SendMessageTo(new DialogMessage("Current AutoCommands",$"Found {commands.Count} Commands",sb.ToString()), Context.Player.SteamUserId);
}
}

[Command("set toolbar", "Makes your current toolbar the new default toolbar for new players.")]
[Permission(MyPromoteLevel.Admin)]
public void SetToolbar()
Expand Down
7 changes: 4 additions & 3 deletions Essentials/Commands/BlocksModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public void RemoveSubtype(string subtype)
}

foreach (var x in toRemove)
x.CubeGrid.RazeBlock(x.Position);
x.CubeGrid?.RemoveBlock(x);
Context.Respond($"Removed {toRemove.Count} blocks of subtype {subtype}.");
}

Expand All @@ -111,7 +111,7 @@ public void RemoveType(string type)
}

foreach (var x in toRemove)
x.CubeGrid.RazeBlock(x.Position);
x.CubeGrid?.RemoveBlock(x);
Context.Respond($"Removed {toRemove.Count} blocks of type {type}.");
}

Expand Down Expand Up @@ -211,7 +211,8 @@ public bool IsBlockTypeOf(MyFunctionalBlock block, BlockCategory category)
case BlockCategory.Power:
return block.BlockDefinition.Id.TypeId == typeof(MyObjectBuilder_Reactor) ||
block.BlockDefinition.Id.TypeId == typeof(MyObjectBuilder_BatteryBlock) ||
block.BlockDefinition.Id.TypeId == typeof(MyObjectBuilder_SolarPanel);
block.BlockDefinition.Id.TypeId == typeof(MyObjectBuilder_SolarPanel) ||
block.BlockDefinition.Id.TypeId == typeof(MyObjectBuilder_FueledPowerProducer);
case BlockCategory.Production:
return block.BlockDefinition.Id.TypeId == typeof(MyObjectBuilder_Assembler) ||
block.BlockDefinition.Id.TypeId == typeof(MyObjectBuilder_Refinery) ||
Expand Down