Files
2020-04-09 14:35:16 +02:00

138 lines
4.6 KiB
C#

using System;
using System.Threading;
using System.IO;
using WebSocketSharp;
namespace PluginDevBuildTool
{
class Program
{
static int Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine(@"Usage: PluginDevBuildTool unload/reload ""c:\full\path\to\plugin.dp64""");
return 1;
}
var action = args[0];
switch (action)
{
case "unload":
case "reload":
break;
default:
Console.WriteLine($"PluginDevBuildTool: Invalid action \"{action}\"!");
return 1;
}
var pluginPath = args[1];
var pluginName = Path.GetFileName(pluginPath);
var fileInfo = new FileInfo(pluginPath);
if (!fileInfo.Exists)
{
if (action == "unload")
{
// No destination file = nothing to unload because it doesn't exist
return 0;
}
else
{
Console.WriteLine($"PluginDevBuildTool: \"{pluginPath}\" does not exist!");
return 1;
}
}
bool CanOpenExclusively()
{
try
{
using (var fs = fileInfo.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
}
return true;
}
catch
{
return false;
}
}
bool BroadcastIntention()
{
var result = true;
using (var ws = new WebSocket("ws://127.0.0.1:4649/PluginDevHelper"))
{
ws.OnError += (sender, e) =>
{
result = false;
};
ws.Log.Output = (d, s) =>
{
};
ws.Connect();
if(!ws.IsAlive)
return false;
ws.Send($"{action}:{pluginName}");
}
return result;
}
var unloadedPath = pluginPath + ".unloaded";
if (action == "unload")
{
// Nobody has this plugin loaded
if (CanOpenExclusively())
{
Console.WriteLine($"PluginDevBuildTool: Exclusive access to {pluginName} already obtained!");
return 0;
}
Console.WriteLine($"PluginDevBuildTool: Failed to obtain exclusive access, requesting to unload {pluginName}");
if (!BroadcastIntention())
{
Console.WriteLine("PluginDevBuildTool: Failed to send broadcast over websocket");
return 1;
}
// This value seemed to work instantly every time
Thread.Sleep(200);
// A 5 second unload time seems to be a reasonable limit
const int pollTimeout = 500;
const int totalTimeout = 5000;
for (var i = 0; i < totalTimeout / pollTimeout; i++)
{
if (CanOpenExclusively())
{
File.WriteAllText(unloadedPath, "1");
Console.WriteLine($"PluginDevBuildTool: Exclusive access to {pluginName} obtained!");
return 0;
}
Console.WriteLine($"PluginDevBuildTool: Waiting {pollTimeout}ms for exclusive access...");
Thread.Sleep(pollTimeout);
}
Console.WriteLine("PluginDevBuildTool: Failed to unload plugin...");
return 1;
}
else if (action == "reload")
{
if (File.Exists(unloadedPath))
{
File.Delete(unloadedPath);
if (!BroadcastIntention())
return 1;
Console.WriteLine($"PluginDevBuildTool: Requested reload of {pluginName}");
}
return 0;
}
else
{
throw new ArgumentException();
}
}
}
}