Jump to content

[1.9.4] Getting player idle time in the server


lamp3345

Recommended Posts

Hi, I try to do some testing in my server with RenderOverlayEvent.

Its doesn't work in multiplayer. I don't know how to get it worked.

 

 

            MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();

 

            if (server != null)

            {

                mc.fontRendererObj.drawStringWithShadow(String.valueOf(server.getMaxPlayerIdleMinutes()), 4, 44, 16777215);

 

                if (server.getMaxPlayerIdleMinutes() >= 5)

                {

                    if (player.ticksExisted % 500 == 0)

                    {

                        player.playSound(SoundEvents.AMBIENT_CAVE, 1.0F, 1.0F);

                        player.addChatMessage(Serializer.jsonToComponent("[{\"text\":\"You are AFK too long\"}]"));

                    }

                }

            }

 

 

Sorry for english. I'm bad.

Link to comment
Share on other sites

Hi, I try to do some testing in my server with RenderOverlayEvent.

Its doesn't work in multiplayer. I don't know how to get it worked.

 

 

            MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();

 

            if (server != null)

            {

                mc.fontRendererObj.drawStringWithShadow(String.valueOf(server.getMaxPlayerIdleMinutes()), 4, 44, 16777215);

 

                if (server.getMaxPlayerIdleMinutes() >= 5)

                {

                    if (player.ticksExisted % 500 == 0)

                    {

                        player.playSound(SoundEvents.AMBIENT_CAVE, 1.0F, 1.0F);

                        player.addChatMessage(Serializer.jsonToComponent("[{\"text\":\"You are AFK too long\"}]"));

                    }

                }

            }

 

 

Sorry for english. I'm bad.

Link to comment
Share on other sites

http://mcforge.readthedocs.io/en/latest/concepts/sides/

 

When in SP you are connected to integrated local server (basically multiplayer with one player).

In SP you have access to your own MinecraftServer since it is the one you are running in background, thus this:

MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();

Will not be null (it will be your integrated server).

 

Now when you connect to other server (LAN or dedic) you don't have server thread with you (thus your getMinecraftServerInstance() will be null). Read 1st link if you didn't catch the fact that there are 2 threads.

 

Now - guts tell me that MinecraftServer#getMaxPlayerIdleMinutes() is for server-side only.

This means you can't access it from client thread. To make it clear:

- If you are on MP (outside server) you don't have server thread, thus you cannot access MinecraftServer#getMaxPlayerIdleMinutes().

- While you are on SP - you DO have your integrated server thread, BUT - while it is possible to access this value (you will be doing cross-thread calls), you generally shouldn't do so! Why? Exchanging data between threads directly is kind of bad design, because, as you should understand now - it is NOT universal (works only on SP, not on MP).

 

How to deal with it? Unless "idleMinutes" are somehow sent to client internally (which I doubt) - only server thread can use this field, that is why you will need packets to share it with client.

1. Setup SimpleNetworkWrapper

2. Make packet which will send integer (only)

3. Make handler which will literally set some static field to integer received.

4. The packet can be sent from PlayerEvent.PlayerLoggedInEvent.

5. Use that integer in all of your rendering things.

 

Links:

SNW: http://www.minecraftforge.net/forum/index.php/topic,20135.0.html

Example: http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/2137055-1-7-x-1-8-customizing-packet-handling-with

Thread safety: http://greyminecraftcoder.blogspot.com.au/2015/01/thread-safety-with-network-messages.html

 

Aside from that: (some recent quote that might be useful):

If something is made with SideOnly it is ONLY viable to be referenced by other SideOnly thing.

E.g: You can't reference client class from common/server code, in particular - you can't write "Minecraft#whatever" ANYWHERE outside client-only scope. Client-only scope are all other client-only things + mentioned Client Proxy which would be an extension to common proxy.

 

If you want to reference anything that is reserved for particular side, you need proxy to do it. So instead of referencing given thing from your common code (e.g some Entity class which is common), you make a call to e.g: MyProxy#method(). Say that you want client-only stuff to be referenced - that example "method" will be abstract for common proxy, empty for server proxy (since server should not act upon it), and filled with client-only code on client proxy.

 

This is precisely what you need to operate on Particles which are CLIENT ONLY.

 

That said - since referencing scoped things requires you to be in that things scope - it is logical that if you want to extend a sided class (which referencing definition contains) - you also need to mark that class as sided and also reference it via proxy.

Important thing are those so-called "scopes" - you shouldn't write code for one scope, but for all, and if you need such code, you use proxies. Note that it is not directly connected with current case.

  • Like 1

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

http://mcforge.readthedocs.io/en/latest/concepts/sides/

 

When in SP you are connected to integrated local server (basically multiplayer with one player).

In SP you have access to your own MinecraftServer since it is the one you are running in background, thus this:

MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();

Will not be null (it will be your integrated server).

 

Now when you connect to other server (LAN or dedic) you don't have server thread with you (thus your getMinecraftServerInstance() will be null). Read 1st link if you didn't catch the fact that there are 2 threads.

 

Now - guts tell me that MinecraftServer#getMaxPlayerIdleMinutes() is for server-side only.

This means you can't access it from client thread. To make it clear:

- If you are on MP (outside server) you don't have server thread, thus you cannot access MinecraftServer#getMaxPlayerIdleMinutes().

- While you are on SP - you DO have your integrated server thread, BUT - while it is possible to access this value (you will be doing cross-thread calls), you generally shouldn't do so! Why? Exchanging data between threads directly is kind of bad design, because, as you should understand now - it is NOT universal (works only on SP, not on MP).

 

How to deal with it? Unless "idleMinutes" are somehow sent to client internally (which I doubt) - only server thread can use this field, that is why you will need packets to share it with client.

1. Setup SimpleNetworkWrapper

2. Make packet which will send integer (only)

3. Make handler which will literally set some static field to integer received.

4. The packet can be sent from PlayerEvent.PlayerLoggedInEvent.

5. Use that integer in all of your rendering things.

 

Links:

SNW: http://www.minecraftforge.net/forum/index.php/topic,20135.0.html

Example: http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/2137055-1-7-x-1-8-customizing-packet-handling-with

Thread safety: http://greyminecraftcoder.blogspot.com.au/2015/01/thread-safety-with-network-messages.html

 

Aside from that: (some recent quote that might be useful):

If something is made with SideOnly it is ONLY viable to be referenced by other SideOnly thing.

E.g: You can't reference client class from common/server code, in particular - you can't write "Minecraft#whatever" ANYWHERE outside client-only scope. Client-only scope are all other client-only things + mentioned Client Proxy which would be an extension to common proxy.

 

If you want to reference anything that is reserved for particular side, you need proxy to do it. So instead of referencing given thing from your common code (e.g some Entity class which is common), you make a call to e.g: MyProxy#method(). Say that you want client-only stuff to be referenced - that example "method" will be abstract for common proxy, empty for server proxy (since server should not act upon it), and filled with client-only code on client proxy.

 

This is precisely what you need to operate on Particles which are CLIENT ONLY.

 

That said - since referencing scoped things requires you to be in that things scope - it is logical that if you want to extend a sided class (which referencing definition contains) - you also need to mark that class as sided and also reference it via proxy.

Important thing are those so-called "scopes" - you shouldn't write code for one scope, but for all, and if you need such code, you use proxies. Note that it is not directly connected with current case.

  • Like 1

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.