feat(docs): complete PlayHours mod implementation with comprehensive documentation

- Add complete PlayHours mod source code with all features:
  * Schedule enforcement with per-day schedules and midnight-spanning support
  * Login control with configurable thresholds and exemptions
  * Warnings and auto-kick system with countdown functionality
  * Force modes (NORMAL/FORCE_OPEN/FORCE_CLOSED) for maintenance
  * Whitelist/blacklist system for player access control
  * Date exceptions for holidays and special events
  * Multi-language support (English/French) with smart time formatting
  * LuckPerms integration with vanilla ops fallback
  * Dynamic MOTD system with real-time schedule display
  * Comprehensive command system with permission integration
  * TOML configuration with hot-reload support

- Add comprehensive documentation suite:
  * Installation guide with step-by-step setup instructions
  * Complete configuration reference with all options
  * Commands reference with usage examples
  * Features overview with detailed explanations
  * MOTD system configuration and customization guide
  * Permissions system documentation with LuckPerms integration
  * Technical details covering architecture and limitations
  * Usage examples with real-world scenarios
  * Changelog with version history

- Add resource files:
  * Language files (en_us.json, fr_fr.json) with localized messages
  * Mod metadata (mods.toml) with proper Forge configuration
  * Resource pack metadata (pack.mcmeta)

- Update build configuration:
  * Gradle build system with proper dependencies
  * Project properties and version management
  * Development environment setup

- Restructure documentation:
  * Replace old README.txt with new comprehensive README.md
  * Create modular documentation structure in docs/ directory
  * Add cross-references and navigation between documents
  * Include quick start guide and common use cases

This commit represents the complete v1.0.0 release of PlayHours, a production-ready server operation hours enforcement mod for Minecraft Forge 1.20.1.
This commit is contained in:
Mr¤KayJayDee
2025-10-23 23:28:20 +02:00
parent 58919ced40
commit c0fd2a2787
63 changed files with 6974 additions and 265 deletions

485
docs/TECHNICAL.md Normal file
View File

