diff --git a/DMAPI/st_interface.dm b/DMAPI/st_interface.dm index b7bdda3364..237946a2b3 100644 --- a/DMAPI/st_interface.dm +++ b/DMAPI/st_interface.dm @@ -57,12 +57,11 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) ExportService(SERVICE_REQUEST_WORLD_REBOOT) //just let em know /world/proc/ServiceCommand(list/params) - var/sCK = RunningService() var/their_sCK = params[SERVICE_CMD_PARAM_KEY] - - if(!their_sCK) + if(!their_sCK || !RunningService(TRUE)) return FALSE //continue world/Topic + var/sCK = world.params[SERVICE_WORLD_PARAM] if(their_sCK != sCK) return "Invalid comms key!"; diff --git a/TGServerService/App.config b/TGServerService/App.config index 50b637af30..6b4ecc1601 100644 --- a/TGServerService/App.config +++ b/TGServerService/App.config @@ -56,7 +56,7 @@ 0 - 3 + 4 @@ -70,6 +70,9 @@ 38607 + + + diff --git a/TGServerService/DreamDaemon.cs b/TGServerService/DreamDaemon.cs index 37e67c0a2e..a0c10da0ef 100644 --- a/TGServerService/DreamDaemon.cs +++ b/TGServerService/DreamDaemon.cs @@ -53,10 +53,14 @@ namespace TGServerService RestartInProgress = true; currentPort = Properties.Settings.Default.ReattachPort; serviceCommsKey = Properties.Settings.Default.ReattachCommsKey; + try + { + GameAPIVersion = new Version(Properties.Settings.Default.ReattachAPIVersion); + } + catch { } currentStatus = TGDreamDaemonStatus.Online; DDWatchdog = new Thread(new ThreadStart(Watchdog)); DDWatchdog.Start(); - RequestRestart(); //TODO: Remove this when DD -> Service communication is more } catch (Exception e) { @@ -391,6 +395,10 @@ namespace TGServerService 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" : ""); UpdateInterfaceDll(true); + lock (topicLock) + { + GameAPIVersion = null; //needs updating + } Proc.Start(); if (!Proc.WaitForInputIdle(DDHangStartTime * 1000)) diff --git a/TGServerService/Interop.cs b/TGServerService/Interop.cs index 5cf968e842..121a762479 100644 --- a/TGServerService/Interop.cs +++ b/TGServerService/Interop.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; +using System.Threading; using System.Web.Script.Serialization; using System.Web.Security; using TGServiceInterface; @@ -18,8 +19,9 @@ namespace TGServerService string serviceCommsKey; //regenerated every DD restart //range of supported api versions - const string MinAPIVersion = "3.1.0.0"; - const string MaxAPIVersion = "3.1.0.99"; + readonly Version MinAPIVersion = new Version("3.1.0.0"); + readonly Version MaxAPIVersion = new Version("3.1.0.99"); + Version GameAPIVersion; //See code/modules/server_tools/server_tools.dm for command switch const string SCHardReboot = "hard_reboot"; //requests that dreamdaemon restarts when the round ends @@ -64,6 +66,15 @@ namespace TGServerService cmd = splits[0]; splits.RemoveAt(0); + bool APIValid; + lock (topicLock) + { + APIValid = CheckAPIVersionConstraints(); + } + + if (!APIValid && cmd != SRAPIVersion) + return; //SPEAK THE LANGUAGE!!! + switch (cmd) { case SRIRCBroadcast: @@ -84,24 +95,32 @@ namespace TGServerService if (UpdateStaged) { UpdateStaged = false; + lock (topicLock) + { + GameAPIVersion = null; //needs updating + } TGServerService.WriteInfo("Staged update applied", TGServerService.EventID.ServerUpdateApplied); } } break; case SRAPIVersion: - try + lock (topicLock) { - var theirs = new Version(splits[1]); - var minimum = new Version(MinAPIVersion); - var maximum = new Version(MaxAPIVersion); - if (theirs < minimum || theirs > maximum) - throw new Exception(); - SendCommand(SCAPICompat); - } - catch - { - TGServerService.WriteWarning("API version of the game ({0}) is incompatible with the current supported API versions (Min: {1}. Max: {2})", TGServerService.EventID.APIVersionMismatch); + try + { + GameAPIVersion = new Version(splits[0]); + if (!CheckAPIVersionConstraints()) + throw new Exception(); + } + catch + { + TGServerService.WriteWarning(String.Format("API version of the game ({0}) is incompatible with the current supported API versions (Min: {1}. Max: {2}). Interop disabled.", splits.Count > 1 ? splits[1] : "NULL", MinAPIVersion, MaxAPIVersion), TGServerService.EventID.APIVersionMismatch); + GameAPIVersion = null; + break; + } } + //This needs to be done asyncronously otherwise DD won't be able to process it, because it's waiting for THIS THREAD to return + ThreadPool.QueueUserWorkItem(_ => SendCommand(SCAPICompat)); break; } } @@ -116,10 +135,18 @@ namespace TGServerService } } + //requires topiclock + bool CheckAPIVersionConstraints() + { + return !(GameAPIVersion == null || GameAPIVersion < MinAPIVersion || GameAPIVersion > MaxAPIVersion); + } + //Fuckery to diddle byond with the right packet to accept our girth string SendTopic(string topicdata, ushort port) { lock (topicLock) { + if (!CheckAPIVersionConstraints()) + return "Incompatible API!"; using (var topicSender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { SendTimeout = 5000, ReceiveTimeout = 5000 }) { try diff --git a/TGServerService/Properties/Settings.Designer.cs b/TGServerService/Properties/Settings.Designer.cs index 7a36955962..7a76d2a5ae 100644 --- a/TGServerService/Properties/Settings.Designer.cs +++ b/TGServerService/Properties/Settings.Designer.cs @@ -205,7 +205,7 @@ namespace TGServerService.Properties { [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("3")] + [global::System.Configuration.DefaultSettingValueAttribute("4")] public int SettingsVersion { get { return ((int)(this["SettingsVersion"])); @@ -262,5 +262,17 @@ namespace TGServerService.Properties { this["RemoteAccessPort"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ReattachAPIVersion { + get { + return ((string)(this["ReattachAPIVersion"])); + } + set { + this["ReattachAPIVersion"] = value; + } + } } } diff --git a/TGServerService/Properties/Settings.settings b/TGServerService/Properties/Settings.settings index d8952c5a5d..5618f8cd97 100644 --- a/TGServerService/Properties/Settings.settings +++ b/TGServerService/Properties/Settings.settings @@ -48,7 +48,7 @@ 0 - 3 + 4 @@ -62,5 +62,8 @@ 38607 + + + \ No newline at end of file