コード例 #1
0
        private static void ShutdownProcesses(object _, EventArgs ev)
        {
            Running = false;

            if (!AuthenticationServer.Process.HasExited)
            {
                AuthenticationServer.Process.Kill();
            }

            if (!CharacterServer.Process.HasExited)
            {
                CharacterServer.Process.Kill();
            }

            foreach (var server in WorldServers.Where(server => !server.Process.HasExited))
            {
                server.Process.Kill();
            }

            if (!(ev is ConsoleCancelEventArgs cancelEv))
            {
                return;
            }

            cancelEv.Cancel = true;

            Environment.Exit(0);
        }
コード例 #2
0
        public WorldServer GetWorldServer(int mapId)
        {
            if (WorldServers.TryGetValue(mapId, out var worldServer) || WorldServers.TryGetValue(-1, out worldServer))
            {
                return(worldServer);
            }

            return(null);
        }
コード例 #3
0
ファイル: MasterServer.cs プロジェクト: Wincent01/Nova
        private static async Task HandleRequest(WorldServerRequest request)
        {
            await using var ctx = new NovaContext();

            if (request.State == WorldServerRequestState.Unanswered)
            {
                //
                // Search for available server
                //

                foreach (var worldServer in WorldServers.Where(w => w.ZoneId == request.ZoneId))
                {
                    var specification = await ctx.Specifications.FirstAsync(s => s.Id == worldServer.Id);

                    if (specification.ActiveUserCount >= specification.MaxUserCount)
                    {
                        continue;
                    }

                    var req = await ctx.WorldServerRequests.FirstAsync(r => r.Id == request.Id);

                    req.SpecificationId = specification.Id;

                    req.State = WorldServerRequestState.Complete;

                    await ctx.SaveChangesAsync();

                    return;
                }

                //
                // Start new server
                //

                ushort instanceId = 0;

                for (var i = 0; i < ushort.MaxValue; i++)
                {
                    if (WorldServers.Any(w => w.InstanceId == instanceId))
                    {
                        instanceId++;

                        continue;
                    }

                    await AnswerRequest(request, instanceId);

                    break;
                }
            }
        }
コード例 #4
0
ファイル: MasterServer.cs プロジェクト: Wincent01/Nova
        private static async Task HandleRequests()
        {
            while (true)
            {
                await Task.Delay(100);

                await using var ctx = new NovaContext();

                //
                // Cleanup
                //

                for (var index = 0; index < WorldServers.Count; index++)
                {
                    var worldServer = WorldServers[index];

                    if (worldServer.Process.HasExited)
                    {
                        WorldServers.RemoveAt(index);
                    }
                    else
                    {
                        var specifications = await ctx.Specifications.FirstAsync(w => w.Id == worldServer.Id);

                        if (specifications.ActiveUserCount != default)
                        {
                            worldServer.EmptyTime = default;

                            continue;
                        }

                        worldServer.EmptyTime++;

                        if (worldServer.EmptyTime != 10000)
                        {
                            continue;
                        }

                        // Evil, but works
                        worldServer.Process.Kill();

                        WorldServers.RemoveAt(index);
                    }
                }

                foreach (var request in ctx.WorldServerRequests)
                {
                    await HandleRequest(request);
                }
            }
        }
コード例 #5
0
        public WorldServer GetWorldServer(int mapId)
        {
            WorldServer worldServer;

            // Try to get available world servers for the specific map or for all maps (-1).
            if (WorldServers.TryGetValue(mapId, out worldServer) || WorldServers.TryGetValue(-1, out worldServer))
            {
                if (Helper.CheckConnection(worldServer.Address, worldServer.Port))
                {
                    return(worldServer);
                }
            }

            return(null);
        }
コード例 #6
0
            public void Register(WsRealmInfo info)
            {
                if (info.RealmPassword != CfgNetwork.Default.RealmPassword)
                {
                    Log.Info($"Realm id:{info.Id} not passed!");
                    return;
                }
                if (WorldServers.ContainsKey(info.Id))
                {
                    Log.Info("Server already registered!");
                    return;
                }

                WorldServers.TryAdd(info.Id, info);

                Log.Info($"Realm server: {info.RealmName} registered!");
            }
