public static void Main(string[] args) { Thread.CurrentThread.Name = "Main"; try { string MODInfo = "Terraria's Dedicated Server Mod. (" + VERSION_NUMBER + " {" + Statics.CURRENT_TERRARIA_RELEASE + "}) #" + Statics.BUILD; try { Console.Title = MODInfo; } catch { } var lis = new Logging.LogTraceListener(); System.Diagnostics.Trace.Listeners.Clear(); System.Diagnostics.Trace.Listeners.Add(lis); System.Diagnostics.Debug.Listeners.Clear(); System.Diagnostics.Debug.Listeners.Add(lis); ProgramLog.Log("Initializing " + MODInfo); ProgramLog.Log("Setting up Paths."); if (!SetupPaths()) { return; } Platform.InitPlatform(); ProgramLog.Log("Setting up Properties."); bool propertiesExist = File.Exists("server.properties"); SetupProperties(); if (!propertiesExist) { ProgramLog.Console.Print("New properties file created. Would you like to exit for editing? [Y/n]: "); if (Console.ReadLine().ToLower() == "y") { ProgramLog.Console.Print("Complete, Press any Key to Exit..."); Console.ReadKey(true); return; } } var logFile = Statics.DataPath + Path.DirectorySeparatorChar + "server.log"; ProgramLog.OpenLogFile(logFile); string PIDFile = properties.PIDFile.Trim(); if (PIDFile.Length > 0) { string ProcessUID = Process.GetCurrentProcess().Id.ToString(); bool Issue = false; if (File.Exists(PIDFile)) { try { File.Delete(PIDFile); } catch (Exception) { ProgramLog.Console.Print("Issue deleting PID file, Continue? [Y/n]: "); if (Console.ReadLine().ToLower() == "n") { ProgramLog.Console.Print("Press any Key to Exit..."); Console.ReadKey(true); return; } Issue = true; } } if (!Issue) { try { File.WriteAllText(PIDFile, ProcessUID); } catch (Exception) { ProgramLog.Console.Print("Issue creating PID file, Continue? [Y/n]: "); if (Console.ReadLine().ToLower() == "n") { ProgramLog.Console.Print("Press any Key to Exit..."); Console.ReadKey(true); return; } } ProgramLog.Log("PID File Created, Process ID: " + ProcessUID); } } ParseArgs(args); try { if (UpdateManager.performProcess()) { ProgramLog.Log("Restarting into new update!"); return; } } catch (UpdateCompleted) { throw; } catch (Exception e) { ProgramLog.Log(e, "Error updating"); } LoadMonitor.Start(); ProgramLog.Log("Starting remote console server"); RemoteConsole.RConServer.Start("rcon_logins.properties"); ProgramLog.Log("Starting permissions manager"); permissionManager = new PermissionManager(); ProgramLog.Log("Preparing Server Data..."); using (var prog = new ProgressLogger(1, "Loading item definitions")) Collections.Registries.Item.Load(); using (var prog = new ProgressLogger(1, "Loading NPC definitions")) Collections.Registries.NPC.Load(Collections.Registries.NPC_FILE); using (var prog = new ProgressLogger(1, "Loading projectile definitions")) Collections.Registries.Projectile.Load(Collections.Registries.PROJECTILE_FILE); commandParser = new CommandParser(); commandParser.ReadPermissionNodes(); ProgramLog.Log("Loading plugins..."); Terraria_Server.Plugins.PluginManager.Initialize(Statics.PluginPath, Statics.LibrariesPath); var ctx = new HookContext() { Sender = new ConsoleSender() }; var eArgs = new HookArgs.ServerStateChange() { ServerChangeState = ServerState.INITIALIZING }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); PluginManager.LoadPlugins(); ProgramLog.Log("Plugins loaded: " + PluginManager.PluginCount); string worldFile = properties.WorldPath; FileInfo file = new FileInfo(worldFile); if (!file.Exists) { try { file.Directory.Create(); } catch (Exception exception) { ProgramLog.Log(exception); ProgramLog.Console.Print("Press any key to continue..."); Console.ReadKey(true); return; } ctx = new HookContext { Sender = World.Sender, }; eArgs = new HookArgs.ServerStateChange { ServerChangeState = ServerState.GENERATING }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); ProgramLog.Log("Generating world '{0}'", worldFile); string seed = properties.Seed; if (seed == "-1") { seed = new Random().Next(100).ToString(); ProgramLog.Log("Generated seed: {0}", seed); } int worldX = properties.GetMapSizes()[0]; int worldY = properties.GetMapSizes()[1]; if (properties.UseCustomTiles) { int X = properties.MaxTilesX; int Y = properties.MaxTilesY; if (X > 0 && Y > 0) { worldX = X; worldY = Y; } if (worldX < (int)World.MAP_SIZE.SMALL_X || worldY < (int)World.MAP_SIZE.SMALL_Y) { ProgramLog.Log("World dimensions need to be equal to or larger than {0} by {1}; using built-in 'small'", (int)World.MAP_SIZE.SMALL_X, (int)World.MAP_SIZE.SMALL_Y); worldX = (int)((int)World.MAP_SIZE.SMALL_Y * 3.5); worldY = (int)World.MAP_SIZE.SMALL_Y; } ProgramLog.Log("Generating world with custom map size: {0}x{1}", worldX, worldY); } Terraria_Server.Main.maxTilesX = worldX; Terraria_Server.Main.maxTilesY = worldY; WorldIO.clearWorld(); Terraria_Server.Main.Initialize(); if (properties.UseCustomGenOpts) { WorldGen.numDungeons = properties.DungeonAmount; WorldModify.ficount = properties.FloatingIslandAmount; } else { WorldGen.numDungeons = 1; WorldModify.ficount = (int)((double)Terraria_Server.Main.maxTilesX * 0.0008); //The Statics one was generating with default values, We want it to use the actual tileX for the world } WorldGen.GenerateWorld(seed); WorldIO.saveWorld(worldFile, true); } ctx = new HookContext { Sender = World.Sender, }; eArgs = new HookArgs.ServerStateChange { ServerChangeState = ServerState.LOADING }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); // TODO: read map size from world file instead of config int worldXtiles = properties.GetMapSizes()[0]; int worldYtiles = properties.GetMapSizes()[1]; if (properties.UseCustomTiles) { int X = properties.MaxTilesX; int Y = properties.MaxTilesY; if (X > 0 && Y > 0) { worldXtiles = X; worldYtiles = Y; } if (worldXtiles < (int)World.MAP_SIZE.SMALL_X || worldYtiles < (int)World.MAP_SIZE.SMALL_Y) { ProgramLog.Log("World dimensions need to be equal to or larger than {0} by {1}; using built-in 'small'", (int)World.MAP_SIZE.SMALL_X, (int)World.MAP_SIZE.SMALL_Y); worldXtiles = (int)((int)World.MAP_SIZE.SMALL_Y * 3.5); worldYtiles = (int)World.MAP_SIZE.SMALL_Y; } ProgramLog.Log("Using world with custom map size: {0}x{1}", worldXtiles, worldYtiles); } World world = new World(worldXtiles, worldYtiles); world.SavePath = worldFile; Server.InitializeData(world, properties.MaxPlayers, Statics.DataPath + Path.DirectorySeparatorChar + "whitelist.txt", Statics.DataPath + Path.DirectorySeparatorChar + "banlist.txt", Statics.DataPath + Path.DirectorySeparatorChar + "oplist.txt"); NetPlay.password = properties.Password; NetPlay.serverPort = properties.Port; NetPlay.serverSIP = properties.ServerIP; Terraria_Server.Main.Initialize(); Terraria_Server.Main.maxTilesX = worldXtiles; Terraria_Server.Main.maxTilesY = worldYtiles; Terraria_Server.Main.maxSectionsX = worldXtiles / 200; Terraria_Server.Main.maxSectionsY = worldYtiles / 150; WorldIO.LoadWorld(Server.World.SavePath); ctx = new HookContext { Sender = World.Sender, }; eArgs = new HookArgs.ServerStateChange { ServerChangeState = ServerState.LOADED }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); updateThread = new ProgramThread("Updt", Program.UpdateLoop); ProgramLog.Log("Starting the Server"); NetPlay.StartServer(); while (!NetPlay.ServerUp) { } ProgramLog.Console.Print("You can now insert Commands."); while (!Statics.Exit) { try { string line = Console.ReadLine(); if (line.Length > 0) { commandParser.ParseConsoleCommand(line); } } catch (ExitException e) { ProgramLog.Log(e.Message); break; } catch (Exception e) { ProgramLog.Log(e, "Issue parsing console command"); } } while (WorldModify.saveLock || NetPlay.ServerUp) { Thread.Sleep(100); } ProgramLog.Log("Exiting..."); Thread.Sleep(1000); } catch (UpdateCompleted) { } catch (Exception e) { try { using (StreamWriter streamWriter = new StreamWriter(Statics.DataPath + Path.DirectorySeparatorChar + "crashlog.txt", true)) { streamWriter.WriteLine(DateTime.Now); streamWriter.WriteLine("Crash Log Generated by TDSM #" + Statics.BUILD + " for " + //+ " r" + Statics.revision + " for " + VERSION_NUMBER + " {" + Statics.CURRENT_TERRARIA_RELEASE + "}"); streamWriter.WriteLine(e); streamWriter.WriteLine(""); } ProgramLog.Log(e, "Program crash"); ProgramLog.Log("Please send crashlog.txt to http://tdsm.org/"); } catch { } } if (File.Exists(properties.PIDFile.Trim())) { File.Delete(properties.PIDFile.Trim()); } Thread.Sleep(500); ProgramLog.Log("Log end."); ProgramLog.Close(); RemoteConsole.RConServer.Stop(); }
public static void Main(string[] args) { Thread.CurrentThread.Name = "Main"; //header: Terraria's Dedicated Server Mod. (1.1.2 #36) ~ Build: 37 [CodeName] string codeName = Statics.CODENAME.Length > 0 ? String.Format(" [{0}]", Statics.CODENAME) : String.Empty; string MODInfo = String.Format( "Terraria's Dedicated Server Mod. ({0} #{1}) ~ Build: {2}{3}", Statics.VERSION_NUMBER, Statics.CURRENT_TERRARIA_RELEASE, Statics.BUILD, codeName ); try { try { Console.Title = MODInfo; } catch { } var lis = new Logging.LogTraceListener(); System.Diagnostics.Trace.Listeners.Clear(); System.Diagnostics.Trace.Listeners.Add(lis); System.Diagnostics.Debug.Listeners.Clear(); System.Diagnostics.Debug.Listeners.Add(lis); using (var prog = new ProgressLogger(1, "Loading language definitions")) Languages.LoadClass(Collections.Registries.LANGUAGE_FILE); if (Languages.Startup_Initializing == null) { ProgramLog.Error.Log("Please update the language file, either by deleting or finding another online."); Console.ReadKey(true); return; } ProgramLog.Log("{0} {1}", Languages.Startup_Initializing, MODInfo); ProgramLog.Log(Languages.Startup_SettingUpPaths); if (!SetupPaths()) { return; } Platform.InitPlatform(); ProgramLog.Log(Languages.Startup_SettingUpProperties); bool propertiesExist = File.Exists("server.properties"); SetupProperties(); if (!propertiesExist) { ProgramLog.Console.Print(Languages.Startup_NoPropertiesFileFound); if (Console.ReadLine().ToLower() == "y") { //ProgramLog.Console.Print(Languages.Startup_PropertiesCreationComplete); ProgramLog.Log(Languages.ExitRequestCommand); //Console.ReadKey(true); return; } } var logFile = Statics.DataPath + Path.DirectorySeparatorChar + "server.log"; ProgramLog.OpenLogFile(logFile); string PIDFile = properties.PIDFile.Trim(); if (PIDFile.Length > 0) { string ProcessUID = Process.GetCurrentProcess().Id.ToString(); bool Issue = false; if (File.Exists(PIDFile)) { try { File.Delete(PIDFile); } catch (Exception) { ProgramLog.Console.Print(Languages.Startup_IssueDeletingPID); if (Console.ReadLine().ToLower() == "n") { ProgramLog.Console.Print(Languages.Startup_PressAnyKeyToExit); Console.ReadKey(true); return; } Issue = true; } } if (!Issue) { try { File.WriteAllText(PIDFile, ProcessUID); } catch (Exception) { ProgramLog.Console.Print(Languages.Startup_IssueCreatingPID); if (Console.ReadLine().ToLower() == "n") { ProgramLog.Console.Print(Languages.Startup_PressAnyKeyToExit); Console.ReadKey(true); return; } } ProgramLog.Log(Languages.Startup_PIDCreated + ProcessUID); } } ParseArgs(args); try { if (UpdateManager.PerformProcess()) { ProgramLog.Log(Languages.Startup_RestartingIntoNewUpdate); return; } } catch (UpdateCompleted) { throw; } catch (Exception e) { ProgramLog.Log(e, Languages.Startup_ErrorUpdating); } LoadMonitor.Start(); ProgramLog.Log(Languages.Startup_StartingRCON); RemoteConsole.RConServer.Start("rcon_logins.properties"); ProgramLog.Log(Languages.Startup_StartingPermissions); permissionManager = new PermissionManager(); ProgramLog.Log(Languages.Startup_PreparingServerData); using (var prog = new ProgressLogger(1, Languages.Startup_LoadingItemDefinitions)) Collections.Registries.Item.Load(); using (var prog = new ProgressLogger(1, Languages.Startup_LoadingNPCDefinitions)) Collections.Registries.NPC.Load(Collections.Registries.NPC_FILE); using (var prog = new ProgressLogger(1, Languages.Startup_LoadingProjectileDefinitions)) Collections.Registries.Projectile.Load(Collections.Registries.PROJECTILE_FILE); //if (Languages.IsOutOfDate()) // ProgramLog.Error.Log( // String.Format("{0}\n{1}", // Languages.Startup_LanguageFileOOD, Languages.Startup_LanguageFileUpdate) // , true); commandParser = new CommandParser(); commandParser.ReadPermissionNodes(); LoadPlugins(); /* Save access languages - once only */ Languages.Save(Collections.Registries.LANGUAGE_FILE); HookContext ctx; HookArgs.ServerStateChange eArgs; string worldFile = properties.WorldPath; FileInfo file = new FileInfo(worldFile); if (!file.Exists) { try { file.Directory.Create(); } catch (Exception exception) { ProgramLog.Log(exception); ProgramLog.Console.Print(Languages.Startup_PressAnyKeyToExit); Console.ReadKey(true); return; } ctx = new HookContext { Sender = World.Sender, }; eArgs = new HookArgs.ServerStateChange { ServerChangeState = ServerState.GENERATING }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); ProgramLog.Log("{0} '{1}'", Languages.Startup_GeneratingWorld, worldFile); string seed = properties.Seed; if (seed == "-1") { seed = WorldModify.genRand.Next(Int32.MaxValue).ToString(); ProgramLog.Log("{0} {1}", Languages.Startup_GeneratedSeed, seed); } int worldX = properties.GetMapSizes()[0]; int worldY = properties.GetMapSizes()[1]; if (properties.UseCustomTiles) { int X = properties.MaxTilesX; int Y = properties.MaxTilesY; if (X > 0 && Y > 0) { worldX = X; worldY = Y; } if (worldX < (int)World.MAP_SIZE.SMALL_X || worldY < (int)World.MAP_SIZE.SMALL_Y) { ProgramLog.Log("{0} {1}x{2}", Languages.Startup_WorldSizingError, (int)World.MAP_SIZE.SMALL_X, (int)World.MAP_SIZE.SMALL_Y); worldX = (int)((int)World.MAP_SIZE.SMALL_Y * 3.5); worldY = (int)World.MAP_SIZE.SMALL_Y; } ProgramLog.Log("{0} {1}x{2}", Languages.Startup_GeneratingWithCustomSize, worldX, worldY); } Terraria_Server.Main.maxTilesX = worldX; Terraria_Server.Main.maxTilesY = worldY; WorldIO.ClearWorld(); Terraria_Server.Main.Initialize(); if (properties.UseCustomGenOpts) { WorldGen.numDungeons = properties.DungeonAmount; WorldModify.ficount = properties.FloatingIslandAmount; } else { WorldGen.numDungeons = 1; WorldModify.ficount = (int)((double)Terraria_Server.Main.maxTilesX * 0.0008); //The Statics one was generating with default values, We want it to use the actual tileX for the world } WorldGen.GenerateWorld(null, seed); WorldIO.SaveWorld(worldFile, true); } ctx = new HookContext { Sender = World.Sender, }; eArgs = new HookArgs.ServerStateChange { ServerChangeState = ServerState.LOADING }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); // TODO: read map size from world file instead of config int worldXtiles = properties.GetMapSizes()[0]; int worldYtiles = properties.GetMapSizes()[1]; if (properties.UseCustomTiles) { int X = properties.MaxTilesX; int Y = properties.MaxTilesY; if (X > 0 && Y > 0) { worldXtiles = X; worldYtiles = Y; } if (worldXtiles < (int)World.MAP_SIZE.SMALL_X || worldYtiles < (int)World.MAP_SIZE.SMALL_Y) { ProgramLog.Log("{0} {1}x{2}", Languages.Startup_WorldSizingError, (int)World.MAP_SIZE.SMALL_X, (int)World.MAP_SIZE.SMALL_Y); worldXtiles = (int)((int)World.MAP_SIZE.SMALL_Y * 3.5); worldYtiles = (int)World.MAP_SIZE.SMALL_Y; } ProgramLog.Log("{0} {1}x{2}", Languages.Startup_GeneratingWithCustomSize, worldXtiles, worldXtiles); } World.SavePath = worldFile; Server.InitializeData(properties.MaxPlayers, Statics.DataPath + Path.DirectorySeparatorChar + "whitelist.txt", Statics.DataPath + Path.DirectorySeparatorChar + "banlist.txt", Statics.DataPath + Path.DirectorySeparatorChar + "oplist.txt"); NetPlay.password = properties.Password; NetPlay.serverPort = properties.Port; NetPlay.serverSIP = properties.ServerIP; Terraria_Server.Main.Initialize(); Terraria_Server.Main.maxTilesX = worldXtiles; Terraria_Server.Main.maxTilesY = worldYtiles; Terraria_Server.Main.maxSectionsX = worldXtiles / 200; Terraria_Server.Main.maxSectionsY = worldYtiles / 150; WorldIO.LoadWorld(null, null, World.SavePath); ctx = new HookContext { Sender = World.Sender, }; eArgs = new HookArgs.ServerStateChange { ServerChangeState = ServerState.LOADED }; HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs); updateThread = new ProgramThread("Updt", Program.UpdateLoop); ProgramLog.Log(Languages.Startup_StartingTheServer); NetPlay.StartServer(); while (!NetPlay.ServerUp) { } ThreadPool.QueueUserWorkItem(CommandThread); ProgramLog.Console.Print(Languages.Startup_YouCanNowInsertCommands); while (WorldModify.saveLock || NetPlay.ServerUp || Restarting) { Thread.Sleep(100); } ProgramLog.Log(Languages.Startup_Exiting); Thread.Sleep(1000); } catch (UpdateCompleted) { } catch (Exception e) { try { using (StreamWriter streamWriter = new StreamWriter(Statics.DataPath + Path.DirectorySeparatorChar + "crashlog.txt", true)) { streamWriter.WriteLine(DateTime.Now); streamWriter.WriteLine(String.Format("{0} {1}", Languages.Startup_CrashlogGeneratedBy, MODInfo)); streamWriter.WriteLine(e); streamWriter.WriteLine(); } ProgramLog.Log(e, Languages.Startup_ProgramCrash); ProgramLog.Log("{0} crashlog.txt -> http://tdsm.org/", Languages.Startup_PleaseSend); } catch { } } if (properties != null && File.Exists(properties.PIDFile.Trim())) { File.Delete(properties.PIDFile.Trim()); } Thread.Sleep(500); ProgramLog.Log(Languages.Startup_LogEnd); ProgramLog.Close(); RemoteConsole.RConServer.Stop(); }