Appearance
3. Module Architecture
3.1 Common module (AppelTools-Common.jar)
Pure Java library. No Bukkit or Velocity classes are referenced in common; the platform modules implement adapter interfaces declared here. Provides:
- Database (HikariCP + MySQL) with a self-migrating schema system.
- All persistent data classes (POJOs) and DAO interfaces.
- A configuration framework based on
ConfigKey<T>/MessageKey<T>with YAML + ConfigLib. - The
Permissionsconstants class. - The plugin-update subsystem (
PluginUpdaterwith six providers). - Chat filter (
RegexFilter) for advertising and curse-word detection. - The
Embedsfactory for DiscordMessageEmbeds. - A scheduler abstraction and a logger abstraction.
- A small pub/sub queue (
SignedQueue/QueuedData/SignedResult) used to coordinate cross-server chat moderation.
The Gradle task replaceTokens substitutes @version@, @description@, @author@ from Constants.java at compile time.
3.2 Paper module (AppelTools-Paper.jar)
A standard paper-plugin.yml plugin with a PluginLoader. The libraries are shaded into the jar and moved under their own namespace, so the descriptor holds no libraries: section. Responsibilities:
- Gameplay commands (teleport, gamemode, speed, fly, homes, economy, freeze, notes GUI).
- Per-server economy (Vault hook) and per-server balances.
- Player session wrapper (
ATPPlayer) with auto-save every 5 minutes. - Staff mode (vanish + tool kit + invsee + freeze + notes).
- Plugin-messaging listener for chat/command moderation and staff-mode sync from the proxy.
- HikariCP-backed DAO access (shared with common).
3.3 Velocity module (AppelTools-Velocity.jar)
Standard Velocity @Plugin. Responsibilities:
- Cross-server moderation: ban/mute/kick, IP-targeted variants, history, undo.
- Friend system, party system, private messaging.
- Cross-server chat filter and staff-chat broadcasting.
- Reports (with Discord embed).
- Maintenance mode (proxy-wide + per-Paper fan-out).
- Server restart scheduler with countdown broadcasts.
- Server registration (
/servers register/unregister/list). - Discord logging of all significant events.
- Plugin-messaging bridge:
PluginMessageListeneris the central dispatcher for all incoming cross-server channels.
3.4 Inter-Module Wiring
The Paper and Velocity modules share the same MySQL database but do not share a JVM. They synchronize via Velocity plugin-message channels (see 08-messaging.md).
┌──────────────┐ plugin messages ┌──────────────────────┐
│ Velocity │ ─────────────────▶ │ Paper (each node) │
│ Proxy │ ◀───────────────── │ │
└──────┬───────┘ └──────────┬───────────┘
│ │
└─────────────► MySQL ◄────────────────┘3.5 Adapter Pattern
The platform-agnostic contract is defined by me.Maussee.AppelTools.common.Adapters.AppelToolsAdapter (interface). It exposes:
java
SchedulerAdapter getScheduler();
AppelLogger getLogger();
ServerType getServerType(); // enum: VELOCITY, PAPER
String getServerName();
Path getDataDirectory();
Path getConfigPath();
LuckPerms getLuckPerms();
Database getDatabase();
AppelSettingsDB getAppelSettingsDB();
PlayerDataDB getPlayerDataDB();
PlayerServerDataDB getPlayerServerDataDB();
PunishmentDB getPunishmentDB();
UndonePunishmentDB getUndonePunishmentDB();
ServerDataDB getServerDataDB();
StaffInventoryDB getStaffInventoryDB();
FriendRequestDB getFriendRequestDB();
HomeDB getHomeDB();
PlayerManager<? extends ATUserAdapter> getPlayerManager();The platform modules (AppelToolsPaper and AppelToolsVelocity) implement this interface. Player types ATPPlayer (Paper) and ATVPlayer (Velocity) implement ATUserAdapter.
3.6 Package Layout
me.Maussee.AppelTools
├── common
│ ├── Adapters
│ ├── Config
│ ├── Database
│ │ └── DAO
│ ├── Discord
│ ├── Logger
│ ├── Punishments
│ ├── Queue
│ ├── Scheduler
│ ├── Types
│ │ ├── Data
│ │ └── Query
│ └── Utils
│ ├── Exceptions
│ └── Managers
├── paper
│ ├── Commands
│ │ ├── Economy
│ │ ├── Gamemode
│ │ ├── Helpers
│ │ │ ├── Arguments
│ │ │ ├── Contexts
│ │ │ └── Handler
│ │ ├── Home
│ │ ├── Speed
│ │ └── Teleport
│ │ └── Requests
│ ├── Config
│ ├── Discord
│ │ └── Commands
│ ├── Economy
│ ├── Events
│ │ └── Modifiers
│ ├── Types
│ │ └── Debug
│ └── Utils
│ ├── Managers
│ └── Scheduler
└── velocity
├── Commands
│ ├── Friends
│ ├── Helpers
│ │ ├── Arguments
│ │ ├── Contexts
│ │ └── Handler
│ ├── Message
│ ├── Other
│ ├── Party
│ ├── Punishment
│ ├── Report
│ └── Staff
├── Config
├── Discord
│ └── Commands
│ └── Helpers
│ └── Arguments
├── Events
│ └── Modifiers
├── Types
└── Utils
├── Managers
└── Scheduler3.7 Lifecycles
Paper (AppelToolsPaperBootstrap.onEnable → AppelToolsPaper constructor)
- Set paths and data directory; throw
StartupExceptionon failure. - Load
config.yml,messages.yml,data.ymlviaYamlStore. - Set
LocalefromConfig.ServerInfo.LOCALE; setserverNamefromConfig.ServerInfo.NAME. - Generate and persist
serverUuid(random) if unset. - Resolve
LuckPermsprovider; throw if missing. - Register
VaultEconomyProviderand resolve it back. - Create player manager, console, baltop calculator.
- Create all DAOs.
- Setup
Database(Hikari pool) and async-loadServerDatafor the server's port. - Create
CommandRegistrarandModuleManager; load modules and register commands. - Create
StaffInventoryManager. - If
Modules.Discord.ROOT.isEnabled()and token non-empty, loadDiscordBotwith commands (filtering Bukkit listeners out). - Run
PluginChecker.checkPlugins(). - Create
PluginUpdaterManager. playerManager.startAutoSaveTask()(5-minute interval).
onShutdown() stops auto-save, awaits saves, unregisters commands, unloads Discord, disconnects DB.
Velocity (AppelToolsVelocityBootstrap @Plugin → AppelToolsVelocity.onProxyInitialization)
- Inject
Logger,ProxyServer,PluginManager,@DataDirectory Path data. - Construct managers/services.
- Register Velocity event listeners (forwarded by bootstrap).
- Connect to MySQL via
Database. - Build LiteCommands via
CommandRegistrar. - Load modules via
ModuleManager. - Optionally start
DiscordBot,PunishmentManagerauto-save,AnnouncementManager.
onProxyShutdown() reverses: stops schedulers, unregisters commands, disconnects DB, unloads Discord.
3.8 Library Relocations (shadowJar)
To avoid classpath conflicts when deployed alongside other plugins:
Paper shadowJar relocates:
dev.rollczi.litecommands→me.Maussee.AppelTools.libs.litecommands
Velocity shadowJar relocates:
com.mysql→me.Maussee.AppelTools.libs.mysqlcom.zaxxer.hikari→me.Maussee.AppelTools.libs.hikaridev.rollczi.litecommands→me.Maussee.AppelTools.libs.litecommandsnet.dv8tion.jda→me.Maussee.AppelTools.libs.jda