Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public void start(final File dataFolder) throws IOException, LoginException, InterruptedException {
- Objects.checkArgument(!this.running, "bot is already running");
- Objects.checkNotNull(dataFolder, "cannot start without a valid directory");
- Objects.checkArgument(dataFolder.exists(), String.format("data directory doesn't exist '%s'", dataFolder.getAbsolutePath()));
- Objects.checkArgument(dataFolder.isDirectory(), "provided data directory isn't a valid directory");
- Bot.instance = this;
- this.running = true;
- this.startTime = System.currentTimeMillis();
- //check if the bot is already running (prevent accidentally starting 2 instances)
- this.lockFile = new File(dataFolder, "bot.lock");
- try {
- if (this.lockFile.exists()) {
- this.lockFile.delete();
- }
- this.lockFile.createNewFile();
- this.channel = new RandomAccessFile(this.lockFile, "rw").getChannel();
- this.fileLock = this.channel.tryLock();
- } catch (final IOException ignored) {
- }
- //If it's null, then a file lock couldn't be acquired so something else already has a read write access lock
- if (this.fileLock == null) {
- throw new IllegalStateException("Another instance is already running");
- }
- //check for our config file
- final File file = new File(dataFolder, "bot.toml");
- if (!file.exists()) {
- LOGGER.info("Configuration file couldn't be found, creating it...");
- FileUtils.copyURLToFile(this.getClass().getResource("/bot.toml"), file); //config wasn't found so copy internal one (resources/bot.json)
- LOGGER.info(String.format("Configuration file was created at %s, exiting...", file.getCanonicalPath()));
- return;
- }
- LOGGER.info("Loading configuration...");
- this.config = new Toml().read(file);
- LOGGER.info("Loading databases...");
- final String user = this.config.getString("mongo.user");
- final String pass = this.config.getString("mongo.psswd");
- final String host = this.config.getString("mongo.host");
- final int port = Math.toIntExact(this.config.getLong("mongo.port"));
- if ((user == null || user.isEmpty()) || (pass == null || pass.isEmpty())) {
- LOGGER.info("MongoDB information is not configured, attempting to connect with no authentication.");
- this.mongoClient = new MongoClient(host, port);
- } else {
- this.mongoClient = new MongoClient(new MongoClientURI(String.format("mongodb://%s:%s@%s:%s", user, pass, host, port)));
- }
- this.mongoDatabase = this.mongoClient.getDatabase(this.config.getString("mongo.database"));
- LOGGER.info("A database connection was successfully established!");
- LOGGER.info("Loading data managers...");
- //just class initialization
- this.economy = new EconomyImpl();
- this.commandRegistry = new CommandRegistryImpl();
- this.eventRegistry = new EventRegistryImpl();
- this.moduleLoader = new ModuleLoaderImpl(this);
- this.client = new WebhookClientBuilder(this.config.getString("client.webhook"))
- .setHttpClient(Bot.HTTP_CLIENT)
- .setDaemon(true)
- .build();
- LOGGER.info("Retrieving recommended shard count from discord endpoint...");
- final String token = this.config.getString("client.token");
- final String auth = "Bot " + token;
- final Request request = new Request.Builder().url("https://discordapp.com/api/gateway/bot")
- .header("Content-Type", "application/json;charset=utf8mb4")
- .header("Authorization", auth)
- .build();
- //Querying discord for how many shards we should be running
- final int shardTotal;
- try (final Response response = HTTP_CLIENT.newCall(request).execute()) {
- if (response.code() != 200) {
- throw new RuntimeException("Couldn't retrieve recommended shard count.");
- }
- @SuppressWarnings("ConstantConditions")
- final String json = response.body().string();
- final JsonObject object = JSON_PARSER.parse(json).getAsJsonObject();
- shardTotal = object.get("shards").getAsInt(); //get the recommended shard count
- } catch (final IOException ex) { //an error occurred?
- throw new RuntimeException("Couldn't retrieve shard count", ex);
- }
- final DefaultShardManagerBuilder builder = new DefaultShardManagerBuilder()
- .setToken(token)
- .setShardsTotal(shardTotal)
- .setShards(0, shardTotal - 1)
- .setAutoReconnect(true)
- .setEnableShutdownHook(false)
- .setGame(Game.of(Game.GameType.DEFAULT, this.config.getString("client.game", "Sheepy 2.0!")))
- .setAudioEnabled(true)
- .setBulkDeleteSplittingEnabled(false)
- .setUseShutdownNow(true)
- .setHttpClient(HTTP_CLIENT);
- builder.addEventListeners(
- new ServerMessageListener(this),
- new ServerJoinQuitListener(this),
- new ServerMemberListener(this),
- new ServerMemberReactionListener(this),
- new ServerMemberVoiceListener(this),
- new ServerModerationListener(this),
- new ServerRoleListener(this)
- );
- final String webhookUrl = this.config.getString("client.webhook");
- if (webhookUrl == null) {
- LOGGER.info("No webhook url was specified, JDA status logging has been disabled.");
- } else {
- LOGGER.info("Connecting to webhook...");
- this.client = new WebhookClientBuilder(webhookUrl)
- // .setExecutorService(SINGLE_EXECUTOR_SERVICE)
- .setHttpClient(HTTP_CLIENT)
- .build();
- builder.addEventListeners(new JdaStatusListener(this));
- }
- LOGGER.info("Starting shards...");
- this.shardManager = builder.build();
- //Sleep until all shards are connected (shard manager builder doesn't have a buildBlocking method)
- while (this.shardManager.getShards().stream().anyMatch(shard -> shard.getStatus() != JDA.Status.CONNECTED)) {
- Thread.sleep(50L);
- }
- LOGGER.info("Registering default commands...");
- I18n.loanI18n(this.getClass());
- //null is used in the command registry to represent this
- //as being a default command.
- this.commandRegistry.registerCommand(Command.builder()
- .names("evaluate", "eval")
- .syntax(ArgumentParsers.REMAINING_STRING_NO_QUOTE)
- .executor(new EvaluateCommand())
- .build());
- this.commandRegistry.registerCommand(Command.builder()
- .names("buildinfo")
- .executor(new BuildInfoCommand())
- .build());
- LOGGER.info("Loading modules...");
- //If there were no modules to loanI18n it just returns an empty list, so no harm done
- final Collection<Module> modules = this.moduleLoader.loadModules();
- modules.forEach(this.moduleLoader::enableModule);
- LOGGER.info("Loaded " + this.moduleLoader.getEnabledModules().size() + " modules");
- /*
- * Check if we're running on an official release
- * We don't want statistics of the dev bot being submitted
- * to DBL or Carbon.
- *
- * To determine whether we're running official or development
- * the environment variable "bot_env" is queried,
- *
- * If the environment variable doesn't exist,
- * we assume it's development, if it does then
- * we get the environment type by the value in the variable
- */
- if (Environment.getEnvironment().isRelease()) {
- LOGGER.info("Currently running an official release, loading bot list agents...");
- LOGGER.info("Starting Carbonitex agent...");
- Scheduler.getInstance().runTaskRepeating(new CarbonitexAgent(this, this.config.getString("client.agent.carbon.key")), 0L, TimeUnit.MINUTES.toMillis(30));
- LOGGER.info("Starting Discord Bot List agent...");
- Scheduler.getInstance().runTaskRepeating(new DiscordBotListAgent(this, this.config.getString("client.agent.dbl.key")), 0L, TimeUnit.MINUTES.toMillis(30));
- }
- LOGGER.info("Starting metrics task...");
- Scheduler.getInstance().runTaskRepeating(new MetricsTask(this), TimeUnit.HOURS.toMillis(1), TimeUnit.HOURS.toMillis(1));
- LOGGER.info("Starting heart beat...");
- Scheduler.getInstance().runTaskRepeating(new HeartBeatTask(this), 0L, TimeUnit.SECONDS.toMillis(15));
- LOGGER.info("Registering shutdown hook...");
- //register our shutdown hook so if something happens sheepy gets properly shutdown
- Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown, "Sheepy-Shutdown-Thread"));
- LOGGER.info(String.format("Startup completed! Took %dms, api version: %s.", (System.currentTimeMillis() - this.startTime), BotInfo.VERSION));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement