Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
86be6f6
Add cleanup filters "nopower" and "haspower". Add option to stop all …
rexxar-tc Jun 4, 2018
8773f93
Ask Jenkins to please build this against the Torch/client-mod branch.…
rexxar-tc Jun 11, 2018
2121aa6
Add !utility listgrids command to show the user all grids they own. C…
rexxar-tc Jun 11, 2018
e177313
Put MOTD in a dialog because that's nicer than chat.
rexxar-tc Jun 11, 2018
aa8322f
Add 'insideplanet' argument to grid cleanup. Finds grids that are mor…
rexxar-tc Jun 11, 2018
b3ed0f9
Add logging to cleanup
rexxar-tc Jun 11, 2018
250a28d
Remove !utlity listrids because !grids list is apparently a thing.
rexxar-tc Jun 11, 2018
661c8e7
Fix #25 !grids static large command not syncing
rexxar-tc Jun 11, 2018
fdb825a
Implement #38 : cleanup voxels with no grids nearby.
rexxar-tc Jun 11, 2018
10d2567
Add separate MOTD for new users.
rexxar-tc Jun 11, 2018
dfbc5dd
Make AutoCommands suck less.
rexxar-tc Jun 14, 2018
73053d2
Add !cleanup help command.
rexxar-tc Jun 16, 2018
2d9b0fe
Un-break cleanup.
rexxar-tc Jun 18, 2018
dd5b48c
Remove global static logger to make Equinox happy
rexxar-tc Jun 18, 2018
f7a9a21
Complete refactor of auto commands! I even tested it this time!
rexxar-tc Jul 3, 2018
5af3086
Fix a typo in autocommand helptext
rexxar-tc Jul 4, 2018
300dfea
!cleanup list now prints to a dialog window.
rexxar-tc Jul 4, 2018
8c05800
Implement info commands
rexxar-tc Jul 6, 2018
770f7d0
Fix crashes in autocommands
rexxar-tc Jul 6, 2018
6928828
client-mod branch deleted, build against master again
rexxar-tc Jul 7, 2018
58122b0
Add !voxels reset planets
rexxar-tc Jul 8, 2018
dcee1aa
Change cleanup conditions to public. Might change behavior??
rexxar-tc Jul 8, 2018
cf47d52
Fix borked cleanup
rexxar-tc Jul 9, 2018
d726efd
Add %player% wildcard to MOTD. Replaces with receiving player's name.
rexxar-tc Jul 9, 2018
085796f
Fix haspower check crashing with a key not present error
rexxar-tc Jul 9, 2018
de1542c
Add DayOfWeek option to auto commands.
rexxar-tc Jul 9, 2018
9921a0e
Don't be stupid and use ViewModels
rexxar-tc Jul 10, 2018
111442e
Default cleanup to not search for grids with pilots.
rexxar-tc Jul 18, 2018
ece8376
Delay sending MOTD until the player spawns with a character.
rexxar-tc Jul 18, 2018
d695c86
Be careful using copy and paste
Jimmacle Jul 19, 2018
9220a94
Fix entity refresh reflection
Jimmacle Jul 19, 2018
0bc78d2
Actually fix entities refresh command
Jimmacle Jul 19, 2018
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 163 additions & 34 deletions Essentials/AutoCommand.cs
Original file line number Diff line number Diff line change
@@ -1,66 +1,195 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using NLog;
using Torch;
using Torch.API;
using Torch.Commands;
using Torch.API.Managers;
using Torch.Commands;
using Torch.Server;
using Torch.Views;

