Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 20 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,24 @@ Permission: **`visor.admin`** (default: ops)
## Configuration
`plugins/VisorPlugin/server_settings.yml`:

| Key | Default | Description |
|-----|---------|-------------------------------------------------------------------------|
| `serverDebug` | `false` | Verbose logging of Visor |
| `vrOnly` | `false` | Kick non-VR players (ops exempt) |
| `twoHandedVR` | `false` | Enable the off-hand slot for two-handed VR |
| `betterSwinging` | `true` | VR-accurate melee attacks and block breaking |
| `swingingRepairDelay` | `400` | Ticks before an unfinished VR block break "heals" |
| `roomCrawlingSupported` | `true` | Allow room-scale crawling (forced crawl/swim pose) |
| `roomClimbingSupported` | `true` | Allow room-scale climbing (resets fall distance) |
| `pvpVRvsVanilla` | `true` | Allow PvP between a VR player and a non-VR player |
| `pvpVRvsVR` | `true` | Allow PvP between two VR players |
| `notifyPvpBlocked` | `false` | Message the attacker when PvP is blocked |
| `creeperSwellDistance` | `1.75` | Creepers swell within this distance of a VR player's head. (`0` disables) |
| `supportedMovement` | `BOTH` | `CONTROLLER`, `TELEPORT`, or `BOTH` |
| `teleportUpLimit` | `1` | Teleport-move vertical-up limit (blocks) |
| `teleportDownLimit` | `4` | Teleport-move vertical-down limit (blocks) |
| `teleportForwardLimit` | `16` | Teleport-move forward limit (blocks) |
| Key | Default | Description |
|-------------------------|--------------|-------------------------------------------------------------------------|
| `serverDebug` | `false` | Verbose logging of Visor |
| `vrOnly` | `false` | Kick non-VR players (ops exempt) |
| `twoHandedVR` | `false` | Enable the off-hand slot for two-handed VR |
| `betterSwinging` | `false` | VR-accurate melee attacks and block breaking |
| `swingingRepairDelay` | `400` | Ticks before an unfinished VR block break "heals" |
| `roomCrawlingSupported` | `false` | Allow room-scale crawling (forced crawl/swim pose) |
| `roomClimbingSupported` | `false` | Allow room-scale climbing (resets fall distance) |
| `pvpVRvsVanilla` | `true` | Allow PvP between a VR player and a non-VR player |
| `pvpVRvsVR` | `true` | Allow PvP between two VR players |
| `notifyPvpBlocked` | `false` | Message the attacker when PvP is blocked |
| `creeperSwellDistance` | `1.75` | Creepers swell within this distance of a VR player's head. (`0` disables) |
| `supportedMovement` | `CONTROLLER` | `CONTROLLER`, `TELEPORT`, or `BOTH` |
| `teleportUpLimit` | `1` | Teleport-move vertical-up limit (blocks) |
| `teleportDownLimit` | `4` | Teleport-move vertical-down limit (blocks) |
| `teleportForwardLimit` | `16` | Teleport-move forward limit (blocks) |
| `trackersSupported` | `false` | Allow to use trackers |

