package moe.kyokobot.bot; import com.mewna.catnip.Catnip; import com.mewna.catnip.CatnipOptions; import com.mewna.catnip.cache.CacheFlag; import io.ebean.EbeanServer; import io.ebean.EbeanServerFactory; import io.ebean.config.ServerConfig; import io.ebean.datasource.DataSourceConfig; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; import moe.kyokobot.bot.command.CommandContextFactory; import moe.kyokobot.bot.command.CommandManager; import moe.kyokobot.bot.command.impl.DefaultCommandManager; import moe.kyokobot.bot.entity.EbeanClassRegistry; import moe.kyokobot.bot.i18n.I18n; import moe.kyokobot.bot.module.EventManager; import moe.kyokobot.bot.module.impl.DefaultModuleManager; import moe.kyokobot.bot.module.impl.ModuleEventManager; import moe.kyokobot.bot.module.impl.ModuleManager; import moe.kyokobot.shared.Settings; import moe.kyokobot.shared.entity.DatabaseEntity; import org.codejargon.feather.Feather; import org.codejargon.feather.Provides; import org.redisson.Redisson; import org.redisson.api.RedissonRxClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Singleton; import java.util.Set; import static com.mewna.catnip.shard.DiscordEvent.Raw; public class MainModule { private static final Logger logger = LoggerFactory.getLogger(MainModule.class); @Singleton @Provides Catnip catnip(Vertx vertx) { var settings = Settings.instance(); var options = new CatnipOptions(settings.apiKeys().get("discord")); options.memberChunkTimeout(settings.memberChunkTimeout()); options.cacheFlags(Set.of(CacheFlag.DROP_GAME_STATUSES)); options.chunkMembers(settings.memberChunking()); options.logUncachedPresenceWhenNotChunking(false); options.enableGuildSubscriptions(true); options.disabledEvents(Set.of(Raw.PRESENCE_UPDATE, "PRESENCES_REPLACE")); return Catnip.catnip(options, vertx); } @Singleton @Provides CommandManager commandManager(Catnip catnip, CommandContextFactory contextFactory, Feather feather) { return new DefaultCommandManager(catnip, contextFactory, feather); } @Singleton @Provides EbeanClassRegistry ebeanClassRegistry() { return new EbeanClassRegistry(); } @Singleton @Provides EbeanServer ebeanServer(EbeanClassRegistry registry, ModuleManager moduleManager) { var settings = Settings.instance(); var config = new ServerConfig(); config.setName("pg"); var dataSource = new DataSourceConfig() .setDriver(settings.jdbcDriverClass()) .setUrl(settings.databaseUrl()) .setUsername(settings.jdbcUser()) .setPassword(settings.jdbcPassword()); config.setDataSourceConfig(dataSource); config.setDefaultServer(true); config.setDdlCreateOnly(true); registry.get().forEach(className -> { try { config.addClass(moduleManager.findClass(className.replace("/", ".")).asSubclass(DatabaseEntity.class)); } catch (Exception e) { logger.error("Error registering database entity class: {}", className, e); } }); return EbeanServerFactory.create(config); } @Singleton @Provides RedissonRxClient redisson(Vertx vertx) { try { var redisConfig = Settings.instance().configureRedis(); redisConfig.setEventLoopGroup(vertx.nettyEventLoopGroup()); return Redisson.createRx(redisConfig); } catch (Exception e) { logger.error("Cannot create Redis client!", e); return null; } } @Singleton @Provides Globals globals(Catnip catnip) { return new Globals(catnip); } @Singleton @Provides I18n i18n() { return new I18n(); } @Singleton @Provides ModuleManager moduleManager(CommandManager commandManager, Feather feather, I18n i18n) { return new DefaultModuleManager(commandManager, feather, i18n); } @Singleton @Provides EventManager eventManager(Catnip catnip) { return new ModuleEventManager(catnip); } @Singleton @Provides Vertx vertx() { var options = new VertxOptions() .setEventLoopPoolSize(Settings.instance().eventLoopThreads()) .setPreferNativeTransport(true); return Vertx.vertx(options); } }