From da8563af76c9b83d14005dbb1cb753ad0ae290b1 Mon Sep 17 00:00:00 2001 From: youngcoder45 Date: Tue, 10 Mar 2026 16:52:56 +0530 Subject: optional cords and broadcast are separate now --- adi_change.md | 239 +++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 171 insertions(+), 68 deletions(-) (limited to 'adi_change.md') diff --git a/adi_change.md b/adi_change.md index 752768d..5338113 100644 --- a/adi_change.md +++ b/adi_change.md @@ -1,7 +1,11 @@ # Changes Made to SVC Intercom Plugin ## Overview -Implemented a speaker system with positional audio for broadcasts. Players now only hear broadcasts when they're near defined speaker locations, creating a more realistic experience. +Implemented a comprehensive speaker system with **dual broadcast modes** for the intercom plugin: +- **Global broadcasts**: Everyone in the world hears equally (original behavior) +- **Speaker broadcasts**: Positional audio from defined speaker locations with limited range + +This allows admins to choose between world-wide announcements or realistic, location-based PA systems. --- @@ -12,10 +16,11 @@ Implemented a speaker system with positional audio for broadcasts. Players now o **Features:** - Stores speaker location (world, x, y, z coordinates) -- Configurable broadcast range +- Configurable broadcast range (1-1000 blocks) - Named speakers for easy management - Distance calculation to check if players are in range - Helper method to get Bukkit Location object +- Thread-safe design --- @@ -23,78 +28,125 @@ Implemented a speaker system with positional audio for broadcasts. Players now o **Purpose:** Singleton manager for speaker storage and persistence **Features:** -- Manages all speakers across all worlds +- Manages all speakers across all worlds using ConcurrentHashMap - JSON-based persistence (saves to `plugins/SVCIntercom/speakers.json`) - Add/remove/list speakers by world - Find speakers within range of a location -- Thread-safe using ConcurrentHashMap +- Thread-safe operations - Automatic save on modifications -- Automatic load on initialization +- Automatic load on plugin initialization +- Uses Gson for serialization --- ### 3. `src/main/java/eu/projnull/spelis/svci/commands/handlers/SpeakerCommand.java` -**Purpose:** Command handler for managing speakers +**Purpose:** Command handler for managing speakers with flexible coordinate options **Commands Implemented:** -- `/intercom speaker add ` - Add speaker at player's current location -- `/intercom speaker add ` - Add speaker at specific coordinates +- `/intercom speaker add ` - Add speaker at player's current location (simplest) +- `/intercom speaker add ` - Add speaker using player's X/Y/Z in different world +- `/intercom speaker add ` - Add speaker at specific coordinates (full control) - `/intercom speaker remove ` - Remove a speaker - `/intercom speaker list [world]` - List all speakers (defaults to player's world) **Features:** +- **Coordinates are truly optional** - 3 different ways to add speakers - Tab completion for world names and speaker names - Permission checks (`svcintercom.speaker.add`, `svcintercom.speaker.remove`, `svcintercom.speaker.list`) - Validation for duplicate names and world existence - Range validation (1.0 to 1000.0 blocks) +- Clear error messages and feedback --- ### 4. `gradlew` **Purpose:** Gradle wrapper script for building the project - Standard Gradle wrapper shell script for Unix-based systems -- Made executable for building the project +- Made executable for building the project without system Gradle --- ## Modified Files -### 1. `src/main/java/eu/projnull/spelis/svci/voice/VoicePlugin.java` -**Changes Made:** -- Modified `onMicPacket()` method to use positional audio from speakers -- **Old behavior:** Sent static audio packets to all players in world (everyone hears equally) -- **New behavior:** - - Checks for speakers in the world - - If speakers exist, only players near speakers hear the broadcast - - Audio appears to come from the nearest speaker location using locational sound packets - - Falls back to old behavior if no speakers are defined -- For each listener, finds the nearest speaker within range -- Uses `sendLocationalSoundPacketTo()` with speaker position instead of `sendStaticSoundPacketTo()` +### 1. `src/main/java/eu/projnull/spelis/svci/voice/BroadcasterState.java` +**Major Changes:** +- Added `BroadcastMode` enum with two values: + - `GLOBAL` - Everyone hears equally, speakers ignored + - `SPEAKER` - Only audible near speakers with positional audio +- Updated `Broadcaster` constructor to require a `mode` parameter +- Added `getMode()` getter method +- Mode is now stored alongside broadcast type and validated on creation + +**Why:** Separates global broadcasts from speaker-based broadcasts, giving admins full control --- -### 2. `src/main/java/eu/projnull/spelis/svci/commands/handlers/FileCommand.java` -**Changes Made:** -- Modified audio playback to use speakers for positional audio -- **Old behavior:** Created static audio channels for each player (everyone hears equally) -- **New behavior:** +### 2. `src/main/java/eu/projnull/spelis/svci/commands/handlers/LiveCommand.java` +**Major Rewrite:** +- Added optional `mode` parameter: `/intercom live [mode]` +- Mode can be `global` or `speaker` +- **Auto-detection**: If mode not specified, uses speaker mode if speakers exist, otherwise global +- Refactored to use helper method `executeLiveBroadcast()` for cleaner code +- Added import for `SpeakerManager` for mode detection +- Warning if speaker mode selected but no speakers exist +- Shows mode in success message: `(global)` or `(speaker)` + +**Usage Examples:** +- `/intercom live Player world 60` - Auto-detect +- `/intercom live Player world 60 global` - Force global +- `/intercom live Player world 60 speaker` - Force speaker mode + +--- + +### 3. `src/main/java/eu/projnull/spelis/svci/commands/handlers/FileCommand.java` +**Major Rewrite:** +- Added optional `mode` parameter: `/intercom file [mode]` +- Mode can be `global` or `speaker` +- **Auto-detection**: If mode not specified, uses speaker mode if speakers exist, otherwise global +- Refactored to use helper method `executeFileBroadcast()` for cleaner code +- **Global mode**: Creates static audio channels for each player (everyone hears equally) +- **Speaker mode**: Creates locational audio channels at each speaker position +- Warning if speaker mode selected but no speakers exist +- Shows mode and speaker count in success message + +**Behavior:** +- Global: Uses `createStaticAudioChannel()` - no positional audio +- Speaker: Uses `createLocationalAudioChannel()` with `setDistance()` for each speaker + +--- + +### 4. `src/main/java/eu/projnull/spelis/svci/voice/VoicePlugin.java` +**Major Changes:** +- Modified `onMicPacket()` to respect broadcast mode +- **Global mode path**: Uses static sound packets, everyone hears equally (ignores speakers) +- **Speaker mode path**: - Checks for speakers in the world - - If speakers exist, creates locational audio channels at each speaker position - - Sets channel distance to speaker's range - - Falls back to old behavior if no speakers are defined - - Updated success message to show speaker count -- Uses `createLocationalAudioChannel()` at speaker positions instead of `createStaticAudioChannel()` + - Finds nearest speaker to each listener + - Sends locational sound packets from speaker position + - Players only hear if within range of a speaker +- Removed auto-fallback - now strictly follows the configured mode +- Better separation of concerns between modes + +**Key Logic:** +```java +if (mode == GLOBAL) { + // Send static packets to all players +} else { + // Find nearest speaker per listener + // Send locational packets from speaker position +} +``` --- -### 3. `src/main/java/eu/projnull/spelis/svci/commands/IntercomCommand.java` +### 5. `src/main/java/eu/projnull/spelis/svci/commands/IntercomCommand.java` **Changes Made:** - Added `SpeakerCommand` to the list of registered handlers - New line: `registerHandler(new SpeakerCommand());` --- -### 4. `src/main/java/eu/projnull/spelis/svci/Intercom.java` +### 6. `src/main/java/eu/projnull/spelis/svci/Intercom.java` **Changes Made:** - Added import for `SpeakerManager` - Modified `onEnable()` method to initialize the speaker system @@ -103,54 +155,94 @@ Implemented a speaker system with positional audio for broadcasts. Players now o --- -### 5. `build.gradle.kts` +### 7. `build.gradle.kts` **Changes Made:** -- Added Gson dependency for JSON serialization -- New line in dependencies: `implementation("com.google.code.gson:gson:2.10.1")` -- Required for saving/loading speaker configuration +- Added Gson dependency for JSON serialization: `implementation("com.google.code.gson:gson:2.10.1")` +- Required for saving/loading speaker configuration to disk --- -### 6. `README.md` -**Changes Made:** -- Expanded documentation with new features section -- Added speaker system explanation -- Documented all new speaker commands -- Added "How It Works" section explaining positional audio behavior -- Explained fallback to global audio when no speakers are defined +### 8. `README.md` +**Major Update:** +- Completely rewritten with comprehensive documentation +- Added "Broadcast Modes Explained" section with detailed behavior +- Expanded command documentation with examples +- Added auto-detection explanation +- Added permissions list +- Added setup example with real-world scenarios +- Clarified all three ways to add speakers --- -## Technical Details +## Key Improvements from Previous Version + +### 1. **Separated Global and Speaker Broadcasts** +- **Before**: Speakers would override behavior for entire world (all-or-nothing) +- **After**: Choose mode per broadcast - use global for world announcements, speaker for localized PA + +### 2. **Truly Optional Coordinates** +- **Before**: Two options - full coords or player location +- **After**: Three flexible options: + 1. Just name + range (uses player's location) + 2. Name + range + world (uses player's XYZ in different world) + 3. Full specification with all coordinates -### How Positional Audio Works +### 3. **Better Command Structure** +- Optional mode parameters with auto-detection +- Tab completion for modes +- Clearer command syntax +- More helpful error messages -1. **Live Broadcasts:** - - When a broadcaster speaks, the plugin intercepts their microphone packets - - For each online player in the world, it finds the nearest speaker within range - - If a speaker is found, audio is sent as a locational sound packet from the speaker's position - - If no speaker is within range, that player hears nothing +### 4. **Improved Logic** +- No more auto-fallback confusion +- Explicit mode selection +- Warning system for invalid configurations +- Cleaner code with helper methods -2. **File Playback:** - - Audio is decoded and prepared for playback - - For each speaker in the world, a locational audio channel is created at the speaker's position - - Each channel has a distance parameter set to the speaker's range - - All speakers play the audio simultaneously +--- + +## Technical Details -3. **Fallback Behavior:** - - If no speakers are defined in a world, the plugin uses the original global broadcast - - This ensures backward compatibility with existing setups +### Broadcast Mode Logic + +#### Global Mode: +1. Broadcast is created with `BroadcastMode.GLOBAL` +2. VoicePlugin/FileCommand checks the mode +3. For live: Sends static sound packets to all players +4. For file: Creates static audio channels for each player +5. **Speakers are completely ignored** - audio is non-positional + +#### Speaker Mode: +1. Broadcast is created with `BroadcastMode.SPEAKER` +2. VoicePlugin/FileCommand checks the mode +3. Retrieves speakers from SpeakerManager +4. If no speakers exist, no audio is heard (with warning) +5. For live: Finds nearest speaker per listener, sends locational packets +6. For file: Creates locational audio channels at each speaker position +7. **Only players near speakers hear the audio** + +#### Auto-Detection: +```java +boolean hasSpeakers = !SpeakerManager.inst().getSpeakers(worldId).isEmpty(); +mode = hasSpeakers ? SPEAKER : GLOBAL; +``` ### Data Persistence -- Speakers are saved to `plugins/SVCIntercom/speakers.json` +- Speakers saved to `plugins/SVCIntercom/speakers.json` - Format: Array of speaker objects with worldId, coordinates, range, and name +- Uses Gson for clean JSON serialization - Automatically loaded on plugin enable - Automatically saved after any speaker modification +- Thread-safe operations with ConcurrentHashMap ### Permission Nodes -New permissions added: +**Existing:** +- `svcintercom.broadcast` - Base permission +- `svcintercom.broadcast.start` - Start broadcasts + +**New:** - `svcintercom.speaker` - Base permission for speaker commands - `svcintercom.speaker.add` - Permission to add speakers - `svcintercom.speaker.remove` - Permission to remove speakers @@ -163,16 +255,27 @@ New permissions added: **Files Created:** 4 - Speaker.java (data model) - SpeakerManager.java (persistence & management) -- SpeakerCommand.java (command handlers) +- SpeakerCommand.java (command handlers with 3 flexible add options) - gradlew (build script) -**Files Modified:** 6 -- VoicePlugin.java (positional audio for live broadcasts) -- FileCommand.java (positional audio for file playback) +**Files Modified:** 8 +- BroadcasterState.java (added BroadcastMode enum) +- LiveCommand.java (added mode selection with auto-detect) +- FileCommand.java (added mode selection with auto-detect) +- VoicePlugin.java (respects broadcast mode, no fallback) - IntercomCommand.java (register speaker commands) - Intercom.java (initialize speaker system) - build.gradle.kts (add Gson dependency) -- README.md (documentation) - -**Total Lines Added:** ~600+ -**Key Feature:** Coordinate-based virtual speakers with positional audio and limited range +- README.md (comprehensive documentation rewrite) + +**Total Lines Added:** ~900+ + +**Key Features:** +1. ✅ Dual broadcast modes (Global vs Speaker) +2. ✅ Truly optional coordinates (3 ways to add speakers) +3. ✅ Auto-detection with explicit mode override +4. ✅ Better separation of concerns +5. ✅ Comprehensive documentation +6. ✅ Warning system for invalid configurations +7. ✅ Persistent speaker storage +8. ✅ Thread-safe operations -- cgit v1.3-7-ge9ab