hammy275 / mc-vr-api Goto Github PK
View Code? Open in Web Editor NEWAn API to allow mod developers to see VR player data from Vivecraft.
License: GNU Lesser General Public License v3.0
An API to allow mod developers to see VR player data from Vivecraft.
License: GNU Lesser General Public License v3.0
public class PlayerInitHandler {
@SubscribeEvent
public void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) {
System.out.println("HANDLE PLAYER LOGIN EVENT");
LocalPlayer player = getMCI().player;
assert player != null;
System.out.println("PLAYER NOT NULL");
VrJesterApi.VIVECRAFTLOADED = PositionTracker.vrAPI.playerInVR(player);
System.out.println("CRASHES BEFORE THIS");
}
}
I register the above handler in the MinecraftForge.EVENT_BUS
and it causes the player to disconnect from joining their singleplayer world. I'm trying to assign a flag so I can check throughout my code whether the player is in VR or not. Please find attached gifs and snippet of logs for visual reference.
https://gyazo.com/c2abe794e0a5d21abee8faf94c5a8e22
https://gyazo.com/8674f8a3d827bb3505da4fcb159569d5
-Thanks
VRData functions should correspond to their respective function names in PlayerEntity
.
I'm fine breaking the API here, it's not like this is released yet
https://github.com/hammy275/mc-vr-api/blob/1.19.x/common/src/main/java/net/blf02/vrapi/client/ClientSubscriber.java#L20 ticks for every player the client sees, not just the client player that we care about, causing a crash when we try to get data of other players. Should do a filter here to only get ourselves.
See #14 (comment) for deprecation plans for MC VR API
NOTE: This is the ONLY other planned major version bump.
The Vivecraft developers plan to release an official API at some point. Once it releases, this API should be updated to match it as closely as possible. There isn't a need to have all the features from the official one, however all of the functions we implement should be named and sorted the same way as the official API.
Until the official API releases, this issue won't be closed
Ideally, we make a version 2.1.1 that fixes #23 while simultaneously including 1.19.3 support.
Technically speaking, the API does change, as the API call to IVRData#getRotationMatrix
will switch to JOML's Matrix4f
, but I'm breaking from SemVer on this because:
Matrix4f
is the only option as the Mojang-provided one is completely removed. If it was deprecated, this would be another story, but it's entirely gone to my knowledge.forge
/fabric
packages to be something like forge_vrapi
or fabric_api`forge
isInVR(PlayerEntity player)
This should allow for Fabric compatibility.
Note that at the same time, we'll have to remove the VRPlayerTickEvent
, since Fabric doesn't have an event system in the same way Forge does, and I'm not keen to force the Architectury API to be installed to use this API.
After the port (including full testing with Vivecraft's Fabric port), this will become release 2.0.0.
public boolean isLeftHanded(PlayerEntity player) {
if (player.world.isClient) {
VRDataGrabber.isSelf(player);
return VRDataGrabber.isLeftHanded();
} else {
return ((Tracker.ServerSideVRPlayerData)Tracker.playerToVR.get(player.getGameProfile().getName())).isLeftHanded();
}
}
in
if (player.world.isClient) {
VRDataGrabber.isSelf(player);
return VRDataGrabber.isLeftHanded();
}
it returns the function VRDataGrabber.isLeftHanded();
but if the player is not using VR it returns nothing:
public static boolean isLeftHanded() {
if (!ReflectionConstants.clientHasVivecraft()) {
throw new IllegalArgumentException("Cannot retrieve hand status of player outside VR!");
} else {
try {
Object VRSettingsInstance = Minecraft_VRSettings.get(vrHolder);
return (Boolean)VRSettings_reverseHands.get(VRSettingsInstance);
} catch (IllegalAccessException var1) {
throw new RuntimeException("Could not get handedness of local player!");
}
}
}
as you can see here
if (!ReflectionConstants.clientHasVivecraft()) {
throw new IllegalArgumentException("Cannot retrieve hand status of player outside VR!");
}
ReflectionConstants.clientHasVivecraft() is true only if the player is using VR
if it doesn't the API's funtion will return an error:
at java.base/java.lang.reflect.Field.checkAccess(Field.java:1141)
at java.base/java.lang.reflect.Field.get(Field.java:425)
at net.blf02.vrapi.client.VRDataGrabber.isLeftHanded(VRDataGrabber.java:210)
at net.blf02.vrapi.common.VRAPI.isLeftHanded(VRAPI.java:206)
now I'm not sure if this is just my code or for everyones' but for me, this is what happens, please fix this
the code where the error occurs:
Vec3d controllerVel = (VRPlugin.apiInstance.getRenderVRPlayer().getController(VRPlugin.apiInstance.isLeftHanded(player) ? 1 : 0).position().subtract(lastControllerPos)).multiply(100d);
fix:
if (player.world.isClient) {
VRDataGrabber.isSelf(player);
try{
return VRDataGrabber.isLeftHanded();
} catch (RuntimeException re){
return null;
}
} else {
return ((Tracker.ServerSideVRPlayerData)Tracker.playerToVR.get(player.getGameProfile().getName())).isLeftHanded();
}
ImmersiveMC Discord server has a support thread where the issue occurred. It's the "the server didn't have mc-vr-api installed" chat message being shown.
If the server has mc-vr-api
installed, the client doesn't necessarily need to have it. This way, non-VR users can join. Same vice-versa, so a client can join a server, and just not have VR API functions available.
This will require a new function, and thus will increment the version to 1.2.0
, along with some documentation changes. The function is simply titled doesOtherSideHaveVR()
.
TODO:
SimpleChannel
to not check protocol versions.HashSet
of String
s representing players. When the server receives the network protocol packet, it adds the username to the set if the versions are compatible. It then sends a packet back to the client, which sets a client-only serverHasAPI
boolean to true
once receiving it.HashSet
serverHasAPI
back to falsedoesOtherSideHaveVR()
, which returns the value from the HashMap
server-side, and the serverHasAPI
boolean client-side.VRPlayerTickEvent
to only run if doesOtherSideHaveVR()
is true.DISPLAYTEST
so Forge doesn't display a red X if the API is only installed client-side.serverHasAPI
is still false (ie. we didn't receive the packet back from the server saying that we have the API) mention in chat that the server doesn't have the API, and VR-specific functions may not be available as a result.NOTE: We aren't updating the other functions to require doesOtherSideHaveVR()
. Mod devs are expected to check this. Not doing a major version bump for this, since before this, the functionality between those with the API and without wasn't possible because of protections from Forge.
Let's make sure the dedicated server doesn't have a heart attack when we run this.
Didn't catch this sooner, but there are some fun clauses in the GPLv3.0 that make it not work with Minecraft. Will switch to LGPL.
I think that this will make it much easier to code with the API.
If a mod wants to integrate this API, they should be able to do so without making the mod mandatory for players. This way, mods can be enhanced with VR, and the API can be left out if no one is going to be in VR on a server.
When switching out of VR, MC VR API does not alert the server of this fact. This should be remedied!
https://mclo.gs/fFPRa9e
only mods running are
optifineless vivecraft ver 0.11, architectuary, vrapi 2.0, immersivemc
seems to be complaining about how you removed vrplayer tick event
It will make a good example mod!
Depends on hammy275/mc-vr-playground#6
On MC VR API 3.0.6 for 1.20.1
Odds are, this should work more than fine (especially in comparison to #3 ), since there isn't any Vivecraft code, and we bail pretty early.
Finally tracked down why this happens.
Because we don't depend on Vivecraft, Forge/NeoForge may decide to load MC VR API before Vivecraft. As a consequence, when running VRDataGrabber#init()
, we detect a lack of Vivecraft, and don't initialize properly, thus leading to the crash.
This should be similar to a Forge event, but won't actually be.
Whenever TickEvent.PlayerTickEvent
is called, it should get all of the plugin instances (probably from a variable they're stored into at startup), we should call a VRPlayerTick
function, that is passed in all of the parameters from TickEvent.PlayerTickEvent
.
The reason we do this over a regular Forge event is so it can be easily used without requiring the API, similarly to the rest of the API.
Clear playerToVR HashMap of a disconnected player when they disconnect.
The README is extremely out of date at the moment; it needs to be updated!
To make VR dev easier, I think it would be cool to have support for placing fake controller and HMD positions while in a dev environment.
The controllers and HMD would be represented in-world by particles, each one would be a separate key to place, and the keys and placement code would only work in a dev environment (in production, you'd ideally just be in VR anyways)
was trying to test immersive mc forgot to enable it and found out it was this. im running in nonvrmode for vivecraft, i also tested if it was vivecraft incompatible and found that it wasnt , this is the only other mod enabled.
See #18
Null pointer thrown on player death for vrapi-3.0.8-1.20.4-forge.
java.lang.NullPointerException: Cannot invoke "net.minecraft.world.entity.player.Player.m_9236_()" because "player" is null at net.blf02.vrapi.common.VRAPI.playerInVR(VRAPI.java:138) ~[vrapi-3.0.8-1.20.4-forge.jar!/:?] {re:classloading} at com.hammy275.immersivemc.common.vr.VRRumble.rumbleIfVR(VRRumble.java:20) ~[immersivemc-1.5.0-alpha2-1.20.4-forge.jar!/:?] {re:classloading} at com.hammy275.immersivemc.server.tracker.RangedGrabTrackerServer.tick(RangedGrabTrackerServer.java:46) ~[immersivemc-1.5.0-alpha2-1.20.4-forge.jar!/:?] {re:classloading} at com.hammy275.immersivemc.common.tracker.AbstractTracker.doTick(AbstractTracker.java:14) ~[immersivemc-1.5.0-alpha2-1.20.4-forge.jar!/:?] {re:classloading} at com.hammy275.immersivemc.server.ServerSubscriber.onServerTick(ServerSubscriber.java:23) ~[immersivemc-1.5.0-alpha2-1.20.4-forge.jar!/:?] {re:classloading} at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732) ~[?:?] {re:mixin,re:computing_frames} at dev.architectury.event.EventFactory.invokeMethod(EventFactory.java:53) ~[architectury-11.1.17-minecraftforge.jar!/:?] {re:classloading} at dev.architectury.event.EventFactory$1.handleInvocation(EventFactory.java:62) ~[architectury-11.1.17-minecraftforge.jar!/:?] {re:classloading} at com.google.common.reflect.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:87) ~[guava-32.1.2-jre.jar!/:?] {} at jdk.proxy3.$Proxy78.tick(Unknown Source) ~[?:?] {} at dev.architectury.event.forge.EventHandlerImplCommon.event(EventHandlerImplCommon.java:75) ~[architectury-11.1.17-minecraftforge.jar!/:?] {re:mixin,re:classloading} at dev.architectury.event.forge.__EventHandlerImplCommon_event_ServerTickEvent.invoke(.dynamic) ~[architectury-11.1.17-minecraftforge.jar!/:?] {re:classloading,pl:eventbus:B} at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:58) ~[eventbus-6.2.0.jar!/:?] {} at net.minecraftforge.eventbus.EventBus.post(EventBus.java:300) ~[eventbus-6.2.0.jar!/:?] {} at net.minecraftforge.eventbus.EventBus.post(EventBus.java:281) ~[eventbus-6.2.0.jar!/:?] {} at net.minecraftforge.event.ForgeEventFactory.post(ForgeEventFactory.java:170) ~[forge-1.20.4-49.0.48-universal.jar!/:?] {re:classloading} at net.minecraftforge.event.ForgeEventFactory.onPostServerTick(ForgeEventFactory.java:755) ~[forge-1.20.4-49.0.48-universal.jar!/:?] {re:classloading} at net.minecraft.server.MinecraftServer.m_5705_(MinecraftServer.java:864) ~[forge-1.20.4-49.0.48-client.jar!/:?] {re:mixin,pl:accesstransformer:B,re:classloading,pl:accesstransformer:B,pl:mixin:A} at net.minecraft.client.server.IntegratedServer.m_5705_(IntegratedServer.java:93) ~[forge-1.20.4-49.0.48-client.jar!/:?] {re:mixin,pl:runtimedistcleaner:A,re:classloading,pl:runtimedistcleaner:A} at net.minecraft.server.MinecraftServer.m_130011_(MinecraftServer.java:673) ~[forge-1.20.4-49.0.48-client.jar!/:?] {re:mixin,pl:accesstransformer:B,re:classloading,pl:accesstransformer:B,pl:mixin:A} at net.minecraft.server.MinecraftServer.m_206580_(MinecraftServer.java:256) ~[forge-1.20.4-49.0.48-client.jar!/:?] {re:mixin,pl:accesstransformer:B,re:classloading,pl:accesstransformer:B,pl:mixin:A} at java.lang.Thread.run(Thread.java:833) ~[?:?] {re:mixin}
Based on the interface, we should either be throwing an Exception here or actually giving the data from other players.
It shouldn't be too demanding to send this info around, so I'll go ahead and do that. Since this changes how API functions work, this is going to require a major version bump, so I'm probably going to break some things while I'm at it.
Looks like they're getting closer to release, we should support them!
Vivecraft provides VRData
instances for both eyes. We should grab those, and expose them to devs.
vrdata_world_pre
will only be available client side, and allows for accessing VR data before the tick. No server-side support since, because of latency, having access to it server-side wouldn't help due to latency (you can't take advantage of when in the tick/on what tick it happens like on the client).
vrdata_world_render
will only be available client side, and would be used to allow rendering things at an effective framerate higher than the "20 fps" that the tick-based ones provide.
Will be available to 1.18.x-multiloader
and 1.19.x
To prevent having to break compatibility and making a 3.y.z
we'll be exposing these as IVRPlayer
instances. They can be obtained in IVRAPI
using the following methods:
getVRPlayerPre
: Get player data from before the running tick.
getVRPlayerRender
: Gets player data for rendering. Client-side only!
Returns int[3]{major, minor, patch}.
I tested it in an example mod where nothing has been changed, using Fabric version 1.20.4. Then I added the dependencies of vr-api and architectury, but encountered errors when running the 'runServer' command (which was working before adding the vr-api dependency).
Does this mean that using vr-api as a dependency in a mod will prevent it from running on the physics server side? What if I want to add a mod that has a dependency on vr-api in Minecraft Server?
In VRAPI
, triggerHapticPulse()
checks if we're client-side, and rumbles the current player if so, before checking if the provided player is null. This means, if the server is a singleplayer world and we do a rumble, it will always rumble the server host and never who should be actually rumbled in a multiplayer setting.
Fields such as these would be very useful to mod devs
So i have this persistant problem where i put the fabric version of this mod and i try to play in a server it says that it cant be found even thought i installed immersive mc and installed mc-vr- api i have no idea what is going on and i am wondering if there is a fix
Confirmed on 1.18.2 Fabric 0.0.15. Will need to check other Minecraft and Vivecraft versions.
EDIT: Looks like Minecraft_vr_Instance is null for some reason. Will figure out why
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.