namespace Essentials
{
public class AutoCommand : ViewModel, IDisposable
public class AutoCommand : ViewModel
{
private Timer _timer;

private TimeSpan _scheduledTime = TimeSpan.Zero;
private static readonly Logger Log = LogManager.GetLogger("Essentials");
private TimeSpan _interval = TimeSpan.Zero;
private DateTime _nextRun = DateTime.MinValue;
private DayOfWeek _day = DayOfWeek.All;
private int _currentStep;
private string _name;
private bool _enabled;
public bool Enabled { get => _enabled; set { _enabled = value; OnTimerChanged(); OnPropertyChanged(); } }
private string _command;
public string Command { get => _command; set { _command = value; OnTimerChanged(); OnPropertyChanged(); } }
private int _dueTime;
public int DueTime { get => _dueTime / 1000; set { _dueTime = value * 1000; OnTimerChanged(); OnPropertyChanged(); } }
private int _period;
public int Period { get => _period / 1000; set { _period = value * 1000; OnTimerChanged(); OnPropertyChanged(); } }

private void OnTimerChanged()

[Display(Description = "Enables or disables this command. NOTE: !admin runauto does NOT respect this setting!")]
public bool Enabled
{
get => _enabled;
set => SetValue(ref _enabled, value);
}

[Display(Description = "Sets the name of this command. Use this name in conjunction with !admin runauto to trigger the command from ingame or from other auto commands.")]
public string Name
{
_timer?.Dispose();
if (Enabled && Period > 0)
_timer = new Timer(RunCommand, this, _dueTime, _period);
get => _name;
set => SetValue(ref _name, value);
}

private void RunCommand(object state)
[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.")]
public string ScheduledTime
{
if (((TorchServer)TorchBase.Instance).State != ServerState.Running)
get => _scheduledTime.ToString();
set
{
_scheduledTime = TimeSpan.Parse(value);
OnPropertyChanged();
if (_scheduledTime != TimeSpan.Zero)
{
Interval = TimeSpan.Zero.ToString();
_nextRun = DateTime.Now.Date + _scheduledTime;
if (_nextRun < DateTime.Now)
_nextRun += TimeSpan.FromDays(1);
}
}
}

[Display(Description = "Sets an interval for this command to be repeated. Format is HH:MM:SS. Will be reset to zero if Scheduled Time is set!")]
public string Interval
{
get => _interval.ToString();
set
{
_interval = TimeSpan.Parse(value);
OnPropertyChanged();
if (_interval != TimeSpan.Zero)
{
ScheduledTime = TimeSpan.Zero.ToString(); //I hate myself for this
_nextRun = DateTime.Now + _interval;
}
}
}

[Display(Name = "Day of week", GroupName = "Schedule", Description = "Combined with Scheduled Time, will run the command on the given day of the week at the set time.")]
public DayOfWeek DayOfWeek
{
get => _day;
set => SetValue(ref _day, value);
}

[Display(Description = "Sub-command steps that will be iterated through once the Interval or Scheduled time is reached.")]
public ObservableCollection<CommandStep> Steps { get; } = new ObservableCollection<CommandStep>();

public AutoCommand()
{
Steps.CollectionChanged += (sender, args) => OnPropertyChanged();
}

public void Update()
{
if (DateTime.Now < _nextRun)
return;

//double cast here as I'm unsure how casting directly between enum types will work
if (DayOfWeek != DayOfWeek.All && DateTime.Now.DayOfWeek != (System.DayOfWeek)(int)DayOfWeek)
{
//adding one day because I can't be bothered to calculate exact interval
_nextRun += TimeSpan.FromDays(1);
return;
}

if (Steps.Count <= 0)
return;

var step = Steps[_currentStep];

step.RunStep();
_currentStep++;
_nextRun += step.DelaySpan;

var autoCommand = (AutoCommand)state;
TorchBase.Instance.Invoke(() =>
if (_currentStep >= Steps.Count)
{
var manager = TorchBase.Instance.CurrentSession.Managers.GetManager<CommandManager>();
manager?.HandleCommandFromServer(autoCommand.Command);
});
_currentStep = 0;
if (_scheduledTime != TimeSpan.Zero)
_nextRun = DateTime.Now.Date + _scheduledTime + TimeSpan.FromDays(1);
else
_nextRun = DateTime.Now + _interval;
}
}

~AutoCommand()
public class CommandStep : ViewModel
{
try
internal TimeSpan DelaySpan;
private string _command;

[Display(Description = "Delay AFTER this step and BEFORE the next step. Format is HH:MM:SS.")]
public string Delay
{
Dispose();
get => DelaySpan.ToString();
set => SetValue(ref DelaySpan, TimeSpan.Parse(value));
}
catch

[Display(Description = "Command to be run as the server.")]
public string Command
{
// ignored
get => _command;
set => SetValue(ref _command, value);
}

public void RunStep()
{
if (((TorchServer)EssentialsPlugin.Instance.Torch).State != ServerState.Running)
return;

if (string.IsNullOrEmpty(Command))
return;

EssentialsPlugin.Instance.Torch.Invoke(() =>
{
var manager = EssentialsPlugin.Instance.Torch.CurrentSession.Managers.GetManager<CommandManager>();
manager?.HandleCommandFromServer(Command);
});
}

public override string ToString()
{
return Command;
}
}


/// <summary>
/// Runs the command and all steps immediately, in a new thread
/// </summary>
internal void RunNow()
{
Task.Run(() =>
{
foreach (var step in Steps)
{
step.RunStep();
Thread.Sleep(step.DelaySpan);
}
});
}

/// <inheritdoc />
public void Dispose()
public override string ToString()
{
_timer?.Dispose();
return $"{Name} : {(Enabled ? "Enabled" : "Disabled")} : {Steps.Count}";
}
}

public enum DayOfWeek
{
All = -1,
Sunday = System.DayOfWeek.Sunday,
Monday = System.DayOfWeek.Monday,
Tuesday = System.DayOfWeek.Tuesday,
Wednesday = System.DayOfWeek.Wednesday,
Thursday = System.DayOfWeek.Thursday,
Friday = System.DayOfWeek.Friday,
Saturday = System.DayOfWeek.Saturday
}
}
49 changes: 49 additions & 0 deletions Essentials/AutoCommands.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using NLog;

