public async Task <object> AllocateWorld(string zone)
        {
            var response = new SeekWorldResponse();

            if (MasterServer.IsSubsidiary)
            {
                response.FailedReason = "is subsidiary";

                return(response);
            }

            if (!int.TryParse(zone, out var zoneId))
            {
                response.FailedReason = "invalid zone";

                return(response);
            }

            var toCheck = new List <int> {
                MasterServer.ApiPort
            };

            toCheck.AddRange(MasterServer.Subsidiaries);

            foreach (var subsidiary in toCheck)
            {
                var status = await MasterServer.Api.RunCommandAsync <MasterStatusResponse>(
                    subsidiary, "master/status"
                    ).ConfigureAwait(false);

                if (!status.CanHostAdditionWorldInstances)
                {
                    continue;
                }

                var details = await MasterServer.Api.RunCommandAsync <CommissionInstanceResponse>(
                    subsidiary, $"instance/commission?z={zoneId}"
                    ).ConfigureAwait(false);

                response.Success = true;

                response.ApiPort = details.ApiPort;

                response.Id = details.Id;

                return(response);
            }

            response.FailedReason = "out of servers";

            return(response);
        }
        public async Task <object> SeekWorld(string zone)
        {
            var response = new SeekWorldResponse();

            if (!int.TryParse(zone, out var zoneId))
            {
                response.FailedReason = "invalid zone";

                return(response);
            }

            var instances = await MasterServer.GetAllInstancesAsync();

            foreach (var instance in instances.Where(instance => instance.Zones.Contains(zoneId)))
            {
                var playerInfo = await MasterServer.Api.RunCommandAsync <ZonePlayersResponse>(
                    instance.ApiPort, $"world/players?z={zoneId}"
                    ).ConfigureAwait(false);

                if (!playerInfo.Success)
                {
                    Logger.Error(playerInfo.FailedReason);

                    throw new Exception(playerInfo.FailedReason);
                }

                if (playerInfo.Characters.Count >= playerInfo.MaxPlayers)
                {
                    continue;
                }

                response.Success = true;

                response.ApiPort = instance.ApiPort;

                response.Id = instance.Id;

                return(response);
            }

            response = await MasterServer.Api.RunCommandAsync <SeekWorldResponse>(
                MasterServer.MasterPort, $"master/allocate?z={zoneId}"
                ).ConfigureAwait(false);

            return(response);
        }