diff --git a/TGDreamDaemonBridge/DreamDaemonBridge.cs b/TGDreamDaemonBridge/DreamDaemonBridge.cs index f02aa1e3ef..c95f3e38d0 100644 --- a/TGDreamDaemonBridge/DreamDaemonBridge.cs +++ b/TGDreamDaemonBridge/DreamDaemonBridge.cs @@ -9,7 +9,7 @@ namespace TGDreamDaemonBridge /// /// Holds the proc that DD calls to access /// - public sealed class DreamDaemonBridge + public static class DreamDaemonBridge { /// /// The proc that DD calls to access @@ -20,6 +20,7 @@ namespace TGDreamDaemonBridge [DllExport("DDEntryPoint", CallingConvention = CallingConvention.Cdecl)] public static int DDEntryPoint(int argc, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeParamIndex = 0)]string[] args) { + System.Diagnostics.Debugger.Launch(); try { using (var I = new Interface()) diff --git a/TGDreamDaemonBridge/TGDreamDaemonBridge.csproj b/TGDreamDaemonBridge/TGDreamDaemonBridge.csproj index 2a9a2d3abe..1fb1121cfe 100644 --- a/TGDreamDaemonBridge/TGDreamDaemonBridge.csproj +++ b/TGDreamDaemonBridge/TGDreamDaemonBridge.csproj @@ -17,6 +17,8 @@ 1 false false + + true @@ -40,12 +42,10 @@ - - {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} - TGServiceInterface - - - + + ..\packages\Costura.Fody.1.6.2\lib\dotnet\Costura.dll + False + ..\packages\UnmanagedExports.1.2.7\lib\net\RGiesecke.DllExport.Metadata.dll False @@ -55,6 +55,24 @@ + + + {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} + TGServiceInterface + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/TGDreamDaemonBridge/packages.config b/TGDreamDaemonBridge/packages.config index 6250dba03c..8a9cbe435c 100644 --- a/TGDreamDaemonBridge/packages.config +++ b/TGDreamDaemonBridge/packages.config @@ -1,4 +1,6 @@  + + \ No newline at end of file diff --git a/TGServerService/EventID.cs b/TGServerService/EventID.cs index 02824101ab..93bdff846d 100644 --- a/TGServerService/EventID.cs +++ b/TGServerService/EventID.cs @@ -245,11 +245,11 @@ namespace TGServerService /// /// Info: When the dll is updated for the /// - InterfaceDLLUpdated = 5800, + BridgeDLLUpdated = 5800, /// /// Error: An error occurred while updating the dll for the /// - InterfaceDLLUpdateFail = 5900, + BridgeDLLUpdateFail = 5900, //YO THERE'S SPACE FOR 1 MORE ID HERE, USE IT!!! diff --git a/TGServerService/ServerInstance/Compiler.cs b/TGServerService/ServerInstance/Compiler.cs index 9fe9af2e22..cd67d9ff45 100644 --- a/TGServerService/ServerInstance/Compiler.cs +++ b/TGServerService/ServerInstance/Compiler.cs @@ -38,7 +38,7 @@ namespace TGServerService object CompilerLock = new object(); CompilerStatus compilerCurrentStatus; string lastCompilerError; - + Thread CompilerThread; bool compilationCancellationRequestation = false; bool canCancelCompilation = false; @@ -49,7 +49,7 @@ namespace TGServerService //deletes leftovers and checks current status void InitCompiler() { - if(File.Exists(LiveDirTest)) + if (File.Exists(LiveDirTest)) File.Delete(LiveDirTest); compilerCurrentStatus = IsInitialized(); } @@ -82,7 +82,7 @@ namespace TGServerService if (CompilerThread == null || !CompilerThread.IsAlive) return; CompilerThread.Abort(); //this will safely kill dm - InitCompiler(); //also cleanup + InitCompiler(); //also cleanup } } @@ -98,7 +98,7 @@ namespace TGServerService { return compilerCurrentStatus == CompilerStatus.Uninitialized || compilerCurrentStatus == CompilerStatus.Initialized; } - + /// public bool Initialize() { @@ -117,7 +117,7 @@ namespace TGServerService //what is says on the tin CompilerStatus IsInitialized() { - if (File.Exists(Path.Combine(GameDirLive, InterfaceDLLName))) //its a good tell, jim + if (File.Exists(Path.Combine(GameDirLive, BridgeDLLName))) //its a good tell, jim return CompilerStatus.Initialized; return CompilerStatus.Uninitialized; } @@ -135,15 +135,9 @@ namespace TGServerService //we need to remove symlinks before we can recursively delete void CleanGameFolder() { - if (Directory.Exists(Path.Combine(GameDirA, InterfaceDLLName))) - Directory.Delete(Path.Combine(GameDirA, InterfaceDLLName)); - if (Directory.Exists(Path.Combine(GameDirA, BridgeDLLName))) Directory.Delete(Path.Combine(GameDirA, BridgeDLLName)); - if (Directory.Exists(Path.Combine(GameDirB, InterfaceDLLName))) - Directory.Delete(Path.Combine(GameDirB, InterfaceDLLName)); - if (Directory.Exists(Path.Combine(GameDirB, BridgeDLLName))) Directory.Delete(Path.Combine(GameDirB, BridgeDLLName)); @@ -196,21 +190,19 @@ namespace TGServerService var Config = GetCachedRepoConfig(); - if (Config != null) { + if (Config != null) + { foreach (var I in Config.StaticDirectoryPaths) CreateSymlink(Path.Combine(GameDirA, I), Path.Combine(StaticDirs, I)); foreach (var I in Config.DLLPaths) CreateSymlink(Path.Combine(GameDirA, I), Path.Combine(StaticDirs, I)); } - CreateSymlink(Path.Combine(GameDirA, InterfaceDLLName), InterfaceDLLName); - CreateSymlink(Path.Combine(GameDirB, InterfaceDLLName), InterfaceDLLName); - CreateSymlink(Path.Combine(GameDirA, BridgeDLLName), BridgeDLLName); CreateSymlink(Path.Combine(GameDirB, BridgeDLLName), BridgeDLLName); CreateSymlink(GameDirLive, GameDirA); - + lock (CompilerLock) { compilerCurrentStatus = CompilerStatus.Compiling; @@ -238,7 +230,7 @@ namespace TGServerService return; } CompileImpl(); - } + } //Returns the A or B dir in which the game is NOT running string GetStagingDir() @@ -277,7 +269,7 @@ namespace TGServerService { File.Delete(rsclock); } - catch //held open by byond + catch //held open by byond { //This means there is a staged update waiting to be applied, we have to unstage it before we can work Directory.Delete(GameDirLive); @@ -360,7 +352,7 @@ namespace TGServerService resurrectee = GetStagingDir(); var Config = GetCachedRepoConfig(); - var deleteExcludeList = new List { InterfaceDLLName, BridgeDLLName }; + var deleteExcludeList = new List { BridgeDLLName }; deleteExcludeList.AddRange(Config.StaticDirectoryPaths); deleteExcludeList.AddRange(Config.DLLPaths); Program.DeleteDirectory(resurrectee, true, deleteExcludeList); @@ -381,9 +373,6 @@ namespace TGServerService CreateSymlink(the_path, Path.Combine(StaticDirs, I)); } - if (!File.Exists(Path.Combine(resurrectee, InterfaceDLLName))) - CreateSymlink(Path.Combine(resurrectee, InterfaceDLLName), InterfaceDLLName); - if (!File.Exists(Path.Combine(resurrectee, BridgeDLLName))) CreateSymlink(Path.Combine(resurrectee, BridgeDLLName), BridgeDLLName); diff --git a/TGServerService/ServerInstance/DreamDaemon.cs b/TGServerService/ServerInstance/DreamDaemon.cs index a8e7b845d5..72943470c1 100644 --- a/TGServerService/ServerInstance/DreamDaemon.cs +++ b/TGServerService/ServerInstance/DreamDaemon.cs @@ -38,23 +38,6 @@ namespace TGServerService /// const int DDBadStartTime = 10; - /// - /// The file name of the .dll that contains the - /// - static readonly string InterfaceDLLName = Path.GetFileName(Assembly.GetAssembly(typeof(Interface)).Location); - /// - /// The file name of the .dll that contains the bridge class - /// - const string BridgeDLLName = "TGDreamDaemonBridge.dll"; - /// - /// The namespace that contains the bridge class. Used for reflection - /// - const string DreamDaemonBridgeNamespace = "TGDreamDaemonBridge"; - /// - /// The bridge class. Used for reflection - /// - const string DreamDaemonBridgeType = DreamDaemonBridgeNamespace + ".DreamDaemonBridge"; - /// /// The DreamDaemon process /// @@ -168,7 +151,7 @@ namespace TGServerService //autostart the server if (Properties.Settings.Default.DDAutoStart) //break this off so we don't hold up starting the service - ThreadPool.QueueUserWorkItem( _ => { Start(); }); + ThreadPool.QueueUserWorkItem(_ => { Start(); }); } /// @@ -195,7 +178,7 @@ namespace TGServerService else if (Detach) Properties.Settings.Default.ReattachToDD = false; Stop(); - if(pcpu != null) + if (pcpu != null) pcpu.Dispose(); if (RenameLog) try @@ -283,7 +266,7 @@ namespace TGServerService { if (DaemonStatus() == DreamDaemonStatus.Offline) return Start(); - lock(restartLock) + lock (restartLock) { if (RestartInProgress) return "Restart already in progress"; @@ -292,8 +275,8 @@ namespace TGServerService SendMessage("DD: Hard restart triggered", MessageType.WatchdogInfo); Stop(); var res = Start(); - if(res != null) - lock(restartLock) + if (res != null) + lock (restartLock) { RestartInProgress = false; } @@ -512,7 +495,7 @@ namespace TGServerService } return StartImpl(false); } - + /// /// Translate the configured level into a byond command line param /// @@ -535,56 +518,46 @@ namespace TGServerService } /// - /// Copies and from the program directory to the the directory + /// Copies from the program directory to the the directory /// - /// If , overwrites the 's current interface .dll, if it exists - void UpdateInterfaceDlls(bool overwrite) + /// If , overwrites the 's current interface .dll if it exists + void UpdateInterfaceDll(bool overwrite) { - var InterfacePath = Assembly.GetAssembly(typeof(Interface)).Location; - UpdateInterfaceDLL(InterfacePath, InterfaceDLLName, overwrite); + var FileExists = File.Exists(BridgeDLLName); + if (FileExists && !overwrite) + return; + //Copy the interface dll to the static dir + var InterfacePath = Assembly.GetAssembly(typeof(Interface)).Location; var BridgePath = Path.Combine(Path.GetDirectoryName(InterfacePath), BridgeDLLName); #if DEBUG //We could be debugging from the project directory - if(!File.Exists(BridgePath)) + if (!File.Exists(BridgePath)) //A little hackish debug mode doctoring never hurt anyone BridgePath = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(InterfacePath)))), "TGDreamDaemonBridge/bin/Debug", BridgeDLLName); #endif try { //Use reflection to ensure these are the droids we're looking for - var bridge = Assembly.ReflectionOnlyLoadFrom(BridgePath); - bridge.GetType(DreamDaemonBridgeType); - UpdateInterfaceDLL(BridgePath, BridgeDLLName, overwrite); + Assembly.ReflectionOnlyLoadFrom(BridgePath).GetType(DreamDaemonBridgeType, true); } - catch (Exception e) { - Service.WriteError(String.Format("Unable to locate {0}! Error: {1}", BridgeDLLName, e.ToString()), EventID.InterfaceDLLUpdateFail); - } - } - - /// - /// Copies the .dll at to in the , optionally with an paremeter, retrying once if the file is locked - /// - /// The path of the source .dll - /// The path of the destination .dll - /// If , overwrites the 's current .dll, if it exists - void UpdateInterfaceDLL(string path, string targetPath, bool overwrite) - { - var FileExists = File.Exists(targetPath); - if (FileExists && !overwrite) + catch (Exception e) + { + Service.WriteError(String.Format("Unable to locate {0}! Error: {1}", BridgeDLLName, e.ToString()), EventID.BridgeDLLUpdateFail); return; - //Copy the interface dll to the static dir + } + try { if (FileExists) { - var Old = File.ReadAllBytes(path); - var New = File.ReadAllBytes(targetPath); + var Old = File.ReadAllBytes(BridgeDLLName); + var New = File.ReadAllBytes(BridgePath); if (Old.SequenceEqual(New)) return; //no need } - File.Copy(path, targetPath, overwrite); - Service.WriteInfo("Updated interface DLL", EventID.InterfaceDLLUpdated); + File.Copy(InterfacePath, BridgeDLLName, overwrite); + Service.WriteInfo("Updated interface DLL", EventID.BridgeDLLUpdated); } catch { @@ -592,18 +565,18 @@ namespace TGServerService { //ok the things being stupid and hasn't released the dll yet, try ONCE more Thread.Sleep(1000); - File.Copy(path, targetPath, overwrite); + File.Copy(InterfacePath, BridgeDLLName, overwrite); } catch (Exception e) { //intentionally using the fi - Service.WriteError(String.Format("Failed to update interface DLL {0}! Error: {1}", targetPath, e.ToString()), EventID.InterfaceDLLUpdateFail); + Service.WriteError("Failed to update interface DLL! Error: " + e.ToString(), EventID.BridgeDLLUpdateFail); } } } /// - /// Clears the current , calls with a parameter, and attempts to start the DreamDaemon + /// Clears the current , calls with a parameter, and attempts to start the DreamDaemon /// /// If , sets to a new pointing to and starts it /// on success, error message on failure @@ -623,7 +596,7 @@ namespace TGServerService GenCommsKey(); StartingSecurity = (DreamDaemonSecurity)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 " : ""); - UpdateInterfaceDlls(true); + UpdateInterfaceDll(true); lock (topicLock) { GameAPIVersion = null; //needs updating @@ -763,7 +736,8 @@ namespace TGServerService public void SetWebclient(bool on) { var Config = Properties.Settings.Default; - lock (watchdogLock) { + lock (watchdogLock) + { var diff = on != Config.Webclient; if (diff) { diff --git a/TGServerService/ServerInstance/Interop.cs b/TGServerService/ServerInstance/Interop.cs index 62bd60b49c..1cd07178be 100644 --- a/TGServerService/ServerInstance/Interop.cs +++ b/TGServerService/ServerInstance/Interop.cs @@ -42,6 +42,19 @@ namespace TGServerService const string CCPAdminOnly = "admin_only"; const string CCPRequiredParameters = "required_parameters"; + /// + /// The file name of the .dll that contains the bridge class + /// + const string BridgeDLLName = "TGDreamDaemonBridge.dll"; + /// + /// The namespace that contains the bridge class. Used for reflection + /// + const string DreamDaemonBridgeNamespace = "TGDreamDaemonBridge"; + /// + /// The bridge class. Used for reflection + /// + const string DreamDaemonBridgeType = DreamDaemonBridgeNamespace + ".DreamDaemonBridge"; + List ServerChatCommands; void LoadServerChatCommands() diff --git a/TGServerService/ServerInstance/Repository.cs b/TGServerService/ServerInstance/Repository.cs index 8f9629c8c0..0ebbddb121 100644 --- a/TGServerService/ServerInstance/Repository.cs +++ b/TGServerService/ServerInstance/Repository.cs @@ -96,7 +96,7 @@ namespace TGServerService { Directory.CreateDirectory(RepoKeyDir); if(Exists()) - UpdateInterfaceDlls(false); + UpdateInterfaceDll(false); if(LoadRepo() == null) DisableGarbageCollectionNoLock(); //start the autoupdate timer @@ -336,7 +336,7 @@ namespace TGServerService void InitialConfigureRepository() { Directory.CreateDirectory(StaticDirs); - UpdateInterfaceDlls(false); + UpdateInterfaceDll(false); UpdateTGS3Json(); var Config = GetCachedRepoConfig(); //RepoBusy is set if we're here foreach(var I in Config.StaticDirectoryPaths)