コード例 #7
0
        void LoadAvailableWorldServers()
        {
            var worldServers = DB.Auth.Select <WorldServer>();

            if (worldServers.Count == 0)
            {
                Log.Error("No WorldServers available.");
            }

            worldServers.ForEach(ws =>
            {
                if (WorldServers.TryAdd(ws.MapId, ws))
                {
                    Log.Normal("Added new WorldServer for Map '{0}' at '{1}:{2}'.", ws.MapId, ws.Address, ws.Port);
                }
            });

            Log.Normal($"Loaded {WorldServers.Count} WorldServers.");
            Log.Message();
        }
コード例 #8
0
        private static async Task HandleRequests()
        {
            while (Running)
            {
                await Task.Delay(50);

                if (!Running)
                {
                    return;
                }

                await using var ctx = new UchuContext();

                //
                // Auto restart these
                //

                if (AuthenticationServer.Process.HasExited)
                {
                    await StartAuthentication();
                }

                if (CharacterServer.Process.HasExited)
                {
                    await StartCharacter();
                }

                //
                // Cleanup
                //

                for (var index = 0; index < WorldServers.Count; index++)
                {
                    var worldServer = WorldServers[index];

                    if (worldServer.Process.HasExited)
                    {
                        // We don't auto restart world servers

                        var specs = await ctx.Specifications.FirstOrDefaultAsync(s => s.Id == worldServer.Id);

                        if (specs != default)
                        {
                            ctx.Specifications.Remove(specs);

                            await ctx.SaveChangesAsync();
                        }

                        WorldServers.RemoveAt(index);
                    }
                    else
                    {
                        var specifications = await ctx.Specifications.FirstAsync(w => w.Id == worldServer.Id);

                        if (specifications.ActiveUserCount != default)
                        {
                            worldServer.EmptyTime = default;

                            continue;
                        }

                        worldServer.EmptyTime++;

                        if (worldServer.EmptyTime != 10000)
                        {
                            continue;
                        }

                        // Evil, but works
                        worldServer.Process.Kill();

                        WorldServers.RemoveAt(index);
                    }
                }

                foreach (var request in ctx.WorldServerRequests)
                {
                    if (request.State == WorldServerRequestState.Unanswered)
                    {
                        //
                        // Search for available server
                        //

                        foreach (var worldServer in WorldServers.Where(w => w.ZoneId == request.ZoneId))
                        {
                            var specification = await ctx.Specifications.FirstAsync(s => s.Id == worldServer.Id);

                            if (specification.ActiveUserCount >= specification.MaxUserCount)
                            {
                                continue;
                            }

                            var req = await ctx.WorldServerRequests.FirstAsync(r => r.Id == request.Id);

                            req.SpecificationId = specification.Id;

                            req.State = WorldServerRequestState.Complete;

                            await ctx.SaveChangesAsync();

                            goto continueToNext;
                        }

                        //
                        // Start new server
                        //

                        var clone = ctx.Specifications.Count(c => c.ZoneId == request.ZoneId);

                        int port;

                        if (Config.Networking.WorldPorts?.Any() ?? false)
                        {
                            //
                            // Check for available user specified ports.
                            //
                            // Sometimes, most likely when someone is hosting a public instance, they have to
                            // port forward. These are therefore the only ports that can be used.
                            //

                            var ports = Config.Networking.WorldPorts.ToList();

                            foreach (var specification in ctx.Specifications)
                            {
                                if (ports.Contains(specification.Port))
                                {
                                    ports.Remove(specification.Port);
                                }
                            }

                            port = ports.FirstOrDefault();
                        }
                        else
                        {
                            //
                            // Pick the first port which is not used by another server instance.
                            //

                            port = 2003;

                            while (ctx.Specifications.Any(s => s.Port == port))
                            {
                                port++;
                            }
                        }

                        //
                        // Find request.
                        //

                        var serverRequest = await ctx.WorldServerRequests.FirstAsync(
                            r => r.Id == request.Id
                            );

                        if (port == default)
                        {
                            //
                            // We were unable to find a user specified port.
                            //

                            serverRequest.State = WorldServerRequestState.Error;

                            await ctx.SaveChangesAsync();
                        }
                        else
                        {
                            //
                            // Start the new server instance.
                            //

                            serverRequest.SpecificationId = await StartWorld(
                                request.ZoneId,
                                (uint)clone,
コード例 #9
0
ファイル: ClusterServer.cs プロジェクト: tech-bear/Rhisis
 /// <inheritdoc />
 public WorldServerInfo GetWorldServerById(int id) => WorldServers.FirstOrDefault(x => x.Id == id);