예제 #1
0
        private void Execute(Action action, string actionInfo)
        {
            Console.WriteLine();
            Console.Write(actionInfo);

            _errors.Clear();
            action.Invoke();

            if (_errors.Any())
            {
                _verificationResult = false;
                ConsoleExt.WriteError(" - ERROR");
            }
            else if (_warnings.Any())
            {
                ConsoleExt.WriteWarning(" - WARNING");
            }
            else
            {
                ConsoleExt.WriteSuccess(" - OK");
            }

            _errors.ToList().ForEach(e => ConsoleExt.WriteError(string.Concat(" - ", e)));
            _warnings.ToList().ForEach(e => ConsoleExt.WriteWarning(string.Concat(" - ", e)));
        }
예제 #2
0
        static void Main(string[] args)
        {
            Console.CancelKeyPress += (sender, e) =>
            {
                _quitEvent.Set();
                e.Cancel = true;
            };

            ConsoleExt.WriteInfo($"[DataConsumer] Starting...");
            var configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.json");//Strings.DefaultConfigFileName);

            try
            {
                var config = Config.Load(configPath);
                if (config == null)
                {
                    Console.WriteLine($"Failed to load config {configPath}");
                    return;
                }

                var consumer = new DataConsumer(config);
                consumer.Start();

                _quitEvent.WaitOne();
                ConsoleExt.WriteInfo($"[DataConsumer] Received Ctrl+C event. Exiting...");
            }
            catch (Exception ex)
            {
                ConsoleExt.WriteError($"Config: {ex}");
                Console.ReadKey();
                return;
            }
        }
예제 #3
0
        static void Main(string[] args)
        {
            Console.CancelKeyPress += (sender, e) =>
            {
                _quitEvent.Set();
                e.Cancel = true;
            };

            ConsoleExt.WriteInfo($"[WebhookProcessor] Starting...");
            var configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.json");//Strings.DefaultConfigFileName);

            try
            {
                _config = Config.Load(configPath);
                if (_config == null)
                {
                    Console.WriteLine($"Failed to load config {configPath}");
                    return;
                }

                var options = new ConfigurationOptions
                {
                    EndPoints =
                    {
                        { $"{_config.Redis.Host}:{_config.Redis.Port}" }
                    },
                    Password = _config.Redis.Password,
                };
                _redis = ConnectionMultiplexer.Connect(options);
                _redis.ConnectionFailed += RedisOnConnectionFailed;
                _redis.ErrorMessage     += RedisOnErrorMessage;
                _redis.InternalError    += RedisOnInternalError;
                if (_redis.IsConnected)
                {
                    _subscriber = _redis.GetSubscriber();
                    _subscriber.Subscribe(/*_config.Redis.QueueName*/ "*", SubscriptionHandler);
                    //_redisDatabase = _redis.GetDatabase(_config.Redis.DatabaseNum);
                }

                ConsoleExt.WriteInfo($"[WebhookProcessor] Starting...");
                WebhookController.Instance.SleepIntervalS = 5;
                WebhookController.Instance.Start();
                ConsoleExt.WriteInfo($"[WebhookProcessor] Started, waiting for webhook events");

                _quitEvent.WaitOne();
                ConsoleExt.WriteInfo($"[WebhookProcessor] Received Ctrl+C event. Exiting...");
            }
            catch (Exception ex)
            {
                ConsoleExt.WriteError($"[WebhookProcessor] Error: {ex}");
                Console.ReadKey();
                return;
            }
        }
        /*
         * public virtual async Task DeleteByIdAsync(string key)
         * {
         *  var entity = _dbContext.Set<TEntity>().FirstOrDefault(x => x.Id == key);
         *  await _dbContext.Set<TEntity>().DeleteAsync(entity);
         * }
         */

        #endregion

        public virtual async Task AddOrUpdateAsync(TEntity entity)
        {
            try
            {
                _dbContext.SingleMerge(entity);
                await _dbContext.SaveChangesAsync().ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                ConsoleExt.WriteError($"AddOrUpdateAsync: {ex}");
            }
        }