@@ -0,0 +1,485 @@
# Technical Details
This document covers the technical architecture, implementation details, and limitations of the PlayHours mod.
## 🏗️ Architecture Overview
### Core Components
PlayHours is built with a modular architecture consisting of several key components:
- **Core Logic** - Schedule calculation and enforcement
- **Event Handlers** - Server tick and login event processing
- **Configuration** - TOML-based configuration management
- **Commands** - Brigadier-based command system
- **Permissions** - LuckPerms integration with ops fallback
- **Text System** - Localization and message formatting
- **MOTD System** - Dynamic server list updates
### Class Structure
```
com.mrkayjaydee.playhours/
├── PlayHoursMod.java # Main mod class
├── command/ # Command system
│ ├── HoursCommand.java # Main command registration
│ ├── CommandBuilder.java # Command utilities
│ └── [Command Builders] # Specialized command builders
├── config/ # Configuration system
│ ├── ServerConfig.java # Main config class
│ ├── GeneralConfig.java # General settings
│ ├── DaysConfig.java # Day-specific schedules
│ ├── ExceptionsConfig.java # Date exceptions
│ ├── ListsConfig.java # Whitelist/blacklist
│ ├── MessagesConfig.java # Message customization
│ └── MOTDConfig.java # MOTD settings
├── core/ # Core logic
│ ├── ScheduleService.java # Main schedule service
│ ├── ScheduleCalculator.java # Schedule calculations
│ ├── ExceptionHandler.java # Exception handling
│ ├── PlayerAccessChecker.java # Access control
│ ├── TimeRange.java # Time range representation
│ └── ForceMode.java # Force mode enum
├── events/ # Event handlers
│ ├── LoginGuard.java # Login event handling
│ ├── TickScheduler.java # Server tick processing
│ ├── MOTDHandler.java # MOTD updates
│ └── [Event Handlers] # Other event handlers
├── permissions/ # Permission system
│ ├── PermissionChecker.java # Main permission checker
│ ├── LuckPermsIntegration.java # LuckPerms integration
│ └── PermissionConstants.java # Permission constants
└── text/ # Text system
├── Messages.java # Message management
├── LocaleLoader.java # Locale loading
└── [Text Handlers] # Text processing
```
## ⚙️ Core Logic
### Schedule Service
The `ScheduleService` class is the central coordinator for all schedule-related operations:
```java
public final class ScheduleService {
private final PlayerAccessChecker accessChecker;
private final ScheduleCalculator scheduleCalculator;
private final ExceptionHandler exceptionHandler;
// Main schedule check
public boolean isOpen(ZonedDateTime now) {
// 1. Check force mode
// 2. Check exceptions
// 3. Check daily schedule
}
// Player-specific access check
public boolean isOpenForName(String name, boolean isExempt) {
// 1. Check player access (lists, force mode)
// 2. Check schedule if not exempt
}
}
```
### Schedule Calculation
The `ScheduleCalculator` handles time-based schedule calculations:
```java
public final class ScheduleCalculator {
// Check if schedule is open at specific time
public boolean isScheduleOpen(ZonedDateTime now) {
// 1. Get current day of week
// 2. Get periods for that day
// 3. Check if current time falls within any period
// 4. Handle midnight-spanning periods
}
// Calculate next open/close times
public Optional<ZonedDateTime> nextClose(ZonedDateTime now) {
// Search through upcoming periods
// Handle midnight-spanning periods
// Return next closing time
}
}
```
### Time Range Handling
The `TimeRange` class represents time periods with support for midnight spanning:
```java
public final class TimeRange {
private final LocalTime start;
private final LocalTime end;
private final boolean spansMidnight;
// Check if time falls within range
public boolean contains(LocalTime time) {
if (spansMidnight) {
return time.isAfter(start) || time.isBefore(end);
} else {
return time.isAfter(start) && time.isBefore(end);
}
}
}
```
## 🔄 Event System
### Login Guard
The `LoginGuard` class handles player login events:
```java
@Mod.EventBusSubscriber
public class LoginGuard {
@SubscribeEvent
public static void onLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
// 1. Check if player is allowed by schedule/lists
// 2. Check if within closing threshold
// 3. Disconnect player if denied
}
}
```
### Tick Scheduler
The `TickScheduler` class handles server tick events for warnings and kicks:
```java
@Mod.EventBusSubscriber
public class TickScheduler {
@SubscribeEvent
public static void onServerTick(TickEvent.ServerTickEvent event) {
// 1. Check if server is open
// 2. Broadcast warnings if closing soon
// 3. Handle countdown messages
// 4. Kick players at closing time
}
}
```
### MOTD Handler
The `MOTDHandler` class manages dynamic MOTD updates:
```java
@Mod.EventBusSubscriber
public class MOTDHandler {
@SubscribeEvent
public static void onServerTick(TickEvent.ServerTickEvent event) {
// 1. Check if MOTD is enabled
// 2. Update MOTD periodically
// 3. Build MOTD content
// 4. Apply to server
}
}
```
## 🔧 Configuration System
### Forge Config Integration
PlayHours uses Forge's configuration system with TOML format:
```java
public final class ServerConfig {
public static final ForgeConfigSpec SPEC;
static {
ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder();
// Initialize all config sections
GeneralConfig.init(BUILDER);
DefaultsConfig.init(BUILDER);
DaysConfig.init(BUILDER);
ExceptionsConfig.init(BUILDER);
ListsConfig.init(BUILDER);
MessagesConfig.init(BUILDER);
MOTDConfig.init(BUILDER);
SPEC = BUILDER.build();
}
}
```
### Configuration Reload
The `ConfigEventHandler` handles configuration changes:
```java
@Mod.EventBusSubscriber
public class ConfigEventHandler {
@SubscribeEvent
public static void onConfigLoad(ModConfigEvent event) {
// 1. Validate configuration
// 2. Update schedule service
// 3. Reload messages
// 4. Update MOTD settings
}
}
```
## 🔑 Permission System
### Permission Checker
The `PermissionChecker` class handles permission validation:
```java
public final class PermissionChecker {
public static boolean hasAdmin(ServerPlayer player) {
return hasPermission(player, PermissionConstants.ADMIN, PermissionConstants.ADMIN_FALLBACK_LEVEL);
}
private static boolean hasPermission(ServerPlayer player, String permission, int fallbackLevel) {
// 1. Try LuckPerms if available
// 2. Fall back to vanilla ops
// 3. Handle timeouts gracefully
}
}
```
### LuckPerms Integration
The `LuckPermsIntegration` class handles LuckPerms-specific operations:
```java
public final class LuckPermsIntegration {
private static LuckPerms luckPerms;
static {
try {
luckPerms = LuckPermsProvider.get();
} catch (Throwable ignored) {
luckPerms = null;
}
}
public static boolean hasPermission(ServerPlayer player, String permission) {
if (!isAvailable()) return false;
var user = luckPerms.getUserManager().getUser(player.getUUID());
if (user == null) return false;
var data = user.getCachedData().getPermissionData();
return data.checkPermission(permission).asBoolean();
}
}
```
## 💬 Text System
### Message Management
The `Messages` class handles localized message loading and formatting:
```java
public final class Messages {
private static volatile String currentLocale = "en_us";
private static volatile Map<String, String> bundle = new HashMap<>();
private static volatile Map<String, String> overrides = new HashMap<>();
public static Component accessDenied(String openDay, String openTime) {
// 1. Get message template
// 2. Replace placeholders
// 3. Return formatted message
}
}
```
### Locale Loading
The `LocaleLoader` class handles language file loading:
```java
public final class LocaleLoader {
public static Map<String, String> loadLocale(String locale) {
// 1. Load language file from resources
// 2. Parse JSON content
// 3. Return message mappings
}
}
```
## 📢 MOTD System
### MOTD Builder
The `MOTDBuilder` class constructs MOTD content:
```java
public final class MOTDBuilder {
public static Component build(ScheduleService scheduleService, ZonedDateTime now) {
// 1. Check current status
// 2. Build status line
// 3. Add next open/close times
// 4. Add countdown if applicable
// 5. Apply colors and formatting
}
}
```
### MOTD Validator
The `MOTDValidator` class ensures MOTD content fits Minecraft limits:
```java
public final class MOTDValidator {
public static Component validateAndTruncate(Component motd) {
// 1. Check line count (max 2 lines)
// 2. Check character count (max 59 per line)
// 3. Truncate if necessary
// 4. Return validated MOTD
}
}
```
## 🚨 Known Limitations
### Early Login Denial
**Issue:** Forge 1.20.1 lacks a true pre-join network event.
**Impact:** Players briefly "join" before being disconnected.
**Workaround:** Uses `PlayerLoggedInEvent` with immediate disconnection.
**Future:** Could be improved with newer Forge versions.
### Deprecation Warning
**Issue:** `FMLJavaModLoadingContext.get()` is deprecated.
**Impact:** Warning in server logs.
**Reason:** Required for 1.20.1 compatibility.
**Future:** Will be updated for newer Forge versions.
### MOTD Caching
**Issue:** Some server list clients may cache MOTD content.
**Impact:** MOTD updates may not be immediately visible.
**Workaround:** MOTD updates every 60 seconds by default.
**Future:** Could be improved with more frequent updates.
## 🔧 Performance Considerations
### Schedule Caching
- **Cached calculations** - Schedule data is cached for performance
- **Efficient lookups** - Time-based lookups are optimized
- **Minimal memory usage** - Only essential data is cached
### Event Processing
- **Tick optimization** - Events are processed efficiently
- **Minimal overhead** - Only necessary checks are performed
- **Resource management** - Proper cleanup of resources
### Permission Checking
- **Cached results** - Permission results are cached
- **Timeout protection** - Prevents blocking on permission checks
- **Fallback handling** - Graceful degradation on errors
## 🛠️ Building from Source
### Requirements
- **Java:** 17 or 23
- **Gradle:** 8.8+ (included via wrapper)
- **Forge:** 47.4.10+
### Build Process
```bash
# Clone repository
git clone <repository-url>
cd PlayHours
# Build the mod
./gradlew build
# Output: build/libs/playhours-1.0.0.jar
```
### Development Setup
```bash
# Setup development environment
./gradlew genEclipseRuns # For Eclipse
./gradlew genIntellijRuns # For IntelliJ IDEA
# Run development server
./gradlew runServer
```
### Build Configuration
The `build.gradle` file contains the build configuration:
```gradle
plugins {
id 'net.minecraftforge.gradle' version '5.1.+'
id 'org.parchmentmc.librarian.forgegradle' version '1.+'
}
minecraft {
version = '1.20.1'
mappings channel: 'official', version: '1.20.1'
runs {
server {
workingDirectory project.file('run')
property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug'
}
}
}
```
## 🔍 Debugging
### Log Levels
PlayHours uses different log levels for different types of information:
- **INFO** - General information and status
- **WARN** - Warnings and fallback behavior
- **ERROR** - Errors and exceptions
- **DEBUG** - Detailed debugging information
### Debug Configuration
Enable debug logging by setting the log level:
```properties
# In server.properties or log4j2.xml
logger.playhours.level=DEBUG
```
### Common Debug Messages
```
[INFO] PlayHours loading... (modId=playhours)
[INFO] PlayHours common setup initialized
[WARN] PlayHours: LuckPerms not found, using ops fallback
[DEBUG] PlayHours: Config not ready yet
[ERROR] PlayHours: Permission check timeout for user PlayerName
```
## 📚 Related Documentation
- **[Features Overview](FEATURES.md)** - How features work
- **[Configuration Guide](CONFIGURATION.md)** - Configuration details
- **[Commands Reference](COMMANDS.md)** - Command implementation
- **[Usage Examples](EXAMPLES.md)** - Real-world usage
---
*For feature-specific details, see the [Features Overview](FEATURES.md).*