```bash
./gradlew build
Expand All @@ -66,8 +67,8 @@ Permission: **`visor.admin`** (default: ops)

### Adding support for another Minecraft version
1. Create an `nms-vXXX` module applying `paperweight-userdev` with that version's dev bundle
2. Implement `VersionAdapter` (copy an existing leaf; fix any API differences)
3. Register the class in `VersionAdapterRegistry.NMS_LEAVES` and add `runtimeOnly project(path: ':nms-vXXX', configuration: 'reobf')` to the root build
2. Implement `VisorVersionAdapter` (copy an existing leaf; fix any API differences)
3. Register the class in `VersionAdapterRegistry.NMS_LEAVES` and add `runtimeOnly project(path: ':versions:nms-vXXX', configuration: 'reobf')` to the root build

## Notes
- **ViaVersion** is supported for cross-version play: `visor:channel` carries a version-independent byte
Expand Down
27 changes: 16 additions & 11 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,22 @@ dependencies {
compileOnly 'io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT'
implementation 'org.yaml:snakeyaml:2.3'

runtimeOnly project(path: ':nms-v1_20_R1', configuration: 'reobf')
runtimeOnly project(path: ':nms-v1_21_1', configuration: 'reobf')
runtimeOnly project(path: ':nms-v1_21_3', configuration: 'reobf')
runtimeOnly project(path: ':nms-v1_21_4', configuration: 'reobf')
runtimeOnly project(path: ':nms-v1_21_5', configuration: 'reobf')
runtimeOnly project(path: ':nms-v1_21_6', configuration: 'reobf')
runtimeOnly project(path: ':nms-v1_21_7', configuration: 'reobf')
runtimeOnly project(path: ':nms-v1_21_8', configuration: 'reobf')
runtimeOnly project(path: ':nms-v1_21_9', configuration: 'reobf')
runtimeOnly project(path: ':nms-v1_21_10', configuration: 'reobf')
runtimeOnly project(path: ':nms-v1_21_11', configuration: 'reobf')
compileOnly 'org.projectlombok:lombok:1.18.38'
annotationProcessor 'org.projectlombok:lombok:1.18.38'
testCompileOnly 'org.projectlombok:lombok:1.18.38'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.38'

runtimeOnly project(path: ':versions:nms-v1_20_R1', configuration: 'reobf')
runtimeOnly project(path: ':versions:nms-v1_21_1', configuration: 'reobf')
runtimeOnly project(path: ':versions:nms-v1_21_3', configuration: 'reobf')
runtimeOnly project(path: ':versions:nms-v1_21_4', configuration: 'reobf')
runtimeOnly project(path: ':versions:nms-v1_21_5', configuration: 'reobf')
runtimeOnly project(path: ':versions:nms-v1_21_6', configuration: 'reobf')
runtimeOnly project(path: ':versions:nms-v1_21_7', configuration: 'reobf')
runtimeOnly project(path: ':versions:nms-v1_21_8', configuration: 'reobf')
runtimeOnly project(path: ':versions:nms-v1_21_9', configuration: 'reobf')
runtimeOnly project(path: ':versions:nms-v1_21_10', configuration: 'reobf')
runtimeOnly project(path: ':versions:nms-v1_21_11', configuration: 'reobf')

testImplementation platform('org.junit:junit-bom:5.11.3')
testImplementation 'org.junit.jupiter:junit-jupiter'
Expand Down
26 changes: 15 additions & 11 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@ dependencyResolutionManagement {
}
}

include 'nms-v1_20_R1'
include 'nms-v1_21_1'
include 'nms-v1_21_3'
include 'nms-v1_21_4'
include 'nms-v1_21_5'
include 'nms-v1_21_6'
include 'nms-v1_21_7'
include 'nms-v1_21_8'
include 'nms-v1_21_9'
include 'nms-v1_21_10'
include 'nms-v1_21_11'
[
'nms-v1_20_R1',
'nms-v1_21_1',
'nms-v1_21_3',
'nms-v1_21_4',
'nms-v1_21_5',
'nms-v1_21_6',
'nms-v1_21_7',
'nms-v1_21_8',
'nms-v1_21_9',
'nms-v1_21_10',
'nms-v1_21_11'
].each { name ->
include "versions:$name"
}
143 changes: 143 additions & 0 deletions src/main/java/org/vmstudio/visor/api/VisorAPI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package org.vmstudio.visor.api;

import java.util.Collection;
import java.util.UUID;

import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.vmstudio.visor.api.network.VisorChannel;
import org.vmstudio.visor.api.network.VisorChannelHandler;
import org.vmstudio.visor.api.player.VRPlayer;
import org.vmstudio.visor.api.player.VisorPlayer;
import org.vmstudio.visor.api.nms.McVersion;
import org.vmstudio.visor.protocol.VisorProtocol;

/**
* Central access point for all Visor Plugin API functionality
*/
public interface VisorAPI {
/**
* Get Visor API
*
* @return Visor API
*/
static VisorAPI get(){
if(Instance.api == null){
throw new IllegalStateException("VisorAPI is not available. Add [VisorPlugin] to depends in plugin.yml");
}
return Instance.api;
}

/**
* Visor core network/protocol version
*
* @return Network version from {@link VisorProtocol}
*/
static int networkVersion(){
return VisorProtocol.CORE_NETWORK_VERSION;
}

/**
* Minecraft version this server runs
*
* @return Minecraft version
*/
McVersion minecraftVersion();

/**
* If there is a VR player with specified uuid
*
* @return true/false
*/
boolean isVRPlayer(UUID uuid);

/**
* If specified player has VR
*
* @return true/false
*/
boolean isVRPlayer(Player player);

/**
* Get Visor player with specified uuid.
*
* @return Visor player or null if not found
*/
@Nullable
VisorPlayer getVisorPlayer(UUID uuid);

/**
* Get Visor player from MC player.
*
* @return Visor player or null if not found
*/
@Nullable
VisorPlayer getVisorPlayer(Player player);

/**
* Get all Visor players on server.
* @return Visor players
*/
Collection<VisorPlayer> getVisorPlayers();

/**
* Get player in VR with specified uuid.
*
* @return VR player or null if not found
*/
@Nullable
VRPlayer getVRPlayer(UUID uuid);

/**
* Get player in VR from MC player.
*
* @return VR player or null if not found
*/
@Nullable
VRPlayer getVRPlayer(Player player);

/**
* Get Visor player from MC player.
*
* @return Visor player or null if not found
*/
Collection<VRPlayer> getVRPlayers();

/**
* Register a custom channel for payloads with the matching Visor addon.
* Use this overload when you only send and receive typed
* packets via {@link VisorChannel#on} and {@link VisorChannel#send}
*
* @param owner the plugin that registering channel
* @param channel channel name in {@code namespace:path} form (like {@code "myaddon:hello"})
* @return registered channel
*/
VisorChannel registerChannel(Plugin owner, String channel);

/**
* Register a custom channel with a raw handler.
* This is like {@link #registerChannel(Plugin, String)} but any inbound
* message whose first byte does not match a typed packet registered with
* {@link VisorChannel#on} is sending to {@code handler} with raw bytes
*
* @param owner the plugin that registering channel
* @param channel channel name in {@code namespace:path} form (like {@code "myaddon:hello"})
* @param handler fallback for payloads the typed packet layer does not handle
* @return registered channel
*/
VisorChannel registerChannel(Plugin owner, String channel, VisorChannelHandler handler);

@ApiStatus.Internal
final class Instance {
private static VisorAPI api;

private Instance(){}

@ApiStatus.Internal
public static void set(VisorAPI api){
Instance.api = api;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.vmstudio.visor.api.event;

import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.vmstudio.visor.api.player.VisorPlayer;

/**
* Fired when a player with the Visor mod joins (after the handshake), VR or not - see {@link #isVRPlayer()}
*/
public final class VisorPlayerJoinedEvent extends Event {
private static final HandlerList handlers = new HandlerList();

private final VisorPlayer visorPlayer;

public VisorPlayerJoinedEvent(VisorPlayer visorPlayer){
this.visorPlayer = visorPlayer;
}

public VisorPlayer getVisorPlayer(){
return visorPlayer;
}

public boolean isVRPlayer(){
return this.visorPlayer.isVR();
}

@Override
public @NotNull HandlerList getHandlers(){
return handlers;
}

public static HandlerList getHandlerList(){
return handlers;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.vmstudio.visor.api.event;

import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.vmstudio.visor.api.player.VisorPlayer;

/**
* Fired when a player with the Visor mod disconnects, VR or not - see {@link #isVRPlayer()}
*/
public final class VisorPlayerLeftEvent extends Event {
private static final HandlerList handlers = new HandlerList();

private final VisorPlayer visorPlayer;

public VisorPlayerLeftEvent(VisorPlayer vrPlayer){
this.visorPlayer = vrPlayer;
}

public VisorPlayer getVisorPlayer(){
return visorPlayer;
}

public boolean isVRPlayer(){
return this.visorPlayer.isVR();
}

@Override
public @NotNull HandlerList getHandlers(){
return handlers;
}

public static HandlerList getHandlerList(){
return handlers;
}
}
Loading
Loading