예제 #5
0
        private static T LoadInit <T>(string filePath)
        {
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException($"{filePath} file not found.", filePath);
            }

            var data = File.ReadAllText(filePath);

            if (string.IsNullOrEmpty(data))
            {
                ConsoleExt.WriteError($"File {filePath} is empty.");
                return(default);
예제 #6
0
        public void Stop()
        {
            //_timer.Stop();
            IsRunning = false;
            if (_thread == null)
            {
                return;
            }

            _thread.Interrupt();
            if (!_thread.Join(2000))
            {
                ConsoleExt.WriteError($"[WebhookController] Failed to abort webhook thread");
            }
            _thread = null;
        }
 private Task PushData <T>(string channel, T data)
 {
     try
     {
         if (data == null)
         {
             return(Task.CompletedTask);
         }
         //_subscriber.PublishAsync(channel, data.ToJson(), CommandFlags.FireAndForget);
         _redisDatabase.ListRightPushAsync(Startup.Config.Redis.QueueName, new { channel, data, }.ToJson());
     }
     catch (Exception ex)
     {
         ConsoleExt.WriteError(ex);
     }
     return(Task.CompletedTask);
 }
예제 #8
0
        public static DeviceControllerContext CreateDeviceControllerContext(string connectionString)// where T : DbContext
        {
            try
            {
                var optionsBuilder = new DbContextOptionsBuilder <DeviceControllerContext>();
                optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));

                var ctx = new DeviceControllerContext(optionsBuilder.Options);
                //ctx.ChangeTracker.AutoDetectChangesEnabled = false;
                return(ctx);
            }
            catch (Exception ex)
            {
                ConsoleExt.WriteError($"[RawSql] Result: {ex.Message}");
                Environment.Exit(0);
            }
            return(null);
        }
예제 #9
0
        public static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;
            var org = Console.ForegroundColor;

            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine($"Chuck Device Controller v{Assembly.GetExecutingAssembly().GetName().Version}");
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine("Starting...");
            Console.ForegroundColor = org;

            var configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Strings.DefaultConfigFileName);

            try
            {
                Startup.Config = Config.Load(configPath);
                if (Startup.Config == null)
                {
                    Console.WriteLine($"Failed to load config {configPath}");
                    return;
                }
            }
            catch (Exception ex)
            {
                ConsoleExt.WriteError($"Config: {ex.Message}");
                Console.ReadKey();
                return;
            }
            // Start database migrator
            var migrator = new DatabaseMigrator();

            while (!migrator.Finished)
            {
                Thread.Sleep(50);
            }

            CreateHostBuilder(args).Build().Run();
        }
 public virtual async Task AddOrUpdateAsync(List <TEntity> entities)
 {
     try
     {
         await _dbContext.BulkMergeAsync(entities, x =>
         {
             x.AutoMap   = AutoMapType.ByIndexerName;
             x.BatchSize = 100;
             //x.BatchTimeout = 10 * 1000;
             x.InsertIfNotExists  = true;
             x.InsertKeepIdentity = true;
             x.MergeKeepIdentity  = true;
             x.Resolution         = ResolutionType.Smart;
             x.UseTableLock       = true;
             x.AllowDuplicateKeys = true;
             //x.ColumnPrimaryKeyExpression = entity => entity.Id || entity.Uuid;
         }).ConfigureAwait(false);
     }
     catch (Exception ex)
     {
         ConsoleExt.WriteError($"[EfCoreRepository] AddOrUpdateAsync: {ex.Message}");
     }
 }
예제 #11
0
        public static void Main(string[] args)
        {
            ConsoleExt.WriteInfo($"ProtoParser starting...");
            var configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.json");//Strings.DefaultConfigFileName);

            try
            {
                Startup.Config = Config.Load(configPath);
                if (Startup.Config == null)
                {
                    Console.WriteLine($"Failed to load config {configPath}");
                    return;
                }
            }
            catch (Exception ex)
            {
                ConsoleExt.WriteError($"Config: {ex.Message}");
                Console.ReadKey();
                return;
            }

            CreateHostBuilder(args).Build().Run();
        }
