mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-24 21:46:52 +01:00
Merge pull request #139 from tgstation/BetterKajiggers
Chages relay API from shell() and sockets to call() and the interface DLL
This commit is contained in:
Generated
+1902
-1946
File diff suppressed because it is too large
Load Diff
+482
-503
@@ -1,503 +1,482 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using TGServiceInterface;
|
||||
|
||||
namespace TGControlPanel
|
||||
{
|
||||
partial class Main
|
||||
{
|
||||
enum FullUpdateAction
|
||||
{
|
||||
UpdateHard,
|
||||
UpdateMerge,
|
||||
UpdateHardTestmerge,
|
||||
Reset,
|
||||
Testmerge,
|
||||
}
|
||||
|
||||
FullUpdateAction fuAction;
|
||||
ushort testmergePR;
|
||||
string updateError;
|
||||
bool updatingFields = false;
|
||||
|
||||
string DDStatusString = null;
|
||||
void InitServerPage()
|
||||
{
|
||||
LoadServerPage();
|
||||
ServerTimer.Start();
|
||||
WorldStatusChecker.RunWorkerAsync();
|
||||
WorldStatusChecker.RunWorkerCompleted += WorldStatusChecker_RunWorkerCompleted;
|
||||
FullUpdateWorker.RunWorkerCompleted += FullUpdateWorker_RunWorkerCompleted;
|
||||
ServerPathTextbox.LostFocus += ServerPathTextbox_LostFocus;
|
||||
ServerPathTextbox.KeyDown += ServerPathTextbox_KeyDown;
|
||||
projectNameText.LostFocus += ProjectNameText_LostFocus;
|
||||
projectNameText.KeyDown += ProjectNameText_KeyDown;
|
||||
ServerStartBGW.RunWorkerCompleted += ServerStartBGW_RunWorkerCompleted;
|
||||
}
|
||||
|
||||
private void ServerStartBGW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
if (e.Result != null)
|
||||
MessageBox.Show((string)e.Result);
|
||||
}
|
||||
|
||||
private void ProjectNameText_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Enter)
|
||||
UpdateProjectName();
|
||||
}
|
||||
|
||||
private void ServerPathTextbox_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Enter)
|
||||
UpdateServerPath();
|
||||
}
|
||||
|
||||
private void FullUpdateWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
if (updateError != null)
|
||||
MessageBox.Show(updateError);
|
||||
UpdateHardButton.Enabled = true;
|
||||
UpdateMergeButton.Enabled = true;
|
||||
TestmergeButton.Enabled = true;
|
||||
UpdateTestmergeButton.Enabled = true;
|
||||
LoadServerPage();
|
||||
ServerTimer.Start();
|
||||
}
|
||||
|
||||
private void WorldStatusChecker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
if (DDStatusString != "Topic recieve error!" || ServerStatusLabel.Text == "OFFLINE")
|
||||
ServerStatusLabel.Text = DDStatusString;
|
||||
WorldStatusTimer.Start();
|
||||
}
|
||||
|
||||
private void CompileCancelButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var res = Server.GetComponent<ITGCompiler>().Cancel();
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
LoadServerPage();
|
||||
}
|
||||
|
||||
private void ServerPathTextbox_LostFocus(object sender, EventArgs e)
|
||||
{
|
||||
UpdateServerPath();
|
||||
}
|
||||
|
||||
void UpdateServerPath()
|
||||
{
|
||||
var Config = Server.GetComponent<ITGConfig>();
|
||||
if (updatingFields || ServerPathTextbox.Text.Trim() == Config.ServerDirectory())
|
||||
return;
|
||||
var DialogResult = MessageBox.Show("This will move the entire server installation.", "Confim", MessageBoxButtons.YesNo);
|
||||
if (DialogResult != DialogResult.Yes)
|
||||
return;
|
||||
MessageBox.Show(Config.MoveServer(ServerPathTextbox.Text) ?? "Success!");
|
||||
}
|
||||
|
||||
void LoadServerPage()
|
||||
{
|
||||
var RepoExists = Server.GetComponent<ITGRepository>().Exists();
|
||||
compileButton.Visible = RepoExists;
|
||||
initializeButton.Visible = RepoExists;
|
||||
NudgePortSelector.Visible = RepoExists;
|
||||
AutostartCheckbox.Visible = RepoExists;
|
||||
WebclientCheckBox.Visible = RepoExists;
|
||||
PortSelector.Visible = RepoExists;
|
||||
projectNameText.Visible = RepoExists;
|
||||
compilerProgressBar.Visible = RepoExists;
|
||||
CompilerStatusLabel.Visible = RepoExists;
|
||||
CompileCancelButton.Visible = RepoExists;
|
||||
NudgePortLabel.Visible = RepoExists;
|
||||
CompilerLabel.Visible = RepoExists;
|
||||
ProjectPathLabel.Visible = RepoExists;
|
||||
ServerPRLabel.Visible = RepoExists;
|
||||
ServerGStopButton.Visible = RepoExists;
|
||||
ServerStartButton.Visible = RepoExists;
|
||||
ServerGRestartButton.Visible = RepoExists;
|
||||
ServerRestartButton.Visible = RepoExists;
|
||||
PortLabel.Visible = RepoExists;
|
||||
ServerStopButton.Visible = RepoExists;
|
||||
TestmergeButton.Visible = RepoExists;
|
||||
ServerTestmergeInput.Visible = RepoExists;
|
||||
UpdateHardButton.Visible = RepoExists;
|
||||
UpdateMergeButton.Visible = RepoExists;
|
||||
UpdateTestmergeButton.Visible = RepoExists;
|
||||
ResetTestmerge.Visible = RepoExists;
|
||||
WorldAnnounceField.Visible = RepoExists;
|
||||
WorldAnnounceButton.Visible = RepoExists;
|
||||
|
||||
var DM = Server.GetComponent<ITGCompiler>();
|
||||
var DD = Server.GetComponent<ITGDreamDaemon>();
|
||||
var Config = Server.GetComponent<ITGConfig>();
|
||||
|
||||
if (updatingFields)
|
||||
return;
|
||||
try
|
||||
{
|
||||
updatingFields = true;
|
||||
|
||||
if (!ServerPathTextbox.Focused)
|
||||
ServerPathTextbox.Text = Config.ServerDirectory();
|
||||
|
||||
SecuritySelector.SelectedIndex = (int)DD.SecurityLevel();
|
||||
|
||||
if (!RepoExists)
|
||||
return;
|
||||
|
||||
var Online = DD.DaemonStatus() == TGDreamDaemonStatus.Online;
|
||||
ServerGStopButton.Enabled = Online;
|
||||
ServerGRestartButton.Enabled = Online;
|
||||
ServerStopButton.Enabled = Online;
|
||||
ServerRestartButton.Enabled = Online;
|
||||
|
||||
var ShuttingDown = DD.ShutdownInProgress();
|
||||
ServerGStopButton.Checked = ShuttingDown;
|
||||
|
||||
AutostartCheckbox.Checked = DD.Autostart();
|
||||
WebclientCheckBox.Checked = DD.Webclient();
|
||||
if (!PortSelector.Focused)
|
||||
PortSelector.Value = DD.Port();
|
||||
if (!projectNameText.Focused)
|
||||
projectNameText.Text = DM.ProjectName();
|
||||
|
||||
var val = Config.InteropPort(out string error);
|
||||
if (error != null)
|
||||
{
|
||||
updatingFields = false;
|
||||
NudgePortSelector.Value = 4567;
|
||||
updatingFields = true;
|
||||
MessageBox.Show("Error (I will try and recover): " + error);
|
||||
}
|
||||
else
|
||||
{
|
||||
NudgePortSelector.Value = val;
|
||||
updatingFields = true;
|
||||
}
|
||||
|
||||
switch (DM.GetStatus())
|
||||
{
|
||||
case TGCompilerStatus.Compiling:
|
||||
CompilerStatusLabel.Text = "Compiling...";
|
||||
compilerProgressBar.Style = ProgressBarStyle.Marquee;
|
||||
compileButton.Enabled = false;
|
||||
initializeButton.Enabled = false;
|
||||
CompileCancelButton.Enabled = true;
|
||||
break;
|
||||
case TGCompilerStatus.Initializing:
|
||||
CompilerStatusLabel.Text = "Initializing...";
|
||||
compilerProgressBar.Style = ProgressBarStyle.Marquee;
|
||||
compileButton.Enabled = false;
|
||||
initializeButton.Enabled = false;
|
||||
CompileCancelButton.Enabled = false;
|
||||
break;
|
||||
case TGCompilerStatus.Initialized:
|
||||
CompilerStatusLabel.Text = "Idle";
|
||||
compilerProgressBar.Style = ProgressBarStyle.Blocks;
|
||||
initializeButton.Enabled = true;
|
||||
compileButton.Enabled = true;
|
||||
CompileCancelButton.Enabled = false;
|
||||
break;
|
||||
case TGCompilerStatus.Uninitialized:
|
||||
CompilerStatusLabel.Text = "Uninitialized";
|
||||
compilerProgressBar.Style = ProgressBarStyle.Blocks;
|
||||
compileButton.Enabled = false;
|
||||
initializeButton.Enabled = true;
|
||||
CompileCancelButton.Enabled = false;
|
||||
break;
|
||||
default:
|
||||
CompilerStatusLabel.Text = "Unknown!";
|
||||
compilerProgressBar.Style = ProgressBarStyle.Blocks;
|
||||
initializeButton.Enabled = true;
|
||||
compileButton.Enabled = true;
|
||||
CompileCancelButton.Enabled = true;
|
||||
break;
|
||||
}
|
||||
error = DM.CompileError();
|
||||
if (error != null)
|
||||
MessageBox.Show("Error: " + error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
updatingFields = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ServerTimer_Tick(object sender, System.EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
LoadServerPage();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ServerTimer.Stop();
|
||||
Program.ServiceDisconnectException(ex);
|
||||
}
|
||||
}
|
||||
private void ProjectNameText_LostFocus(object sender, EventArgs e)
|
||||
{
|
||||
UpdateProjectName();
|
||||
}
|
||||
|
||||
void UpdateProjectName()
|
||||
{
|
||||
if (!updatingFields)
|
||||
Server.GetComponent<ITGCompiler>().SetProjectName(projectNameText.Text);
|
||||
}
|
||||
|
||||
private void PortSelector_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!updatingFields)
|
||||
Server.GetComponent<ITGDreamDaemon>().SetPort((ushort)PortSelector.Value);
|
||||
}
|
||||
|
||||
private void RunServerUpdate(FullUpdateAction fua, ushort tm = 0)
|
||||
{
|
||||
if (FullUpdateWorker.IsBusy)
|
||||
return;
|
||||
testmergePR = tm;
|
||||
fuAction = fua;
|
||||
initializeButton.Enabled = false;
|
||||
compileButton.Enabled = false;
|
||||
UpdateHardButton.Enabled = false;
|
||||
UpdateMergeButton.Enabled = false;
|
||||
TestmergeButton.Enabled = false;
|
||||
UpdateTestmergeButton.Enabled = false;
|
||||
compilerProgressBar.Style = ProgressBarStyle.Marquee;
|
||||
switch (fuAction)
|
||||
{
|
||||
case FullUpdateAction.Testmerge:
|
||||
CompilerStatusLabel.Text = String.Format("Testmerging pull request #{0}...", testmergePR);
|
||||
break;
|
||||
case FullUpdateAction.UpdateHard:
|
||||
CompilerStatusLabel.Text = String.Format("Updating Server (RESET)...");
|
||||
break;
|
||||
case FullUpdateAction.UpdateMerge:
|
||||
CompilerStatusLabel.Text = String.Format("Updating Server (MERGE)...");
|
||||
break;
|
||||
case FullUpdateAction.UpdateHardTestmerge:
|
||||
CompilerStatusLabel.Text = String.Format("Updating and testmerging pull request #{0}...", testmergePR);
|
||||
break;
|
||||
}
|
||||
ServerTimer.Stop();
|
||||
FullUpdateWorker.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private void InitializeButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!Server.GetComponent<ITGCompiler>().Initialize())
|
||||
MessageBox.Show("Unable to start initialization!");
|
||||
LoadServerPage();
|
||||
}
|
||||
private void CompileButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!Server.GetComponent<ITGCompiler>().Compile())
|
||||
MessageBox.Show("Unable to start compilation!");
|
||||
LoadServerPage();
|
||||
}
|
||||
//because of lol byond this can take some time...
|
||||
private void WorldStatusChecker_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Server.GetComponent<ITGRepository>().Exists())
|
||||
DDStatusString = "NOT INSTALLED";
|
||||
else
|
||||
DDStatusString = Server.GetComponent<ITGDreamDaemon>().StatusString(true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
DDStatusString = "ERROR";
|
||||
}
|
||||
}
|
||||
|
||||
private void WorldStatusTimer_Tick(object sender, System.EventArgs e)
|
||||
{
|
||||
WorldStatusTimer.Stop();
|
||||
WorldStatusChecker.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private void AutostartCheckbox_CheckedChanged(object sender, System.EventArgs e)
|
||||
{
|
||||
if (!updatingFields)
|
||||
Server.GetComponent<ITGDreamDaemon>().SetAutostart(AutostartCheckbox.Checked);
|
||||
}
|
||||
private void ServerStartButton_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
if (!ServerStartBGW.IsBusy)
|
||||
ServerStartBGW.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private void ServerStartBGW_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
e.Result = Server.GetComponent<ITGDreamDaemon>().Start();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
e.Result = ex.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private void ServerStopButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var DialogResult = MessageBox.Show("This will immediately shut down the server. Continue?", "Confim", MessageBoxButtons.YesNo);
|
||||
if (DialogResult == DialogResult.No)
|
||||
return;
|
||||
var res = Server.GetComponent<ITGDreamDaemon>().Stop();
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
}
|
||||
|
||||
private void ServerRestartButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var DialogResult = MessageBox.Show("This will immediately restart the server. Continue?", "Confim", MessageBoxButtons.YesNo);
|
||||
if (DialogResult == DialogResult.No)
|
||||
return;
|
||||
var res = Server.GetComponent<ITGDreamDaemon>().Restart();
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
}
|
||||
|
||||
private void ServerGStopButton_Checked(object sender, EventArgs e)
|
||||
{
|
||||
if (updatingFields)
|
||||
return;
|
||||
var DialogResult = MessageBox.Show("This will shut down the server when the current round ends. Continue?", "Confim", MessageBoxButtons.YesNo);
|
||||
if (DialogResult == DialogResult.No)
|
||||
return;
|
||||
Server.GetComponent<ITGDreamDaemon>().RequestStop();
|
||||
LoadServerPage();
|
||||
}
|
||||
|
||||
private void ServerGRestartButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var DialogResult = MessageBox.Show("This will restart the server when the current round ends. Continue?", "Confim", MessageBoxButtons.YesNo);
|
||||
if (DialogResult == DialogResult.No)
|
||||
return;
|
||||
Server.GetComponent<ITGDreamDaemon>().RequestRestart();
|
||||
}
|
||||
|
||||
|
||||
private void FullUpdateWorker_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
var Repo = Server.GetComponent<ITGRepository>();
|
||||
var DM = Server.GetComponent<ITGCompiler>();
|
||||
switch (fuAction)
|
||||
{
|
||||
case FullUpdateAction.Testmerge:
|
||||
updateError = Repo.MergePullRequest(testmergePR);
|
||||
if (updateError == null)
|
||||
{
|
||||
Repo.GenerateChangelog(out updateError);
|
||||
updateError = DM.Compile(true) ? updateError : "Compilation failed!";
|
||||
}
|
||||
break;
|
||||
case FullUpdateAction.UpdateHard:
|
||||
updateError = Repo.Update(true);
|
||||
if (updateError == null)
|
||||
{
|
||||
Repo.GenerateChangelog(out updateError);
|
||||
if (updateError == null)
|
||||
updateError = Repo.PushChangelog();
|
||||
updateError = DM.Compile(true) ? updateError : "Compilation failed!";
|
||||
}
|
||||
break;
|
||||
case FullUpdateAction.UpdateHardTestmerge:
|
||||
updateError = Repo.Update(true);
|
||||
if (updateError == null)
|
||||
{
|
||||
Repo.GenerateChangelog(out updateError);
|
||||
if (updateError == null)
|
||||
updateError = Repo.PushChangelog();
|
||||
updateError = Repo.MergePullRequest(testmergePR);
|
||||
if (updateError == null)
|
||||
{
|
||||
Repo.GenerateChangelog(out updateError);
|
||||
updateError = DM.Compile(true) ? updateError : "Compilation failed!";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FullUpdateAction.UpdateMerge:
|
||||
updateError = Repo.Update(false);
|
||||
if (updateError == null)
|
||||
{
|
||||
Repo.GenerateChangelog(out updateError);
|
||||
if (updateError == null)
|
||||
Repo.PushChangelog(); //not an error 99% of the time if this fails, just a dirty tree
|
||||
updateError = DM.Compile(true) ? updateError : "Compilation failed!";
|
||||
}
|
||||
break;
|
||||
case FullUpdateAction.Reset:
|
||||
updateError = Repo.Reset(true);
|
||||
if (updateError == null)
|
||||
{
|
||||
Repo.GenerateChangelog(out updateError);
|
||||
updateError = DM.Compile(true) ? updateError : "Compilation failed!";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void ResetTestmerge_Click(object sender, EventArgs e)
|
||||
{
|
||||
RunServerUpdate(FullUpdateAction.Reset);
|
||||
}
|
||||
|
||||
private void UpdateHardButton_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
RunServerUpdate(FullUpdateAction.UpdateHard);
|
||||
}
|
||||
|
||||
private void UpdateTestmergeButton_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
RunServerUpdate(FullUpdateAction.UpdateHardTestmerge, (ushort)ServerTestmergeInput.Value);
|
||||
}
|
||||
|
||||
private void UpdateMergeButton_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
RunServerUpdate(FullUpdateAction.UpdateMerge);
|
||||
}
|
||||
private void TestmergeButton_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
RunServerUpdate(FullUpdateAction.Testmerge, (ushort)ServerTestmergeInput.Value);
|
||||
}
|
||||
|
||||
private void NudgePortSelector_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!updatingFields)
|
||||
Server.GetComponent<ITGConfig>().SetInteropPort((ushort)NudgePortSelector.Value);
|
||||
}
|
||||
|
||||
private void SecuritySelector_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!updatingFields)
|
||||
if (!Server.GetComponent<ITGDreamDaemon>().SetSecurityLevel((TGDreamDaemonSecurity)SecuritySelector.SelectedIndex))
|
||||
MessageBox.Show("Security change will be applied after next server reboot.");
|
||||
}
|
||||
|
||||
private void WorldAnnounceButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var msg = WorldAnnounceField.Text;
|
||||
if (!String.IsNullOrWhiteSpace(msg))
|
||||
{
|
||||
var res = Server.GetComponent<ITGDreamDaemon>().WorldAnnounce(msg);
|
||||
if (res != null)
|
||||
{
|
||||
MessageBox.Show(res);
|
||||
return;
|
||||
}
|
||||
}
|
||||
WorldAnnounceField.Text = "";
|
||||
}
|
||||
|
||||
private void WebclientCheckBox_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!updatingFields)
|
||||
Server.GetComponent<ITGDreamDaemon>().SetWebclient(WebclientCheckBox.Checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using TGServiceInterface;
|
||||
|
||||
namespace TGControlPanel
|
||||
{
|
||||
partial class Main
|
||||
{
|
||||
enum FullUpdateAction
|
||||
{
|
||||
UpdateHard,
|
||||
UpdateMerge,
|
||||
UpdateHardTestmerge,
|
||||
Reset,
|
||||
Testmerge,
|
||||
}
|
||||
|
||||
FullUpdateAction fuAction;
|
||||
ushort testmergePR;
|
||||
string updateError;
|
||||
bool updatingFields = false;
|
||||
|
||||
string DDStatusString = null;
|
||||
void InitServerPage()
|
||||
{
|
||||
LoadServerPage();
|
||||
ServerTimer.Start();
|
||||
WorldStatusChecker.RunWorkerAsync();
|
||||
WorldStatusChecker.RunWorkerCompleted += WorldStatusChecker_RunWorkerCompleted;
|
||||
FullUpdateWorker.RunWorkerCompleted += FullUpdateWorker_RunWorkerCompleted;
|
||||
ServerPathTextbox.LostFocus += ServerPathTextbox_LostFocus;
|
||||
ServerPathTextbox.KeyDown += ServerPathTextbox_KeyDown;
|
||||
projectNameText.LostFocus += ProjectNameText_LostFocus;
|
||||
projectNameText.KeyDown += ProjectNameText_KeyDown;
|
||||
ServerStartBGW.RunWorkerCompleted += ServerStartBGW_RunWorkerCompleted;
|
||||
}
|
||||
|
||||
private void ServerStartBGW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
if (e.Result != null)
|
||||
MessageBox.Show((string)e.Result);
|
||||
}
|
||||
|
||||
private void ProjectNameText_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Enter)
|
||||
UpdateProjectName();
|
||||
}
|
||||
|
||||
private void ServerPathTextbox_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Enter)
|
||||
UpdateServerPath();
|
||||
}
|
||||
|
||||
private void FullUpdateWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
if (updateError != null)
|
||||
MessageBox.Show(updateError);
|
||||
UpdateHardButton.Enabled = true;
|
||||
UpdateMergeButton.Enabled = true;
|
||||
TestmergeButton.Enabled = true;
|
||||
UpdateTestmergeButton.Enabled = true;
|
||||
LoadServerPage();
|
||||
ServerTimer.Start();
|
||||
}
|
||||
|
||||
private void WorldStatusChecker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
if (DDStatusString != "Topic recieve error!" || ServerStatusLabel.Text == "OFFLINE")
|
||||
ServerStatusLabel.Text = DDStatusString;
|
||||
WorldStatusTimer.Start();
|
||||
}
|
||||
|
||||
private void CompileCancelButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var res = Server.GetComponent<ITGCompiler>().Cancel();
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
LoadServerPage();
|
||||
}
|
||||
|
||||
private void ServerPathTextbox_LostFocus(object sender, EventArgs e)
|
||||
{
|
||||
UpdateServerPath();
|
||||
}
|
||||
|
||||
void UpdateServerPath()
|
||||
{
|
||||
var Config = Server.GetComponent<ITGConfig>();
|
||||
if (updatingFields || ServerPathTextbox.Text.Trim() == Config.ServerDirectory())
|
||||
return;
|
||||
var DialogResult = MessageBox.Show("This will move the entire server installation.", "Confim", MessageBoxButtons.YesNo);
|
||||
if (DialogResult != DialogResult.Yes)
|
||||
return;
|
||||
MessageBox.Show(Config.MoveServer(ServerPathTextbox.Text) ?? "Success!");
|
||||
}
|
||||
|
||||
void LoadServerPage()
|
||||
{
|
||||
var RepoExists = Server.GetComponent<ITGRepository>().Exists();
|
||||
compileButton.Visible = RepoExists;
|
||||
initializeButton.Visible = RepoExists;
|
||||
AutostartCheckbox.Visible = RepoExists;
|
||||
WebclientCheckBox.Visible = RepoExists;
|
||||
PortSelector.Visible = RepoExists;
|
||||
projectNameText.Visible = RepoExists;
|
||||
compilerProgressBar.Visible = RepoExists;
|
||||
CompilerStatusLabel.Visible = RepoExists;
|
||||
CompileCancelButton.Visible = RepoExists;
|
||||
CompilerLabel.Visible = RepoExists;
|
||||
ProjectPathLabel.Visible = RepoExists;
|
||||
ServerPRLabel.Visible = RepoExists;
|
||||
ServerGStopButton.Visible = RepoExists;
|
||||
ServerStartButton.Visible = RepoExists;
|
||||
ServerGRestartButton.Visible = RepoExists;
|
||||
ServerRestartButton.Visible = RepoExists;
|
||||
PortLabel.Visible = RepoExists;
|
||||
ServerStopButton.Visible = RepoExists;
|
||||
TestmergeButton.Visible = RepoExists;
|
||||
ServerTestmergeInput.Visible = RepoExists;
|
||||
UpdateHardButton.Visible = RepoExists;
|
||||
UpdateMergeButton.Visible = RepoExists;
|
||||
UpdateTestmergeButton.Visible = RepoExists;
|
||||
ResetTestmerge.Visible = RepoExists;
|
||||
WorldAnnounceField.Visible = RepoExists;
|
||||
WorldAnnounceButton.Visible = RepoExists;
|
||||
|
||||
var DM = Server.GetComponent<ITGCompiler>();
|
||||
var DD = Server.GetComponent<ITGDreamDaemon>();
|
||||
var Config = Server.GetComponent<ITGConfig>();
|
||||
|
||||
if (updatingFields)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
updatingFields = true;
|
||||
|
||||
if (!ServerPathTextbox.Focused)
|
||||
ServerPathTextbox.Text = Config.ServerDirectory();
|
||||
|
||||
SecuritySelector.SelectedIndex = (int)DD.SecurityLevel();
|
||||
|
||||
if (!RepoExists)
|
||||
return;
|
||||
|
||||
var Online = DD.DaemonStatus() == TGDreamDaemonStatus.Online;
|
||||
ServerGStopButton.Enabled = Online;
|
||||
ServerGRestartButton.Enabled = Online;
|
||||
ServerStopButton.Enabled = Online;
|
||||
ServerRestartButton.Enabled = Online;
|
||||
|
||||
var ShuttingDown = DD.ShutdownInProgress();
|
||||
ServerGStopButton.Checked = ShuttingDown;
|
||||
|
||||
AutostartCheckbox.Checked = DD.Autostart();
|
||||
WebclientCheckBox.Checked = DD.Webclient();
|
||||
if (!PortSelector.Focused)
|
||||
PortSelector.Value = DD.Port();
|
||||
if (!projectNameText.Focused)
|
||||
projectNameText.Text = DM.ProjectName();
|
||||
|
||||
switch (DM.GetStatus())
|
||||
{
|
||||
case TGCompilerStatus.Compiling:
|
||||
CompilerStatusLabel.Text = "Compiling...";
|
||||
compilerProgressBar.Style = ProgressBarStyle.Marquee;
|
||||
compileButton.Enabled = false;
|
||||
initializeButton.Enabled = false;
|
||||
CompileCancelButton.Enabled = true;
|
||||
break;
|
||||
case TGCompilerStatus.Initializing:
|
||||
CompilerStatusLabel.Text = "Initializing...";
|
||||
compilerProgressBar.Style = ProgressBarStyle.Marquee;
|
||||
compileButton.Enabled = false;
|
||||
initializeButton.Enabled = false;
|
||||
CompileCancelButton.Enabled = false;
|
||||
break;
|
||||
case TGCompilerStatus.Initialized:
|
||||
CompilerStatusLabel.Text = "Idle";
|
||||
compilerProgressBar.Style = ProgressBarStyle.Blocks;
|
||||
initializeButton.Enabled = true;
|
||||
compileButton.Enabled = true;
|
||||
CompileCancelButton.Enabled = false;
|
||||
break;
|
||||
case TGCompilerStatus.Uninitialized:
|
||||
CompilerStatusLabel.Text = "Uninitialized";
|
||||
compilerProgressBar.Style = ProgressBarStyle.Blocks;
|
||||
compileButton.Enabled = false;
|
||||
initializeButton.Enabled = true;
|
||||
CompileCancelButton.Enabled = false;
|
||||
break;
|
||||
default:
|
||||
CompilerStatusLabel.Text = "Unknown!";
|
||||
compilerProgressBar.Style = ProgressBarStyle.Blocks;
|
||||
initializeButton.Enabled = true;
|
||||
compileButton.Enabled = true;
|
||||
CompileCancelButton.Enabled = true;
|
||||
break;
|
||||
}
|
||||
var error = DM.CompileError();
|
||||
if (error != null)
|
||||
MessageBox.Show("Error: " + error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
updatingFields = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ServerTimer_Tick(object sender, System.EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
LoadServerPage();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ServerTimer.Stop();
|
||||
Program.ServiceDisconnectException(ex);
|
||||
}
|
||||
}
|
||||
private void ProjectNameText_LostFocus(object sender, EventArgs e)
|
||||
{
|
||||
UpdateProjectName();
|
||||
}
|
||||
|
||||
void UpdateProjectName()
|
||||
{
|
||||
if (!updatingFields)
|
||||
Server.GetComponent<ITGCompiler>().SetProjectName(projectNameText.Text);
|
||||
}
|
||||
|
||||
private void PortSelector_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!updatingFields)
|
||||
Server.GetComponent<ITGDreamDaemon>().SetPort((ushort)PortSelector.Value);
|
||||
}
|
||||
|
||||
private void RunServerUpdate(FullUpdateAction fua, ushort tm = 0)
|
||||
{
|
||||
if (FullUpdateWorker.IsBusy)
|
||||
return;
|
||||
testmergePR = tm;
|
||||
fuAction = fua;
|
||||
initializeButton.Enabled = false;
|
||||
compileButton.Enabled = false;
|
||||
UpdateHardButton.Enabled = false;
|
||||
UpdateMergeButton.Enabled = false;
|
||||
TestmergeButton.Enabled = false;
|
||||
UpdateTestmergeButton.Enabled = false;
|
||||
compilerProgressBar.Style = ProgressBarStyle.Marquee;
|
||||
switch (fuAction)
|
||||
{
|
||||
case FullUpdateAction.Testmerge:
|
||||
CompilerStatusLabel.Text = String.Format("Testmerging pull request #{0}...", testmergePR);
|
||||
break;
|
||||
case FullUpdateAction.UpdateHard:
|
||||
CompilerStatusLabel.Text = String.Format("Updating Server (RESET)...");
|
||||
break;
|
||||
case FullUpdateAction.UpdateMerge:
|
||||
CompilerStatusLabel.Text = String.Format("Updating Server (MERGE)...");
|
||||
break;
|
||||
case FullUpdateAction.UpdateHardTestmerge:
|
||||
CompilerStatusLabel.Text = String.Format("Updating and testmerging pull request #{0}...", testmergePR);
|
||||
break;
|
||||
}
|
||||
ServerTimer.Stop();
|
||||
FullUpdateWorker.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private void InitializeButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!Server.GetComponent<ITGCompiler>().Initialize())
|
||||
MessageBox.Show("Unable to start initialization!");
|
||||
LoadServerPage();
|
||||
}
|
||||
private void CompileButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!Server.GetComponent<ITGCompiler>().Compile())
|
||||
MessageBox.Show("Unable to start compilation!");
|
||||
LoadServerPage();
|
||||
}
|
||||
//because of lol byond this can take some time...
|
||||
private void WorldStatusChecker_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Server.GetComponent<ITGRepository>().Exists())
|
||||
DDStatusString = "NOT INSTALLED";
|
||||
else
|
||||
DDStatusString = Server.GetComponent<ITGDreamDaemon>().StatusString(true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
DDStatusString = "ERROR";
|
||||
}
|
||||
}
|
||||
|
||||
private void WorldStatusTimer_Tick(object sender, System.EventArgs e)
|
||||
{
|
||||
WorldStatusTimer.Stop();
|
||||
WorldStatusChecker.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private void AutostartCheckbox_CheckedChanged(object sender, System.EventArgs e)
|
||||
{
|
||||
if (!updatingFields)
|
||||
Server.GetComponent<ITGDreamDaemon>().SetAutostart(AutostartCheckbox.Checked);
|
||||
}
|
||||
private void ServerStartButton_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
if (!ServerStartBGW.IsBusy)
|
||||
ServerStartBGW.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private void ServerStartBGW_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
e.Result = Server.GetComponent<ITGDreamDaemon>().Start();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
e.Result = ex.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private void ServerStopButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var DialogResult = MessageBox.Show("This will immediately shut down the server. Continue?", "Confim", MessageBoxButtons.YesNo);
|
||||
if (DialogResult == DialogResult.No)
|
||||
return;
|
||||
var res = Server.GetComponent<ITGDreamDaemon>().Stop();
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
}
|
||||
|
||||
private void ServerRestartButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var DialogResult = MessageBox.Show("This will immediately restart the server. Continue?", "Confim", MessageBoxButtons.YesNo);
|
||||
if (DialogResult == DialogResult.No)
|
||||
return;
|
||||
var res = Server.GetComponent<ITGDreamDaemon>().Restart();
|
||||
if (res != null)
|
||||
MessageBox.Show(res);
|
||||
}
|
||||
|
||||
private void ServerGStopButton_Checked(object sender, EventArgs e)
|
||||
{
|
||||
if (updatingFields)
|
||||
return;
|
||||
var DialogResult = MessageBox.Show("This will shut down the server when the current round ends. Continue?", "Confim", MessageBoxButtons.YesNo);
|
||||
if (DialogResult == DialogResult.No)
|
||||
return;
|
||||
Server.GetComponent<ITGDreamDaemon>().RequestStop();
|
||||
LoadServerPage();
|
||||
}
|
||||
|
||||
private void ServerGRestartButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var DialogResult = MessageBox.Show("This will restart the server when the current round ends. Continue?", "Confim", MessageBoxButtons.YesNo);
|
||||
if (DialogResult == DialogResult.No)
|
||||
return;
|
||||
Server.GetComponent<ITGDreamDaemon>().RequestRestart();
|
||||
}
|
||||
|
||||
|
||||
private void FullUpdateWorker_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
var Repo = Server.GetComponent<ITGRepository>();
|
||||
var DM = Server.GetComponent<ITGCompiler>();
|
||||
switch (fuAction)
|
||||
{
|
||||
case FullUpdateAction.Testmerge:
|
||||
updateError = Repo.MergePullRequest(testmergePR);
|
||||
if (updateError == null)
|
||||
{
|
||||
Repo.GenerateChangelog(out updateError);
|
||||
updateError = DM.Compile(true) ? updateError : "Compilation failed!";
|
||||
}
|
||||
break;
|
||||
case FullUpdateAction.UpdateHard:
|
||||
updateError = Repo.Update(true);
|
||||
if (updateError == null)
|
||||
{
|
||||
Repo.GenerateChangelog(out updateError);
|
||||
if (updateError == null)
|
||||
updateError = Repo.PushChangelog();
|
||||
updateError = DM.Compile(true) ? updateError : "Compilation failed!";
|
||||
}
|
||||
break;
|
||||
case FullUpdateAction.UpdateHardTestmerge:
|
||||
updateError = Repo.Update(true);
|
||||
if (updateError == null)
|
||||
{
|
||||
Repo.GenerateChangelog(out updateError);
|
||||
if (updateError == null)
|
||||
updateError = Repo.PushChangelog();
|
||||
updateError = Repo.MergePullRequest(testmergePR);
|
||||
if (updateError == null)
|
||||
{
|
||||
Repo.GenerateChangelog(out updateError);
|
||||
updateError = DM.Compile(true) ? updateError : "Compilation failed!";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FullUpdateAction.UpdateMerge:
|
||||
updateError = Repo.Update(false);
|
||||
if (updateError == null)
|
||||
{
|
||||
Repo.GenerateChangelog(out updateError);
|
||||
if (updateError == null)
|
||||
Repo.PushChangelog(); //not an error 99% of the time if this fails, just a dirty tree
|
||||
updateError = DM.Compile(true) ? updateError : "Compilation failed!";
|
||||
}
|
||||
break;
|
||||
case FullUpdateAction.Reset:
|
||||
updateError = Repo.Reset(true);
|
||||
if (updateError == null)
|
||||
{
|
||||
Repo.GenerateChangelog(out updateError);
|
||||
updateError = DM.Compile(true) ? updateError : "Compilation failed!";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void ResetTestmerge_Click(object sender, EventArgs e)
|
||||
{
|
||||
RunServerUpdate(FullUpdateAction.Reset);
|
||||
}
|
||||
|
||||
private void UpdateHardButton_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
RunServerUpdate(FullUpdateAction.UpdateHard);
|
||||
}
|
||||
|
||||
private void UpdateTestmergeButton_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
RunServerUpdate(FullUpdateAction.UpdateHardTestmerge, (ushort)ServerTestmergeInput.Value);
|
||||
}
|
||||
|
||||
private void UpdateMergeButton_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
RunServerUpdate(FullUpdateAction.UpdateMerge);
|
||||
}
|
||||
private void TestmergeButton_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
RunServerUpdate(FullUpdateAction.Testmerge, (ushort)ServerTestmergeInput.Value);
|
||||
}
|
||||
|
||||
private void SecuritySelector_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!updatingFields)
|
||||
if (!Server.GetComponent<ITGDreamDaemon>().SetSecurityLevel((TGDreamDaemonSecurity)SecuritySelector.SelectedIndex))
|
||||
MessageBox.Show("Security change will be applied after next server reboot.");
|
||||
}
|
||||
|
||||
private void WorldAnnounceButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var msg = WorldAnnounceField.Text;
|
||||
if (!String.IsNullOrWhiteSpace(msg))
|
||||
{
|
||||
var res = Server.GetComponent<ITGDreamDaemon>().WorldAnnounce(msg);
|
||||
if (res != null)
|
||||
{
|
||||
MessageBox.Show(res);
|
||||
return;
|
||||
}
|
||||
}
|
||||
WorldAnnounceField.Text = "";
|
||||
}
|
||||
|
||||
private void WebclientCheckBox_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!updatingFields)
|
||||
Server.GetComponent<ITGDreamDaemon>().SetWebclient(WebclientCheckBox.Checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+607
-594
File diff suppressed because it is too large
Load Diff
@@ -675,24 +675,6 @@ namespace TGServerService
|
||||
}
|
||||
}
|
||||
|
||||
//public api
|
||||
public string SetInteropPort(ushort port)
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (configLock)
|
||||
{
|
||||
File.WriteAllText(InteropConfig, port.ToString());
|
||||
}
|
||||
InitInterop();
|
||||
return null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return e.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public IList<MapSetting> MapSettings(out string error)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using TGServiceInterface;
|
||||
|
||||
@@ -37,6 +38,7 @@ namespace TGServerService
|
||||
//Only need 1 proc instance
|
||||
void InitDreamDaemon()
|
||||
{
|
||||
UpdateInterfaceDll(false);
|
||||
var Reattach = Properties.Settings.Default.ReattachToDD;
|
||||
if (Reattach)
|
||||
try
|
||||
@@ -46,10 +48,8 @@ namespace TGServerService
|
||||
throw new Exception("GetProcessById returned null!");
|
||||
TGServerService.WriteInfo("Reattached to running DD process!", TGServerService.EventID.DDReattachSuccess);
|
||||
SendMessage("DD: Update complete. Watch dog reactivated...", ChatMessageType.WatchdogInfo);
|
||||
|
||||
//start wd
|
||||
InitInterop();
|
||||
|
||||
//start wd
|
||||
RestartInProgress = true;
|
||||
currentPort = Properties.Settings.Default.ReattachPort;
|
||||
serviceCommsKey = Properties.Settings.Default.ReattachCommsKey;
|
||||
@@ -235,7 +235,6 @@ namespace TGServerService
|
||||
currentStatus = TGDreamDaemonStatus.HardRebooting;
|
||||
currentPort = 0;
|
||||
Proc.Close();
|
||||
ShutdownInterop();
|
||||
|
||||
if (AwaitingShutdown == ShutdownRequestPhase.Pinged)
|
||||
return;
|
||||
@@ -279,7 +278,6 @@ namespace TGServerService
|
||||
RestartInProgress = true;
|
||||
}
|
||||
Proc.Close();
|
||||
ShutdownInterop();
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
@@ -365,6 +363,16 @@ namespace TGServerService
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateInterfaceDll(bool overwrite)
|
||||
{
|
||||
var targetPath = Path.Combine(StaticDirs, InterfaceDLLName);
|
||||
if (File.Exists(targetPath) && !overwrite)
|
||||
return;
|
||||
//Copy the interface dll to the static dir
|
||||
var InterfacePath = Assembly.GetAssembly(typeof(DDInteropCallHolder)).Location;
|
||||
File.Copy(InterfacePath, targetPath, true);
|
||||
}
|
||||
|
||||
//used by Start and Watchdog to start a DD instance
|
||||
string StartImpl(bool watchdog)
|
||||
{
|
||||
@@ -382,7 +390,7 @@ namespace TGServerService
|
||||
GenCommsKey();
|
||||
StartingSecurity = (TGDreamDaemonSecurity)Config.ServerSecurity;
|
||||
Proc.StartInfo.Arguments = String.Format("{0} -port {1} {5}-close -verbose -params \"server_service={3}&server_service_version={4}\" -{2} -public", DMB, Config.ServerPort, SecurityWord(), serviceCommsKey, Version(), Config.Webclient ? "-webclient" : "");
|
||||
InitInterop();
|
||||
UpdateInterfaceDll(true);
|
||||
Proc.Start();
|
||||
|
||||
if (!Proc.WaitForInputIdle(DDHangStartTime * 1000))
|
||||
@@ -390,7 +398,6 @@ namespace TGServerService
|
||||
Proc.Kill();
|
||||
Proc.WaitForExit();
|
||||
Proc.Close();
|
||||
ShutdownInterop();
|
||||
currentStatus = TGDreamDaemonStatus.Offline;
|
||||
currentPort = 0;
|
||||
return String.Format("Server start is taking more than {0}s! Aborting!", DDHangStartTime);
|
||||
|
||||
@@ -11,15 +11,12 @@ using TGServiceInterface;
|
||||
namespace TGServerService
|
||||
{
|
||||
//handles talking between the world and us
|
||||
partial class TGStationServer
|
||||
partial class TGStationServer : ITGServiceBridge
|
||||
{
|
||||
object topicLock = new object();
|
||||
const int CommsKeyLen = 64;
|
||||
string serviceCommsKey; //regenerated every DD restart
|
||||
|
||||
Thread NudgeThread;
|
||||
object NudgeLock = new object();
|
||||
|
||||
//See code/modules/server_tools/server_tools.dm for command switch
|
||||
const string SCHardReboot = "hard_reboot"; //requests that dreamdaemon restarts when the round ends
|
||||
const string SCGracefulShutdown = "graceful_shutdown"; //requests that dreamdaemon stops when the round ends
|
||||
@@ -170,90 +167,18 @@ namespace TGServerService
|
||||
TGServerService.WriteInfo("Service Comms Key set to: " + serviceCommsKey, TGServerService.EventID.CommsKeySet);
|
||||
}
|
||||
|
||||
//Start listening for nudges on the configured port
|
||||
public void InitInterop()
|
||||
{
|
||||
lock (NudgeLock)
|
||||
{
|
||||
ShutdownInteropNoLock();
|
||||
NudgeThread = new Thread(new ThreadStart(NudgeHandler)) { IsBackground = true };
|
||||
NudgeThread.Start();
|
||||
}
|
||||
}
|
||||
|
||||
void ShutdownInterop()
|
||||
{
|
||||
lock (NudgeLock)
|
||||
{
|
||||
ShutdownInteropNoLock();
|
||||
}
|
||||
}
|
||||
|
||||
void ShutdownInteropNoLock()
|
||||
{
|
||||
if (NudgeThread != null)
|
||||
{
|
||||
NudgeThread.Abort();
|
||||
NudgeThread.Join();
|
||||
}
|
||||
}
|
||||
|
||||
void NudgeHandler()
|
||||
/// <inheritdoc />
|
||||
public bool InteropMessage(string command)
|
||||
{
|
||||
try
|
||||
{
|
||||
var np = InteropPort(out string error);
|
||||
if (error != null)
|
||||
{
|
||||
TGServerService.WriteError("Unable to start nudge handler: " + error, TGServerService.EventID.NudgeStartFail);
|
||||
return;
|
||||
}
|
||||
|
||||
using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
|
||||
{
|
||||
listener.Bind(new IPEndPoint(IPAddress.Any, np));
|
||||
listener.Listen(5);
|
||||
|
||||
// Start listening for connections.
|
||||
using (var clientConnected = new ManualResetEvent(false))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// Program is suspended while waiting for an incoming connection.
|
||||
clientConnected.Reset();
|
||||
listener.BeginAccept(delegate (IAsyncResult asyncResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var handler = listener.EndAccept(asyncResult))
|
||||
{
|
||||
|
||||
var bytes = new byte[1024];
|
||||
int bytesRec = handler.Receive(bytes);
|
||||
// Show the data on the console.
|
||||
HandleCommand(Encoding.ASCII.GetString(bytes, 0, bytesRec));
|
||||
|
||||
handler.Close();
|
||||
clientConnected.Set();
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{ }
|
||||
}, null);
|
||||
clientConnected.WaitOne();
|
||||
}
|
||||
}
|
||||
}
|
||||
HandleCommand(command);
|
||||
return true;
|
||||
}
|
||||
catch (ThreadAbortException)
|
||||
catch(Exception e)
|
||||
{
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
TGServerService.WriteError("Nudge handler thread crashed: " + e.ToString(), TGServerService.EventID.NudgeCrash);
|
||||
SendMessage("SERVICE: The relay handler crashed, I will attempt to restore it when the server reboots! Error: " + e.Message, ChatMessageType.AdminInfo);
|
||||
RequestRestart();
|
||||
TGServerService.WriteWarning(String.Format("Handle command for \"{0}\" failed: {1}", command, e.ToString()), TGServerService.EventID.InteropCallException);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,8 @@ namespace TGServerService
|
||||
SubmoduleReclone = 6600,
|
||||
Authentication = 6700,
|
||||
PreactionEvent = 6800,
|
||||
PreactionFail = 6900
|
||||
PreactionFail = 6900,
|
||||
InteropCallException = 7000,
|
||||
}
|
||||
|
||||
static TGServerService ActiveService; //So everyone else can write to our eventlog
|
||||
|
||||
@@ -273,22 +273,6 @@ namespace TGServiceInterface
|
||||
[OperationContract]
|
||||
string SetMapSettings(MapSetting newSetting);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the port DD uses to talk to the service
|
||||
/// </summary>
|
||||
/// <param name="error">null on success, error message on failure</param>
|
||||
/// <returns>The port DD uses to talk to the service or 0 on failure</returns>
|
||||
[OperationContract]
|
||||
ushort InteropPort(out string error);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the port DD uses to talk to the service
|
||||
/// </summary>
|
||||
/// <param name="port">The port DD uses to talk to the service</param>
|
||||
/// <returns>null on success, error message on failure</returns>
|
||||
[OperationContract]
|
||||
string SetInteropPort(ushort port);
|
||||
|
||||
/// <summary>
|
||||
/// Return the directory of the server on the host machine
|
||||
/// </summary>
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace TGServiceInterface
|
||||
/// <summary>
|
||||
/// List of types that can be used with GetComponen
|
||||
/// </summary>
|
||||
public static readonly IList<Type> ValidInterfaces = new List<Type> { typeof(ITGByond), typeof(ITGChat), typeof(ITGCompiler), typeof(ITGConfig), typeof(ITGDreamDaemon), typeof(ITGRepository), typeof(ITGSService), typeof(ITGConnectivity), typeof(ITGAdministration) };
|
||||
public static readonly IList<Type> ValidInterfaces = new List<Type> { typeof(ITGByond), typeof(ITGChat), typeof(ITGCompiler), typeof(ITGConfig), typeof(ITGDreamDaemon), typeof(ITGRepository), typeof(ITGSService), typeof(ITGConnectivity), typeof(ITGAdministration), typeof(ITGServiceBridge) };
|
||||
|
||||
/// <summary>
|
||||
/// Base name of the communication pipe
|
||||
@@ -62,15 +62,23 @@ namespace TGServiceInterface
|
||||
/// Returns the requested server component interface. This does not guarantee a successful connection
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the component to retrieve</typeparam>
|
||||
/// <returns></returns>
|
||||
/// <returns>The correct component</returns>
|
||||
public static T GetComponent<T>()
|
||||
{
|
||||
return GetComponentAndChannel<T>(out ChannelFactory<T> ignored);
|
||||
}
|
||||
|
||||
public static T GetComponentAndChannel<T>(out ChannelFactory<T> outChannel)
|
||||
{
|
||||
var ToT = typeof(T);
|
||||
if (!ValidInterfaces.Contains(ToT))
|
||||
throw new Exception("Invalid type!");
|
||||
var InterfaceName = typeof(T).Name;
|
||||
if (HTTPSURL == null)
|
||||
return new ChannelFactory<T>(new NetNamedPipeBinding { SendTimeout = new TimeSpan(0, 10, 0) }, new EndpointAddress(String.Format("net.pipe://localhost/{0}/{1}", MasterInterfaceName, InterfaceName))).CreateChannel();
|
||||
{
|
||||
outChannel = new ChannelFactory<T>(new NetNamedPipeBinding { SendTimeout = new TimeSpan(0, 10, 0) }, new EndpointAddress(String.Format("net.pipe://localhost/{0}/{1}", MasterInterfaceName, InterfaceName)));
|
||||
return outChannel.CreateChannel();
|
||||
}
|
||||
|
||||
//okay we're going over
|
||||
var binding = new WSHttpBinding();
|
||||
@@ -78,19 +86,19 @@ namespace TGServiceInterface
|
||||
binding.Security.Mode = requireAuth ? SecurityMode.TransportWithMessageCredential : SecurityMode.Transport; //do not require auth for a connectivity check
|
||||
binding.Security.Message.ClientCredentialType = requireAuth ? MessageCredentialType.UserName : MessageCredentialType.None;
|
||||
var address = new EndpointAddress(String.Format("https://{0}:{1}/{2}/{3}", HTTPSURL, HTTPSPort, MasterInterfaceName, InterfaceName));
|
||||
var cf = new ChannelFactory<T>(binding, address);
|
||||
outChannel = new ChannelFactory<T>(binding, address);
|
||||
if (requireAuth)
|
||||
{
|
||||
cf.Credentials.UserName.UserName = HTTPSUsername;
|
||||
cf.Credentials.UserName.Password = HTTPSPassword;
|
||||
outChannel.Credentials.UserName.UserName = HTTPSUsername;
|
||||
outChannel.Credentials.UserName.Password = HTTPSPassword;
|
||||
}
|
||||
#if DEBUG
|
||||
//allow self signed certs in debug mode
|
||||
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, error) => true;
|
||||
#endif
|
||||
return cf.CreateChannel();
|
||||
return outChannel.CreateChannel();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Used to test if the service is avaiable on the machine
|
||||
/// Note that state can technically change at any time
|
||||
@@ -104,7 +112,7 @@ namespace TGServiceInterface
|
||||
GetComponent<ITGConnectivity>().VerifyConnection();
|
||||
return null;
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
return e.ToString();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using RGiesecke.DllExport;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ServiceModel;
|
||||
|
||||
namespace TGServiceInterface
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Used by DD to access the interop API with call()()
|
||||
/// </summary>
|
||||
[ServiceContract]
|
||||
public interface ITGServiceBridge
|
||||
{
|
||||
/// <summary>
|
||||
/// Called from /world/ExportService(command)
|
||||
/// </summary>
|
||||
/// <param name="command">The command to run</param>
|
||||
/// <returns>true on success, false on failure</returns>
|
||||
[OperationContract]
|
||||
bool InteropMessage(string command);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the proc that DD calls to access <see cref="ITGServiceBridge"/>
|
||||
/// </summary>
|
||||
public class DDInteropCallHolder
|
||||
{
|
||||
/// <summary>
|
||||
/// The proc that DD calls to access <see cref="ITGServiceBridge"/>
|
||||
/// </summary>
|
||||
/// <param name="args">The arguments passed</param>
|
||||
/// <returns>0</returns>
|
||||
[DllExport("DDEntryPoint", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static int DDEntryPoint(int argc, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeParamIndex = 0)]string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
ChannelFactory<ITGServiceBridge> channel = null;
|
||||
try
|
||||
{
|
||||
Server.GetComponentAndChannel(out channel).InteropMessage(String.Join(" ", args));
|
||||
channel.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
if(channel != null)
|
||||
channel.Abort();
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,28 +12,32 @@
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<UseVSHostingProcess>true</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>tgs.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="RGiesecke.DllExport.Metadata, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8f52d83c1a22df51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\UnmanagedExports.1.2.7\lib\net\RGiesecke.DllExport.Metadata.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.ServiceModel" />
|
||||
@@ -53,9 +57,14 @@
|
||||
<Compile Include="Server.cs" />
|
||||
<Compile Include="..\Version.cs" />
|
||||
<Compile Include="Service.cs" />
|
||||
<Compile Include="ServiceBridge.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="tgs.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="../packages/UnmanagedExports.1.2.7/tools/RGiesecke.DllExport.targets" Condition="Exists('../packages/UnmanagedExports.1.2.7/tools/RGiesecke.DllExport.targets')" />
|
||||
</Project>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="UnmanagedExports" version="1.2.7" targetFramework="net452" />
|
||||
</packages>
|
||||
+7
-31
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26430.12
|
||||
VisualStudioVersion = 15.0.26430.15
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGServerService", "TGServerService\TGServerService.csproj", "{F32EDA25-0855-411C-AF5E-F0D042917E2D}"
|
||||
EndProject
|
||||
@@ -65,57 +65,33 @@ EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F32EDA25-0855-411C-AF5E-F0D042917E2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F32EDA25-0855-411C-AF5E-F0D042917E2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F32EDA25-0855-411C-AF5E-F0D042917E2D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F32EDA25-0855-411C-AF5E-F0D042917E2D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F32EDA25-0855-411C-AF5E-F0D042917E2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F32EDA25-0855-411C-AF5E-F0D042917E2D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F32EDA25-0855-411C-AF5E-F0D042917E2D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F32EDA25-0855-411C-AF5E-F0D042917E2D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{394E7643-6B8C-416F-AB18-95AC12648CDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{394E7643-6B8C-416F-AB18-95AC12648CDC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{394E7643-6B8C-416F-AB18-95AC12648CDC}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{394E7643-6B8C-416F-AB18-95AC12648CDC}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{394E7643-6B8C-416F-AB18-95AC12648CDC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{394E7643-6B8C-416F-AB18-95AC12648CDC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{394E7643-6B8C-416F-AB18-95AC12648CDC}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{394E7643-6B8C-416F-AB18-95AC12648CDC}.Release|x86.Build.0 = Release|Any CPU
|
||||
{89191F69-B18E-4B59-B72E-E12F9B6811A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{89191F69-B18E-4B59-B72E-E12F9B6811A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{89191F69-B18E-4B59-B72E-E12F9B6811A0}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{89191F69-B18E-4B59-B72E-E12F9B6811A0}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{89191F69-B18E-4B59-B72E-E12F9B6811A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{89191F69-B18E-4B59-B72E-E12F9B6811A0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{89191F69-B18E-4B59-B72E-E12F9B6811A0}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{89191F69-B18E-4B59-B72E-E12F9B6811A0}.Release|x86.Build.0 = Release|Any CPU
|
||||
{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}.Release|x86.Build.0 = Release|Any CPU
|
||||
{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}.Debug|Any CPU.Build.0 = Debug|x86
|
||||
{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{AC4E7E8B-F83A-481C-A8B0-8FA4E8AE59AB}.Release|Any CPU.Build.0 = Release|x86
|
||||
{154435F6-0890-42D4-9AEC-B743D4FBC1CB}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{154435F6-0890-42D4-9AEC-B743D4FBC1CB}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{154435F6-0890-42D4-9AEC-B743D4FBC1CB}.Debug|x86.Build.0 = Debug|x86
|
||||
{154435F6-0890-42D4-9AEC-B743D4FBC1CB}.Debug|Any CPU.Build.0 = Debug|x86
|
||||
{154435F6-0890-42D4-9AEC-B743D4FBC1CB}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{154435F6-0890-42D4-9AEC-B743D4FBC1CB}.Release|Any CPU.Build.0 = Release|x86
|
||||
{154435F6-0890-42D4-9AEC-B743D4FBC1CB}.Release|x86.ActiveCfg = Release|x86
|
||||
{154435F6-0890-42D4-9AEC-B743D4FBC1CB}.Release|x86.Build.0 = Release|x86
|
||||
{8956D4C3-BFB9-448E-BF5F-EE7E6F9996F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8956D4C3-BFB9-448E-BF5F-EE7E6F9996F9}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8956D4C3-BFB9-448E-BF5F-EE7E6F9996F9}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{8956D4C3-BFB9-448E-BF5F-EE7E6F9996F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8956D4C3-BFB9-448E-BF5F-EE7E6F9996F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8956D4C3-BFB9-448E-BF5F-EE7E6F9996F9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8956D4C3-BFB9-448E-BF5F-EE7E6F9996F9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8956D4C3-BFB9-448E-BF5F-EE7E6F9996F9}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
Reference in New Issue
Block a user