public HybrasylWorld(World world) { World = world; }
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 HybrasylScriptProcessor(World world) { Engine = Python.CreateEngine(); var paths = Engine.GetSearchPaths(); // FIXME: obvious paths.Add(@"C:\Program Files (x86)\IronPython 2.7\Lib"); paths.Add(@"C:\Python27\Lib"); Engine.SetSearchPaths(paths); Engine.ImportModule("random"); Scripts = new Dictionary<string, Script>(); World = new HybrasylWorld(world); }
/// <summary> /// Create a new Hybrasyl map from an XMLMap object. /// </summary> /// <param name="mapElement"></param> public Map(XSD.Map newMap, World theWorld) { Init(); World = theWorld; // TODO: refactor Map class to not do this, but be a partial which overlays // TODO: XmlMap (which would then just be Map) Id = newMap.Id; X = newMap.X; Y = newMap.Y; Name = newMap.Name; EntityTree = new QuadTree<VisibleObject>(0,0,X,Y); Music = newMap.Music; foreach (var warpElement in newMap.Warps) { var warp = new Warp(this); warp.X = warpElement.X; warp.Y = warpElement.Y; if (warpElement.MapTarget !=null) { var maptarget = warpElement.MapTarget as XSD.WarpMaptarget; // map warp warp.DestinationMapName = maptarget.Value; warp.WarpType = WarpType.Map; warp.DestinationX = maptarget.X; warp.DestinationY = maptarget.Y; } else { var worldmaptarget = warpElement.WorldMapTarget as XSD.WorldMapPointTarget; // worldmap warp warp.DestinationMapName = worldmaptarget.Value; warp.WarpType = WarpType.WorldMap; } warp.MinimumLevel = warpElement.Restrictions.Level.Min; warp.MaximumLevel = warpElement.Restrictions.Level.Max; warp.MinimumAbility = warpElement.Restrictions.Ab.Min; warp.MaximumAbility = warpElement.Restrictions.Ab.Max; warp.MobUse = warpElement.Restrictions.NoMobUse == null; Warps[new Tuple<byte, byte>(warp.X, warp.Y)] = warp; } foreach (var npcElement in newMap.Npcs) { var merchant = new Merchant { X = npcElement.X, Y = npcElement.Y, Name = npcElement.Name, Sprite = npcElement.Appearance.Sprite, Direction = (Enums.Direction) npcElement.Appearance.Direction, Portrait = npcElement.Appearance.Portrait, // Wow this is terrible Jobs = ((MerchantJob) (int) npcElement.Jobs) }; InsertNpc(merchant); } foreach (var reactorElement in newMap.Reactors) { // TODO: implement reactor loading support } foreach (var postElement in newMap.Signposts.Items) { if (postElement is XSD.Signpost) { var signpostElement = postElement as XSD.Signpost; var signpost = new Objects.Signpost(signpostElement.X, signpostElement.Y, signpostElement.Message); InsertSignpost(signpost); } else { // TODO: Messageboards Logger.InfoFormat("{0}: messageboard ignored", Name); } } foreach (var spawnElement in newMap.Spawns) { // TODO: implement spawning } Load(); }