public static void Main(string[] args) { // Make our window nice and big Console.SetWindowSize(140, 36); LogLevel = Hybrasyl.Constants.DEFAULT_LOG_LEVEL; Assemblyinfo = new AssemblyInfo(Assembly.GetEntryAssembly()); Constants.DataDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Hybrasyl"); if (!Directory.Exists(Constants.DataDirectory)) { Logger.InfoFormat("Creating data directory {0}", Constants.DataDirectory); try { // Create the various directories we need Directory.CreateDirectory(Constants.DataDirectory); Directory.CreateDirectory(Path.Combine(Constants.DataDirectory, "maps")); Directory.CreateDirectory(Path.Combine(Constants.DataDirectory, "scripts")); Directory.CreateDirectory(Path.Combine(Constants.DataDirectory, "world")); } catch (Exception e) { Logger.ErrorFormat("Can't create data directory: {0}", e.ToString()); return; } } var hybconfig = Path.Combine(Constants.DataDirectory, "config.xml"); if (File.Exists(hybconfig)) { try { Config = Serializer.Deserialize(XmlReader.Create(hybconfig), new HybrasylConfig()); Logger.Info("Configuration file loaded."); } catch (Exception e) { Logger.ErrorFormat("The config file {0} could not be parsed: {1}", hybconfig, e); } } else { var validConfig = false; while (validConfig == false) { try { Config = GatherConfig(); validConfig = true; } catch (Exception e) { Logger.ErrorFormat("Some of the values you entered were invalid. Try again. Error was: {0}", e.ToString()); } } // Write out our configuration XML.Serializer.Serialize(new XmlTextWriter(hybconfig, null), Config); } // Set default logging level ((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root.Level = Level.Info; ((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).RaiseConfigurationChanged( EventArgs.Empty); // Set console buffer, so we can scroll back a bunch Console.BufferHeight = Int16.MaxValue - 1; Logger.InfoFormat("Hybrasyl {0} starting.", Assemblyinfo.Version); Logger.InfoFormat("{0} - this program is licensed under the GNU AGPL, version 3.", Assemblyinfo.Copyright); LoadCollisions(); // For right now we don't support binding to different addresses; the support in the XML // is for a distant future where that may be desirable. IpAddress = IPAddress.Parse(Config.Network.Lobby.Bindaddress); Lobby = new Lobby(Config.Network.Lobby.Port); Login = new Login(Config.Network.Login.Port); World = new World(Config.Network.World.Port, Config.Datastore); Lobby.StopToken = CancellationTokenSource.Token; Login.StopToken = CancellationTokenSource.Token; World.StopToken = CancellationTokenSource.Token; if (!World.InitWorld()) { Logger.FatalFormat("Hybrasyl cannot continue loading. Press any key to exit."); Console.ReadKey(); Environment.Exit(1); } byte[] addressBytes; addressBytes = IpAddress.GetAddressBytes(); Array.Reverse(addressBytes); var stream = new MemoryStream(); var writer = new BinaryWriter(stream, Encoding.GetEncoding(949)); writer.Write((byte)1); writer.Write((byte)1); writer.Write(addressBytes); writer.Write((byte)(2611 / 256)); writer.Write((byte)(2611 % 256)); writer.Write(Encoding.GetEncoding(949).GetBytes("Hybrasyl;Hybrasyl Production\0")); writer.Flush(); var serverTable = stream.ToArray(); ServerTableCrc = ~Crc32.Calculate(serverTable); ServerTable = Zlib.Compress(stream).ToArray(); writer.Close(); stream.Close(); var serverMsg = Path.Combine(Constants.DataDirectory, "server.msg"); if (File.Exists(serverMsg)) { stream = new MemoryStream(Encoding.GetEncoding(949).GetBytes(File.ReadAllText(serverMsg))); } else { stream = new MemoryStream(Encoding.GetEncoding(949).GetBytes(String.Format("Welcome to Hybrasyl!\n\nThis is Hybrasyl (version {0}).\n\nFor more information please visit http://www.hybrasyl.com", Assemblyinfo.Version))); } var notification = stream.ToArray(); NotificationCrc = ~Crc32.Calculate(notification); Notification = Zlib.Compress(stream).ToArray(); World.StartTimers(); World.StartQueueConsumer(); ToggleActive(); StartDate = DateTime.Now; _lobbyThread = new Thread(new ThreadStart(Lobby.StartListening)); _loginThread = new Thread(new ThreadStart(Login.StartListening)); _worldThread = new Thread(new ThreadStart(World.StartListening)); _lobbySendThread = new Thread(new ThreadStart(Lobby.SendLoop)); _loginSendThread = new Thread(new ThreadStart(Login.SendLoop)); _worldSendThread = new Thread(new ThreadStart(World.SendLoop)); _lobbyThread.Start(); _loginThread.Start(); _worldThread.Start(); _lobbySendThread.Start(); _loginSendThread.Start(); _worldSendThread.Start(); while (true) { if (!IsActive()) { CancellationTokenSource.Cancel(); break; } Thread.Sleep(100); } Logger.Warn("Hybrasyl: all servers shutting down"); // Server is shutting down. For Lobby and Login, this terminates the TCP listeners; // for World, this triggers a logoff for all logged in users and then terminates. After // termination, the queue consumer is stopped as well. // For a true restart we'll need to do a few other things; stop timers, etc. Lobby.Shutdown(); Login.Shutdown(); World.Shutdown(); World.StopQueueConsumer(); Logger.WarnFormat("Hybrasyl {0}: shutdown complete.", Assemblyinfo.Version); Environment.Exit(0); }
public static void Main(string[] args) { // Make our window nice and big Console.SetWindowSize(140, 36); LogLevel = Hybrasyl.Constants.DEFAULT_LOG_LEVEL; Assemblyinfo = new AssemblyInfo(Assembly.GetEntryAssembly()); Constants.DataDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Hybrasyl"); if (!Directory.Exists(Constants.DataDirectory)) { Logger.InfoFormat("Creating data directory {0}", Constants.DataDirectory); try { // Create the various directories we need Directory.CreateDirectory(Constants.DataDirectory); Directory.CreateDirectory(Path.Combine(Constants.DataDirectory, "maps")); Directory.CreateDirectory(Path.Combine(Constants.DataDirectory, "scripts")); } catch (Exception e) { Logger.ErrorFormat("Can't create data directory: {0}", e.ToString()); return; } } var hybconfig = Path.Combine(Constants.DataDirectory, "config.xml"); if (File.Exists(hybconfig)) { var xml = File.ReadAllText(hybconfig); HybrasylConfig newConfig; Exception parseException; if (XML.Config.HybrasylConfig.Deserialize(xml, out newConfig, out parseException)) Config = newConfig; else { Logger.ErrorFormat("Error parsing Hybrasyl configuration: {1}", hybconfig, parseException); Environment.Exit(0); } } else { Console.ForegroundColor = ConsoleColor.White; Console.Write("Welcome to Project Hybrasyl: this is Hybrasyl server {0}\n", Assemblyinfo.Version); Console.Write("I need to ask some questions before we can go on. You'll also need to\n"); Console.Write("make sure that an app.config exists in the Hybrasyl server directory,\n"); Console.Write("and that the database specified there exists and is properly loaded.\n"); Console.Write("Otherwise, you're gonna have a bad time.\n\n"); Console.Write("These questions will only be asked once - if you need to make changes\n"); Console.Write("in the future, edit config.xml in the Hybrasyl server directory.\n\n"); Console.Write("Enter this server's IP address, or what IP we should bind to (default is 127.0.0.1): "); var serverIp = Console.ReadLine(); Console.Write("Enter the Lobby Port (default is 2610): "); var lobbyPort = Console.ReadLine(); Console.Write("Enter the Login Port: (default is 2611): "); var loginPort = Console.ReadLine(); Console.Write("Enter the World Port (default is 2612): "); var worldPort = Console.ReadLine(); if (String.IsNullOrEmpty(serverIp)) serverIp = "127.0.0.1"; if (String.IsNullOrEmpty(lobbyPort)) lobbyPort = "2610"; if (String.IsNullOrEmpty(loginPort)) loginPort = "2611"; if (String.IsNullOrEmpty(worldPort)) worldPort = "2612"; Logger.InfoFormat("Using {0}: {1}, {2}, {3}", serverIp, lobbyPort, loginPort, worldPort); Console.Write("Now, we will configure the Redis store.\n\n"); Console.Write("Redis IP or hostname (default is localhost): "); var redisHost = Console.ReadLine(); Console.Write("Redis authentication information (optional - if you don't have these, just hit enter)"); Console.Write("Username: "******"Password: "******"localhost"; Config = new HybrasylConfig {datastore = {host = redisHost}, network = { lobby = new NetworkInfo { bindaddress = serverIp, port = Convert.ToUInt16(lobbyPort) }, login = new NetworkInfo { bindaddress = serverIp, port = Convert.ToUInt16(loginPort) }, world = new NetworkInfo { bindaddress = serverIp, port = Convert.ToUInt16(worldPort) } }}; if (String.IsNullOrEmpty(redisUser)) Config.datastore.username = redisUser; if (String.IsNullOrEmpty(redisPass)) Config.datastore.username = redisPass; Config.SaveToFile(Path.Combine(Constants.DataDirectory, "config.xml")); } ((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root.Level = Level.Debug; ((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).RaiseConfigurationChanged( EventArgs.Empty); // Set console buffer, so we can scroll back a bunch Console.BufferHeight = Int16.MaxValue - 1; Logger.InfoFormat("Hybrasyl {0} starting.", Assemblyinfo.Version); Logger.InfoFormat("{0} - this program is licensed under the GNU AGPL, version 3.", Assemblyinfo.Copyright); LoadCollisions(); // For right now we don't support binding to different addresses; the support in the XML // is for a distant future where that may be desirable. IpAddress = IPAddress.Parse(Config.network.lobby.bindaddress); Lobby = new Lobby(Config.network.lobby.port); Login = new Login(Config.network.login.port); World = new World(Config.network.world.port, Config.datastore); World.InitWorld(); byte[] addressBytes; addressBytes = IpAddress.GetAddressBytes(); Array.Reverse(addressBytes); var stream = new MemoryStream(); var writer = new BinaryWriter(stream, Encoding.GetEncoding(949)); writer.Write((byte)1); writer.Write((byte)1); writer.Write(addressBytes); writer.Write((byte)(2611 / 256)); writer.Write((byte)(2611 % 256)); writer.Write(Encoding.GetEncoding(949).GetBytes("Hybrasyl;Hybrasyl Production\0")); writer.Flush(); var serverTable = stream.ToArray(); ServerTableCrc = ~Crc32.Calculate(serverTable); ServerTable = Zlib.Compress(stream).ToArray(); writer.Close(); stream.Close(); var serverMsg = Path.Combine(Constants.DataDirectory, "server.msg"); if (File.Exists(serverMsg)) { stream = new MemoryStream(Encoding.GetEncoding(949).GetBytes(File.ReadAllText(serverMsg))); } else { stream = new MemoryStream(Encoding.GetEncoding(949).GetBytes(String.Format("Welcome to Hybrasyl!\n\nThis is Hybrasyl (version {0}).\n\nFor more information please visit http://www.hybrasyl.com", Assemblyinfo.Version))); } var notification = stream.ToArray(); NotificationCrc = ~Crc32.Calculate(notification); Notification = Zlib.Compress(stream).ToArray(); World.StartTimers(); World.StartQueueConsumer(); ToggleActive(); while (true) { Lobby.AcceptConnection(); Login.AcceptConnection(); World.AcceptConnection(); if (!IsActive()) break; Thread.Sleep(10); } Logger.Warn("Hybrasyl: all servers shutting down"); // Server is shutting down. For Lobby and Login, this terminates the TCP listeners; // for World, this triggers a logoff for all logged in users and then terminates. After // termination, the queue consumer is stopped as well. // For a true restart we'll need to do a few other things; stop timers, etc. Lobby.Shutdown(); Login.Shutdown(); World.Shutdown(); World.StopQueueConsumer(); Logger.WarnFormat("Hybrasyl {0}: shutdown complete.", Assemblyinfo.Version); Environment.Exit(0); }
public static void Main(string[] args) { // Make our window nice and big Console.SetWindowSize(140, 36); LogLevel = Hybrasyl.Constants.DEFAULT_LOG_LEVEL; XDocument config; Assemblyinfo = new AssemblyInfo(Assembly.GetEntryAssembly()); Constants.DataDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Hybrasyl"); if (!Directory.Exists(Constants.DataDirectory)) { Logger.InfoFormat("Creating data directory {0}", Constants.DataDirectory); try { // Create the various directories we need Directory.CreateDirectory(Constants.DataDirectory); Directory.CreateDirectory(Path.Combine(Constants.DataDirectory, "maps")); Directory.CreateDirectory(Path.Combine(Constants.DataDirectory, "scripts")); } catch (Exception e) { Logger.ErrorFormat("Can't create data directory: {0}", e.ToString()); return; } } var hybconfig = Path.Combine(Constants.DataDirectory, "config.xml"); if (File.Exists(hybconfig)) { config = XDocument.Load(hybconfig); } else { Console.ForegroundColor = ConsoleColor.White; Console.Write("Welcome to Project Hybrasyl: this is Hybrasyl server {0}\n", Assemblyinfo.Version); Console.Write("I need to ask some questions before we can go on. You'll also need to\n"); Console.Write("make sure that an app.config exists in the Hybrasyl server directory,\n"); Console.Write("and that the database specified there exists and is properly loaded.\n"); Console.Write("Otherwise, you're gonna have a bad time.\n\n"); Console.Write("These questions will only be asked once - if you need to make changes\n"); Console.Write("in the future, edit config.xml in the Hybrasyl server directory.\n\n"); Console.Write("Enter this server's IP address, or what IP we should bind to (default is 127.0.0.1): "); var serverIp = Console.ReadLine(); Console.Write("Enter the Lobby Port (default is 2610): "); var lobbyPort = Console.ReadLine(); Console.Write("Enter the Login Port: (default is 2611): "); var loginPort = Console.ReadLine(); Console.Write("Enter the World Port (default is 2612): "); var worldPort = Console.ReadLine(); if (String.IsNullOrEmpty(serverIp)) { serverIp = "127.0.0.1"; } if (String.IsNullOrEmpty(lobbyPort)) { lobbyPort = "2610"; } if (String.IsNullOrEmpty(loginPort)) { loginPort = "2611"; } if (String.IsNullOrEmpty(worldPort)) { worldPort = "2612"; } Logger.InfoFormat("Using {0}: {1}, {2}, {3}", serverIp, lobbyPort, loginPort, worldPort); Console.Write("Now, we will configure the database:\n\n"); Console.Write("MySQL database IP or hostname: "); var mysqlHost = Console.ReadLine(); Console.Write("MySQL username: "******"MySQL password: "******"MySQL database name: "); var mysqlDbname = Console.ReadLine(); var connectionString = String.Format(Constants.EF_CONNSTRING_TEMPLATE, mysqlHost, mysqlUser, mysqlPass, mysqlDbname); Logger.InfoFormat("Using connection string: {0}", connectionString); // FIXME: XAttribute can return null config = new XDocument( new XElement("hybrasyl", new XElement("datastore", new XAttribute("type", "mysql"), new XAttribute("database", mysqlDbname), new XAttribute("hostname", mysqlHost), new XAttribute("username", mysqlUser), new XAttribute("password", mysqlPass)), new XElement("server", new XAttribute("ip", serverIp), new XAttribute("lobby", lobbyPort), new XAttribute("login", loginPort), new XAttribute("world", worldPort)) ) ); config.Save(Path.Combine(Constants.DataDirectory, "config.xml")); } // Set console buffer, so we can scroll back a bunch Console.BufferHeight = Int16.MaxValue - 1; Logger.InfoFormat("Hybrasyl {0} starting.", Assemblyinfo.Version); Logger.InfoFormat("{0} - this program is licensed under the GNU AGPL, version 3.", Assemblyinfo.Copyright); // Prepare our connection string var dbvalues = config.Element("hybrasyl").Element("datastore"); Constants.ConnectionString = Constants.EF_METADATA + String.Format(Constants.EF_CONNSTRING_TEMPLATE, dbvalues.Attribute("hostname").Value, dbvalues.Attribute("username").Value, dbvalues.Attribute("password").Value, dbvalues.Attribute("database").Value); LoadCollisions(); IpAddress = IPAddress.Parse(config.Element("hybrasyl").Element("server").Attribute("ip").Value); Lobby = new Lobby((int)config.Element("hybrasyl").Element("server").Attribute("lobby")); Login = new Login((int)config.Element("hybrasyl").Element("server").Attribute("login")); World = new World((int)config.Element("hybrasyl").Element("server").Attribute("world")); World.InitWorld(); byte[] addressBytes; addressBytes = IpAddress.GetAddressBytes(); Array.Reverse(addressBytes); var stream = new MemoryStream(); var writer = new BinaryWriter(stream, Encoding.GetEncoding(949)); writer.Write((byte)1); writer.Write((byte)1); writer.Write(addressBytes); writer.Write((byte)(2611 / 256)); writer.Write((byte)(2611 % 256)); writer.Write(Encoding.GetEncoding(949).GetBytes("Hybrasyl;Hybrasyl Production\0")); writer.Flush(); var serverTable = stream.ToArray(); ServerTableCrc = ~Crc32.Calculate(serverTable); ServerTable = Zlib.Compress(stream).ToArray(); writer.Close(); stream.Close(); var serverMsg = Path.Combine(Constants.DataDirectory, "server.msg"); if (File.Exists(serverMsg)) { stream = new MemoryStream(Encoding.GetEncoding(949).GetBytes(File.ReadAllText(serverMsg))); } else { stream = new MemoryStream(Encoding.GetEncoding(949).GetBytes(String.Format("Welcome to Hybrasyl!\n\nThis is Hybrasyl (version {0}).\n\nFor more information please visit http://www.hybrasyl.com", Assemblyinfo.Version))); } var notification = stream.ToArray(); NotificationCrc = ~Crc32.Calculate(notification); Notification = Zlib.Compress(stream).ToArray(); World.StartTimers(); World.StartQueueConsumer(); ToggleActive(); while (true) { Lobby.AcceptConnection(); Login.AcceptConnection(); World.AcceptConnection(); if (!IsActive()) { break; } Thread.Sleep(10); } Logger.Warn("Hybrasyl: all servers shutting down"); // Server is shutting down. For Lobby and Login, this terminates the TCP listeners; // for World, this triggers a logoff for all logged in users and then terminates. After // termination, the queue consumer is stopped as well. // For a true restart we'll need to do a few other things; stop timers, etc. Lobby.Shutdown(); Login.Shutdown(); World.Shutdown(); World.StopQueueConsumer(); Logger.WarnFormat("Hybrasyl {0}: shutdown complete.", Assemblyinfo.Version); Environment.Exit(0); }