예제 #12
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public async void ConfigureServices(IServiceCollection services)
        {
            /*
             * services.AddSingleton<IConfiguration>(provider => new ConfigurationBuilder()
             *      .AddEnvironmentVariables()
             *      .AddJsonFile("config.json", optional: false, reloadOnChange: true)
             *      .Build());
             */

            services.AddHealthChecks()
            .AddMySql(DbConfig.ToString())
            .AddRedis($"{Config.Redis.Host}:{Config.Redis.Port}")
            .AddProcessHealthCheck(Process.GetCurrentProcess().ProcessName, p => p.Length >= 1)
            .AddProcessAllocatedMemoryHealthCheck((int)Environment.WorkingSet)
            .AddDiskStorageHealthCheck(setup =>
            {
                foreach (var drive in DriveInfo.GetDrives())
                {
                    if (drive.IsReady && drive.DriveType == DriveType.Fixed)
                    {
                        setup.AddDrive(drive.RootDirectory.FullName);
                    }
                }
            })
            //.AddDnsResolveHealthCheck(setup => setup.ResolveHost("https://google.com"))
            .AddPingHealthCheck(setup => setup.AddHost("discord.com", 10), "discord");

            services.AddHealthChecksUI(settings =>
            {
                settings.AddHealthCheckEndpoint("Main Health Check", "/health");
                settings.MaximumHistoryEntriesPerEndpoint(50);
            })
            .AddInMemoryStorage();

            // Save sessions to the database
            // TODO: Allow for custom column names
            services.AddDistributedMemoryCache();
            services.AddDistributedMySqlCache(options =>
            {
                options.ConnectionString = DbConfig.ToString();
                //options.DefaultSlidingExpiration
                options.ExpiredItemsDeletionInterval = TimeSpan.FromHours(1);
                options.SchemaName = DbConfig.Database;
                options.TableName  = "session";
            });
            services.AddSession(options =>
            {
                options.IdleTimeout        = TimeSpan.FromMinutes(60);
                options.Cookie.Name        = "cdc.session";
                options.Cookie.HttpOnly    = true;
                options.Cookie.IsEssential = true;
            });

            services.AddSwaggerGen(c => c.SwaggerDoc("v1", new OpenApiInfo {
                Title = "ChuckDeviceController", Version = "v1"
            }));

            services.AddDbContextFactory <DeviceControllerContext>(options =>
                                                                   options.UseMySql(DbConfig.ToString(), ServerVersion.AutoDetect(DbConfig.ToString())), ServiceLifetime.Singleton);
            services.AddDbContext <DeviceControllerContext>(options =>
                                                            //options.UseMySQL(DbConfig.ToString()));
                                                            options.UseMySql(DbConfig.ToString(), ServerVersion.AutoDetect(DbConfig.ToString())), ServiceLifetime.Scoped);

            /*
             * services.AddDbContextPool<DeviceControllerContext>(
             *  options => options.UseMySql(ServerVersion.AutoDetect(DbConfig.ToString()),
             *      mySqlOptions =>
             *      {
             *          mySqlOptions.EnableRetryOnFailure(
             *              maxRetryCount: 3,
             *              maxRetryDelay: TimeSpan.FromSeconds(5),
             *              errorNumbersToAdd: null
             *          );
             *      }
             * ), 128); // TODO: Configurable PoolSize (128=default)
             */

            services.AddScoped(typeof(IAsyncRepository <>), typeof(EfCoreRepository <,>));
            services.AddScoped <Config>();

            // Redis
            var options = new ConfigurationOptions
            {
                AbortOnConnectFail = false,
                EndPoints          =
                {
                    { $"{Config.Redis.Host}:{Config.Redis.Port}" }
                },
                Password = Config.Redis.Password,
            };

            try
            {
                services.AddSingleton <IConnectionMultiplexer>(ConnectionMultiplexer.Connect(options));
            }
            catch (Exception ex)
            {
                ConsoleExt.WriteError(ex.Message);
                Environment.Exit(0);
            }

            // Cross origin resource sharing configuration
            services.AddCors(option => option.AddPolicy("Test", builder => {
                builder.AllowAnyOrigin()
                .AllowAnyHeader()
                .AllowAnyMethod();
            }));

            // Profiling
            // The services.AddMemoryCache(); code is required - there is a bug in
            // MiniProfiler, if we have not configured MemoryCache, it will fail.
            if (Config.EnableProfiler)
            {
                services.AddMemoryCache();
                services.AddEntityFrameworkMySql().AddDbContext <DeviceControllerContext>();
                services.AddMiniProfiler(options =>
                {
                    options.RouteBasePath            = "/profiler";
                    options.EnableMvcViewProfiling   = true;
                    options.EnableMvcFilterProfiling = true;
                    options.EnableServerTimingHeader = true;
                    options.ShowControls             = true;
                    options.TrackConnectionOpenClose = true;
                }).AddEntityFramework();
            }

            services.AddResponseCaching();

            services.AddControllers();
            services.AddControllersWithViews();

            await InstanceController.Instance.Start().ConfigureAwait(false);

            await AssignmentController.Instance.Start().ConfigureAwait(false);

            // TODO: Better impl, use singleton class
            _redis      = ConnectionMultiplexer.Connect(options);
            _subscriber = _redis.GetSubscriber();
            _subscriber.Subscribe("*", PokemonSubscriptionHandler);
        }