namespace Essentials
{
public class AutoCommands : IDisposable
{
private static AutoCommands _instance;
public static AutoCommands Instance => _instance ?? (_instance = new AutoCommands());
private static readonly Logger Log = LogManager.GetLogger("Essentials");

private Timer _timer;

public void Start()
{
_timer = new Timer(1000);
_timer.Elapsed += TimerElapsed;
_timer.AutoReset = true;
_timer.Start();
}

private void TimerElapsed(object sender, ElapsedEventArgs e)
{
foreach (var command in EssentialsPlugin.Instance.Config.AutoCommands)
{
if(!command.Enabled)
continue;

try
{
command.Update();
}
catch (Exception ex)
{
Log.Error(ex, "Error encountered during autocommand update!");
}
}
}

public void Dispose()
{
_timer?.Dispose();
}
}
}
62 changes: 62 additions & 0 deletions Essentials/Commands/AdminModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Sandbox.Engine.Multiplayer;
using Torch.Commands;
using Torch.Commands.Permissions;
using Torch.Mod;
using Torch.Mod.Messages;
using VRage.Game.ModAPI;
using VRageRender.Utils;

namespace Essentials.Commands
{
[Category("admin")]
public class AdminModule : CommandModule
{
[Command("stats", "Get performance statistics of the server")]
[Permission(MyPromoteLevel.Admin)]
public void Statistics()
{
var sb = new StringBuilder();
sb.AppendLine("Generic:");
Stats.Generic.WriteTo(sb);
sb.AppendLine("Network:");
Stats.Network.WriteTo(sb);
sb.AppendLine("Timing:");
Stats.Timing.WriteTo(sb);

ModCommunication.SendMessageTo(new DialogMessage("Statistics", null, sb.ToString()) , Context.Player.SteamUserId);
}

[Command("playercount", "Gets or sets the max number of players on the server")]
[Permission(MyPromoteLevel.Admin)]
public void PlayerCount(int count = -1)
{
if (count == -1)
{
Context.Respond($"Nax player count: {MyMultiplayer.Static.MemberLimit}. Current online players: {MyMultiplayer.Static.MemberCount - 1}");
return;
}

MyMultiplayer.Static.MemberLimit = count;
Context.Respond($"Nax player count: {MyMultiplayer.Static.MemberLimit}. Current online players: {MyMultiplayer.Static.MemberCount - 1}");
}

[Command("runauto", "Runs the auto command with the given name 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}");
return;
}

command.RunNow();
}
}
}
Loading