public async void LoadObjects() { var objects = await ServerDB.SelectAllMapObjectsAsync(_mapID); if (objects?.Any() ?? false) { uint guid; foreach (var item in objects) { if (item.ObjectID < 0) { guid = CreateNSObject(item); } else { guid = CreateNVObject(item); } ServerLogger.Log($"{_server.Name}({_mapID}): Created {(item.ObjectID < 0 ? "NS" : "NV")} object guid {guid:X8} at {item.Position}"); } } if (!_nsObjects.ContainsKey(0)) { ServerLogger.LogWarning($"{_server.Name}({_mapID}) default spawn point not found"); } }
public void LoadObjects() { List <DB_WorldObject> objects; if (ServerDB.SelectAllMapObjects(_mapID, out objects) && objects != null) { uint guid; foreach (var item in objects) { if (item.ObjectID < 0) { guid = CreateNSObject(item); } else { guid = CreateNVObject(item); } ServerLogger.Log($"{_server.Name}({_mapID}): Created {(item.ObjectID < 0 ? "NS" : "NV")} object guid {guid:X8} at {item.Position}"); } } if (!_nsObjects.ContainsKey(0)) { ServerLogger.LogWarn($"{_server.Name}({_mapID}) default spawn point not found"); } }
public static Assembly AssemblyResolveHandler(object sender, ResolveEventArgs args) { var logger = new ServerLogger(); logger.Log(TraceEventType.Warning, "Resolving Assembly: " + args.Name); Assembly match = null; var argsParts = args.Name.Split(','); var targetToLower = (argsParts.Length > 0) ? argsParts[0].ToLower() : args.Name.ToLower(); var basedir = AppDomain.CurrentDomain.BaseDirectory; var providersdir = Path.Combine(basedir, "Providers"); var assemblypaths_all = Directory.GetFiles(providersdir) .Where(q => q.ToLower().Contains(".dll")); var assemblypaths = assemblypaths_all .Where(q => q.ToLower().Contains(targetToLower)).ToList(); var count = assemblypaths.Count; logger.Log(TraceEventType.Verbose, "Items found in Providers dir: {0}", count); foreach (var item in assemblypaths) { Assembly a1 = null; try { a1 = Assembly.LoadFile(item); } finally { } if (a1 != null) { if (a1.FullName == args.Name) { match = a1; break; } if (a1.FullName.StartsWith(args.Name)) { match = a1; break; } } } if (match == null) logger.Log(TraceEventType.Warning, "NO Match found"); else logger.Log(TraceEventType.Information, "Match found"); logger = null; return match; }
public List <MapEntry> LoadMaps() { using var tr = new StreamReader(@"Data/Maps.csv") as TextReader; using var csv = new CsvReader(tr, CultureInfo.CurrentCulture); var maps = csv.GetRecords <MapEntry>().ToList(); ServerLogger.Log($"Loading maps: {maps.Count}"); return(maps); }
private static void BuildCache() { ServerLogger.Log("Build path cache"); nodeCache = new PathNode[MaxCacheSize]; for (var i = 0; i < MaxCacheSize; i++) { var n = new PathNode(null, Position.Zero, 0); nodeCache[i] = n; } cachePos = MaxCacheSize; }
public Dictionary <string, List <MapConnector> > LoadConnectors(List <MapEntry> maps) { var connectors = new Dictionary <string, List <MapConnector> >(); using var tr = new StreamReader(@"Data/Connectors.csv") as TextReader; using var csv = new CsvReader(tr, CultureInfo.CurrentCulture); var connections = csv.GetRecords <CsvMapConnector>(); var entryCount = 0; foreach (var connector in connections) { if (string.IsNullOrWhiteSpace(connector.Source) || connector.Source.StartsWith("//") || connector.Source.StartsWith("#")) { continue; } var con = new MapConnector() { Map = connector.Source, SrcArea = Area.CreateAroundPoint(new Position(connector.X, connector.Y), connector.Width, connector.Height), Target = connector.Target, DstArea = Area.CreateAroundPoint(new Position(connector.TargetX, connector.TargetY), connector.TargetWidth, connector.TargetHeight) }; if (con.Map == null) { continue; } if (!maps.Any(m => m.Code == con.Target)) { ServerLogger.LogWarning($"Connection on map {con.Map} goes to invalid map {con.Target}"); continue; } if (!connectors.ContainsKey(con.Map)) { connectors.Add(con.Map, new List <MapConnector>()); } connectors[con.Map].Add(con); entryCount++; } ServerLogger.Log($"Loading connectors: {entryCount}"); return(connectors); }
public MapSpawnDatabaseInfo LoadSpawnInfo() { var mapSpawns = new MapSpawnDatabaseInfo(); mapSpawns.MapSpawnEntries = new Dictionary <string, List <MapSpawnEntry> >(); using var tr = new StreamReader(@"Data/MapSpawns.csv") as TextReader; using var csv = new CsvReader(tr, CultureInfo.CurrentCulture); var spawns = csv.GetRecords <CsvMapSpawnEntry>().ToList(); var entryCount = 0; foreach (var spawn in spawns) { if (string.IsNullOrWhiteSpace(spawn.Map) || spawn.Map.StartsWith("//") || spawn.Map.StartsWith("#")) { continue; } var entry = new MapSpawnEntry() { X = spawn.X, Y = spawn.Y, Width = spawn.Width, Height = spawn.Height, Count = spawn.Count, Class = spawn.Class, SpawnTime = spawn.SpawnTime, SpawnVariance = spawn.Variance }; if (!mapSpawns.MapSpawnEntries.ContainsKey(spawn.Map)) { mapSpawns.MapSpawnEntries.Add(spawn.Map, new List <MapSpawnEntry>()); } mapSpawns.MapSpawnEntries[spawn.Map].Add(entry); entryCount++; } ServerLogger.Log($"Loading map spawn sets: {entryCount}"); return(mapSpawns); }
private void Initialize() { ServerLogger.Log("Ragnarok Rebuild Zone Server, starting up!"); DistanceCache.Init(); DataManager.Initialize(); world = new World(); NetworkManager.Init(world); Profiler.Init(0.005f); //logs events for frames that take longer than 5ms Time.Start(); GC.Collect(); GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency; }
public static void ScanAndDisconnect() { var players = State.Players; var disconnectList = State.DisconnectList; for (var i = 0; i < players.Count; i++) { if (players[i].ClientConnection.Status == NetConnectionStatus.Disconnected || players[i].ClientConnection.Status == NetConnectionStatus.Disconnecting) { disconnectList.Add(players[i]); } else { if (players[i].Character == null) { if (players[i].LastKeepAlive + 20 < Time.ElapsedTime) { disconnectList.Add(players[i]); } } else { if (players[i].Character.IsActive && players[i].LastKeepAlive + 20 < Time.ElapsedTime) { disconnectList.Add(players[i]); } if (!players[i].Character.IsActive && players[i].LastKeepAlive + 120 < Time.ElapsedTime) { disconnectList.Add(players[i]); } } } } for (var i = 0; i < disconnectList.Count; i++) { var player = disconnectList[i]; ServerLogger.Log($"[Network] Player {player.Entity} has disconnected, removing from world."); DisconnectPlayer(player); } disconnectList.Clear(); }
public static void StartPolicyServer() { //policy server is required for web build to connect const string allPolicy = @"<?xml version='1.0'?> <cross-domain-policy> <allow-access-from domain=""*"" to-ports=""*"" /> </cross-domain-policy>"; State.PolicyServer = new SocketPolicyServer(allPolicy); int ret = State.PolicyServer.Start(); if (ret != 0) { ServerLogger.Log("Failed to start policy server."); } else { ServerLogger.Log("Policy service started."); } }
public List <MonsterDatabaseInfo> LoadMonsterStats() { using var tr = new StreamReader(@"Data/Monsters.csv") as TextReader; using var csv = new CsvReader(tr, CultureInfo.CurrentCulture); var monsters = csv.GetRecords <CsvMonsterData>().ToList(); var obj = new List <MonsterDatabaseInfo>(monsters.Count); foreach (var monster in monsters) { if (monster.Id <= 0) { continue; } obj.Add(new MonsterDatabaseInfo() { Id = monster.Id, Code = monster.Code, HP = monster.HP, Range = monster.Range > 0 ? monster.Range : 1, ScanDist = monster.ScanDist, ChaseDist = monster.ChaseDist, AtkMin = monster.AtkMin, AtkMax = monster.AtkMax, AttackTime = monster.AttackTime / 1000f, HitTime = monster.HitTime / 1000f, RechargeTime = monster.RechargeTime / 1000f, MoveSpeed = monster.MoveSpeed / 1000f, SpriteAttackTiming = monster.SpriteAttackTiming / 1000f, AiType = (MonsterAiType)Enum.Parse(typeof(MonsterAiType), monster.MonsterAiType), Name = monster.Name }); } ServerLogger.Log($"Loading monsters: {obj.Count}"); return(obj); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { ServerLogger.RegisterLogger(logger); Initialize(); var stopwatch = new Stopwatch(); stopwatch.Start(); var total = 0d; var max = 0d; var spos = 0; var totalNetwork = 0d; var totalEcs = 0d; var totalWorld = 0d; var maxNetwork = 0d; var maxEcs = 0d; var maxWorld = 0d; #if DEBUG var noticeTime = 5f; #else var noticeTime = 60f; #endif var lastLog = Time.ElapsedTime - noticeTime + 5f; //make the first check-in 5s after start no matter what while (!stoppingToken.IsCancellationRequested) { Time.Update(); var startTime = Time.GetExactTime(); NetworkManager.ProcessIncomingMessages(); var networkTime = Time.GetExactTime(); world.RunEcs(); var ecsTime = Time.GetExactTime(); world.Update(); var worldTime = Time.GetExactTime(); var elapsed = Time.GetExactTime() - startTime; //Console.WriteLine(elapsed); total += elapsed; Profiler.FinishFrame((float)elapsed); var nt = networkTime - startTime; var et = ecsTime - networkTime; var wt = worldTime - ecsTime; totalNetwork += nt; totalEcs += et; totalWorld += wt; if (max < elapsed) { max = elapsed; } if (maxNetwork < nt) { maxNetwork = nt; } if (maxEcs < et) { maxEcs = et; } if (maxWorld < wt) { maxWorld = wt; } spos++; var ms = (int)(elapsed * 1000) + 1; if (ms < 10) { await Task.Delay(10 - ms, stoppingToken); } if (lastLog + noticeTime < Time.ElapsedTime) { var avg = (total / spos); //var fps = 1 / avg; var players = NetworkManager.PlayerCount; avg *= 1000d; //var avgNetwork = (totalNetwork / spos) * 1000d; //var avgEcs = (totalEcs / spos) * 1000d; //var avgWorld = (totalWorld / spos) * 1000d; #if DEBUG var server = NetworkManager.State.Server; ServerLogger.Log( $"[Program] {players} players. Avg {avg:F2}ms / Peak {max * 1000:F2}ms " + $"(Net/ECS/World: {maxNetwork * 1000:F2}/{maxEcs * 1000:F2}/{maxWorld:F2}) " + $"Sent {server.Statistics.SentBytes}bytes/{server.Statistics.SentMessages}msg/{server.Statistics.SentPackets}packets"); #else ServerLogger.Log( $"[Program] {players} players. Avg {avg:F2}ms / Peak {max * 1000:F2}ms " + $"(Net/ECS/World: {maxNetwork * 1000:F2}/{maxEcs * 1000:F2}/{maxWorld:F2})"); #endif lastLog = Time.ElapsedTime; total = 0; max = 0; spos = 0; totalNetwork = 0; totalWorld = 0; totalEcs = 0; maxNetwork = 0; maxWorld = 0; maxEcs = 0; NetworkManager.ScanAndDisconnect(); } } logger.LogCritical("Oh no! We've dropped out of the processing loop! We will now shutdown."); appLifetime.StopApplication(); }
public static void Init(World gameWorld) { State = new ServerState(); State.World = gameWorld; //policy server is required for web build, but since webGL doesn't support lidgren, it's disabled //StartPolicyServer(); if (!DataManager.TryGetConfigInt("Port", out var port)) { throw new Exception("Configuration does not have value for port!"); } if (!DataManager.TryGetConfigInt("MaxConnections", out var maxConnections)) { throw new Exception("Configuration does not have value for max connections!"); } if (DataManager.TryGetConfigInt("Debug", out var debug)) { State.DebugMode = debug == 1; } #if DEBUG State.DebugMode = true; #else ServerLogger.LogWarning("Server is started using debug mode config flag! Be sure this is what you want."); #endif ServerLogger.Log($"Starting server listening on port {port}, with a maximum of {maxConnections} connections."); //Alright, now onto the regular server. State.Config = new NetPeerConfiguration("RebuildZoneServer"); State.Config.Port = port; State.Config.MaximumConnections = maxConnections; State.Config.EnableMessageType(NetIncomingMessageType.ConnectionApproval); State.Server = new NetServer(State.Config); State.Server.Start(); var handlerCount = System.Enum.GetNames(typeof(PacketType)).Length; State.PacketHandlers = new Action <NetIncomingMessage> [handlerCount]; foreach (var type in Assembly.GetAssembly(typeof(NetworkManager)).GetTypes() .Where(t => t.IsClass && t.IsSubclassOf(typeof(ClientPacketHandler)))) { var handler = (ClientPacketHandler)Activator.CreateInstance(type); var packetType = handler.PacketType; handler.State = State; if (State.PacketHandlers[(int)packetType] != null) { throw new Exception($"Duplicate packet handler exists for type {packetType}!"); } State.PacketHandlers[(int)packetType] = handler.HandlePacket; } for (var i = 0; i < handlerCount; i++) { if (State.PacketHandlers[i] == null) { ServerLogger.Debug($"No packet handler for packet type PacketType.{(PacketType) i} exists."); State.PacketHandlers[i] = State.PacketHandlers[(int)PacketType.UnhandledPacket]; } } ServerLogger.Log("Server started."); }
public World() { Instance = this; var initialMaxEntities = NextPowerOf2(initialEntityCount); if (initialMaxEntities < 1024) { initialMaxEntities = 1024; } ecsWorld = new EcsWorld(initialMaxEntities); ecsSystems = new EcsSystems(ecsWorld) .Inject(this) .Add(new MonsterSystem()) .Add(new CharacterSystem()) .Add(new PlayerSystem()); ecsSystems.Init(); if (DataManager.TryGetConfigValue("SingleMobTest", out var mobName)) { DataManager.DoSingleMobTest(mobName); } var maps = DataManager.Maps; var entities = 0; for (var j = 0; j < maps.Count; j++) { var mapData = maps[j]; try { var map = new Map(this, mapData.Code, mapData.WalkData); map.Id = j; mapIdLookup.Add(mapData.Code, j); var spawns = DataManager.GetSpawnsForMap(mapData.Code); if (spawns != null) { for (var i = 0; i < spawns.Count; i++) { var s = spawns[i]; var mobId = DataManager.GetMonsterIdForCode(s.Class); for (var k = 0; k < s.Count; k++) { var m = CreateMonster(map, mobId, s.X, s.Y, s.Width, s.Height, s); if (!m.IsNull()) { map.AddEntity(ref m); entities++; } } } } var connectors = DataManager.GetMapConnectors(mapData.Code); if (connectors != null) { for (var i = 0; i < connectors.Count; i++) { var c = connectors[i]; var mobId = 1000; var m = CreateMonster(map, mobId, c.SrcArea.MidX, c.SrcArea.MidY, 0, 0, null); if (!m.IsNull()) { map.AddEntity(ref m); } } } Maps.Add(map); } catch (Exception e) { ServerLogger.LogError($"Failed to load map {mapData.Name} ({mapData.Code}) due to error while loading: {e.Message}"); } } mapCount = maps.Count; ServerLogger.Log($"World started with {entities} entities."); }