예제 #13
0
 static void RedisOnInternalError(object sender, InternalErrorEventArgs e)
 {
     ConsoleExt.WriteError($"[WebhookProcessor] [Redis] {e.EndPoint}: {e.Exception}");
 }
예제 #14
0
 static void RedisOnErrorMessage(object sender, RedisErrorEventArgs e)
 {
     ConsoleExt.WriteError($"[WebhookProcessor] [Redis] {e.EndPoint}: {e.Message}");
 }
예제 #15
0
 static void RedisOnConnectionFailed(object sender, ConnectionFailedEventArgs e)
 {
     ConsoleExt.WriteError($"[WebhookProcessor] [Redis] {e.EndPoint}: {e.FailureType} {e.Exception}");
 }
예제 #16
0
        public async Task <Spawnpoint> HandleSpawnpoint(int timeTillHiddenMs, ulong timestampMs)
        {
            var now = DateTime.UtcNow.ToTotalSeconds();

            if (timeTillHiddenMs <= 90000 && timeTillHiddenMs > 0)
            {
                ExpireTimestamp           = Convert.ToUInt64(timestampMs + Convert.ToDouble(timeTillHiddenMs)) / 1000;
                IsExpireTimestampVerified = true;
                var unixDate     = timestampMs.FromMilliseconds();
                var secondOfHour = unixDate.Second + (unixDate.Minute * 60);
                return(new Spawnpoint
                {
                    Id = SpawnId ?? 0,
                    Latitude = Latitude,
                    Longitude = Longitude,
                    Updated = now,
                    DespawnSecond = (ushort)secondOfHour,
                    FirstSeenTimestamp = now,
                });
            }
            else
            {
                IsExpireTimestampVerified = false;
            }

            if (!IsExpireTimestampVerified && SpawnId != null)
            {
                Spawnpoint spawnpoint = null;
                try
                {
                    if (SpawnId != null)
                    {
                        // spawnpoint = await _spawnpointRepository.GetByIdAsync(SpawnId ?? 0).ConfigureAwait(false);
                    }
                }
                catch (Exception ex)
                {
                    ConsoleExt.WriteError($"[Pokemon] Error: {ex}");
                    spawnpoint = null;
                }
                if (spawnpoint != null && spawnpoint?.DespawnSecond != null)
                {
                    var unixDate      = timestampMs.FromMilliseconds();
                    var secondOfHour  = unixDate.Second + (unixDate.Minute * 60);
                    var despawnOffset = spawnpoint.DespawnSecond - secondOfHour;
                    if (spawnpoint.DespawnSecond < secondOfHour)
                    {
                        despawnOffset += 3600;
                    }
                    ExpireTimestamp           = now + (ulong)(despawnOffset ?? 0);
                    IsExpireTimestampVerified = true;
                }
                else
                {
                    spawnpoint = new Spawnpoint
                    {
                        Id                 = SpawnId ?? 0,
                        Latitude           = Latitude,
                        Longitude          = Longitude,
                        Updated            = now,
                        DespawnSecond      = null,
                        FirstSeenTimestamp = now,
                    };
                }
                return(await Task.FromResult(spawnpoint).ConfigureAwait(false));
            }

            if (ExpireTimestamp == 0)
            {
                //Console.WriteLine($"[Pokemon] ExpireTimestamp == 0");
                ExpireTimestamp           = DateTime.UtcNow.ToTotalSeconds();
                IsExpireTimestampVerified = false;
            }
            return(null);
        }