Allow some players to see "better" at Night, is it possible ?

Discussion in 'Plugin Development' started by TrainYourBrain, May 7, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    TrainYourBrain

    Hey guys,

    To go further with vampire mod, I would like to make vampire being able "to see better" at night than other "normal" players. But I don't know if this is possible, because it means the vampire plugin have to atler the night for some of the users ... ? So do you think is possible ?
    Some help will be really appreciate ;-) , I don't want code, but just some idea/way to make it real :)

    Thanks and good night/day :)
     
  2. Offline

    matter123

    well you could set the helmet to pumpkin for night for normal and day for vampires
     
  3. Offline

    TrainYourBrain

    Yeah, that's a hint :)

    But I would prefere to modify the local brightness of a player .. but seems impossible for now.

    Thanks anyway dude ;)
     
  4. Offline

    nickguletskii

    You could continuously send the Packet52MultiBlockChange(or at least I think that it has lighting in it) to a player with lighting values.
     
  5. Offline

    TrainYourBrain

    Thanks for your anwser, but I'm quiet new to Bukkit and I don't know what is Packet52MultiBlockChange. I mean I don't understand what it refers to ?
    With your method, do the blocks will be "brighter" for all players or only to one given player on server ?
    Thanks anyway :)
     
  6. Offline

    nickguletskii

    Only one player. Use the javadoc to find the appropriate way to do this :)
     
  7. Offline

    TrainYourBrain

    So it seems to be the good solution you are given :D .

    I saw the javadoc :) but there is no information about the function Packet52MultiBlockChange :) only parameters expected.
    Another thing is I can't import net.minecraft.server.Packet52MultiBlockChange do you have an idea why ? :) It isn't in the bukkit.jar ?

    Thanks again :D
     
  8. Offline

    Kekec852

    You need to use craftbukkit.jar to import net.minecraft.*
     
  9. Offline

    Alex Nolan

    I too am very interested in a solution to this :)
     
  10. Offline

    TrainYourBrain

    Yep, thanks I add it as external jar ;-)

    But I didn't find any information on about to use the Pack50MultiBlock, even on the javadoc as I said :(
     
  11. Offline

    Alex Nolan

    Here is a decompiled version of Packet52MultiBlockChange, as you can see it doesn't really add that much insight as to how it can be used:

    Code:
    package net.minecraft.src;
    
    import java.io.*;
    
    // Referenced classes of package net.minecraft.src:
    //            Packet, World, Chunk, NetHandler
    
    public class Packet52MultiBlockChange extends Packet
    {
    
        public Packet52MultiBlockChange()
        {
            isChunkDataPacket = true;
        }
    
        public Packet52MultiBlockChange(int i, int j, short aword0[], int k, World world)
        {
            isChunkDataPacket = true;
            xPosition = i;
            zPosition = j;
            size = k;
            coordinateArray = new short[k];
            typeArray = new byte[k];
            metadataArray = new byte[k];
            Chunk chunk = world.getChunkFromChunkCoords(i, j);
            for(int l = 0; l < k; l++)
            {
                int i1 = aword0[l] >> 12 & 0xf;
                int j1 = aword0[l] >> 8 & 0xf;
                int k1 = aword0[l] & 0xff;
                coordinateArray[l] = aword0[l];
                typeArray[l] = (byte)chunk.getBlockID(i1, k1, j1);
                metadataArray[l] = (byte)chunk.getBlockMetadata(i1, k1, j1);
            }
    
        }
    
        public void readPacketData(DataInputStream datainputstream) throws IOException
        {
            xPosition = datainputstream.readInt();
            zPosition = datainputstream.readInt();
            size = datainputstream.readShort() & 0xffff;
            coordinateArray = new short[size];
            typeArray = new byte[size];
            metadataArray = new byte[size];
            for(int i = 0; i < size; i++)
            {
                coordinateArray[i] = datainputstream.readShort();
            }
    
            datainputstream.readFully(typeArray);
            datainputstream.readFully(metadataArray);
        }
    
        public void writePacketData(DataOutputStream dataoutputstream) throws IOException
        {
            dataoutputstream.writeInt(xPosition);
            dataoutputstream.writeInt(zPosition);
            dataoutputstream.writeShort((short)size);
            for(int i = 0; i < size; i++)
            {
                dataoutputstream.writeShort(coordinateArray[i]);
            }
    
            dataoutputstream.write(typeArray);
            dataoutputstream.write(metadataArray);
        }
    
        public void processPacket(NetHandler nethandler)
        {
            nethandler.handleMultiBlockChange(this);
        }
    
        public int getPacketSize()
        {
            return 10 + size * 4;
        }
    
        public int xPosition;
        public int zPosition;
        public short coordinateArray[];
        public byte typeArray[];
        public byte metadataArray[];
        public int size;
    }
    
     
  12. Offline

    nickguletskii

    The light level should be in the metadata... Otherwise I just don't see where it is :/
     
  13. Offline

    TrainYourBrain

    Hey nickguletskii ;)

    Maybe I'm a bit retarder, but I still doesn't understand how to apply the change on the metadata :).
    Do I have to create an instance of Packet52MultiBlockChange and set the metadata as I want ? And after I have send this Packet52MultiBlockChange object to the player object, but how :p ?

    Thanks you very much :)
     
  14. Offline

    Alex Nolan

    I have to concur, I'm not familiar at all with manipulating packets XD (by the looks of your spyer plugin thought, I'd say you are very familiar with that though) :D
     
  15. Offline

    nickguletskii

    Code:
    hideFrom.getHandle().netServerHandler
                                .sendPacket(new Packet29DestroyEntity(hide
                                        .getEntityId()));
    From my plugin. So basically, you do this: player.getHandle().netServerHandler.sendPacket(yourPacket);
    I am not sure if the block change packets are the packets you want though...
     
  16. Offline

    Alex Nolan

  17. Offline

    nickguletskii

    That doesn't include light level.

    Good news! Found the packet that contains light level. http://mc.kev009.com/Protocol#Map_Chunk_.280x33.29
    It is Packet51MapChunk.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jul 16, 2016
  18. Offline

    TrainYourBrain

    OMG ! If it works I'll kiss you !

    Alex, If you use it before I do, please share your code ;) I will do the same I do before you but for now I get tired of programming :)
     
  19. Offline

    nickguletskii

    Just remember - you need to clone the world(so you don't modify the actual world), do a modification to the chunk's blocklightMap and send the packet that contains the cloned world, not the actual world. Moreover, you will have to constantly do that so that the real world doesn't overwrite it ;)
     
  20. Offline

    TrainYourBrain

    Thanks for the advice , looks quiet hard to set up anyway (how to send a pack to the client player for instance) :) ... ok I know I am asking you a lot but I not a professional regarding socket/packet and other thing like that :p
     
  21. Offline

    Alex Nolan

    Wow, great news. So I've been trying to get a working test, but I can't seem to clone the chunk or the world no matter what I try (we need to clone the net.minecraft.server ones, right?). A way I sought to do it was to make a whole new world, but I soon realized that that wouldn't work :/.
     
  22. Offline

    TrainYourBrain

    Ok so here is the way to send a packet to a player :

    Code:
    Packet51MapChunk myPacket;
    ((CraftPlayer)vplayer.getPlayer()).getHandle().netServerHandler.sendPacket(myPacket);
    (vplayer.getPlayer() return a Player object)
    Now I have to find out how initialize Packet51MapChunk :)
     
  23. Offline

    nickguletskii

    It shouldn't be too hard... I am going to try it tomorrow. Also, please tag me when replying to me (by entering @nickguletskii), helps me find your post on time!
     
  24. Offline

    TrainYourBrain

  25. Offline

    Raphfrk

    Btw, another option would be to send fake time of time packets to players. Ofc, this would cause the sun/moon to jump position.
     
  26. Offline

    TrainYourBrain

    @Raphfrk

    Yep, this is an option but I prefered the nickguletskii way :p

    @nickguletskii

    Dear colleague, do you have some news about how to use Packet51MapChunk :) ?
     
  27. Offline

    nickguletskii

    Eeeh, I'll have a look now... Finally free time :D

    Code:
            String s = wor.worldData.name;
            Field fl = wor.getClass().getField("r");
            fl.setAccessible(true);
            IDataManager idm = (IDataManager) fl.get(wor);
            Field fl1 = wor.worldData.getClass().getField("a");
            fl1.setAccessible(true);
            int i = (Integer) fl1.get(wor.worldData);
            WorldProvider wp = wor.worldProvider;
            World psuedo = new World(idm, s, i, wp);
    wor is a Minecraft world (not a Bukkit world)... Well, haven't tested. This can be used to construct a world, nothing more.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jul 16, 2016
  28. Offline

    TrainYourBrain

    @nickguletskii

    Ho thanks your very much !! But don't we have to use PacketMap51Chunk ? :p
    We get closer and closer to the goal thanks to you :)
     
  29. Offline

    Raphfrk

    Probably not :) since

    They are massive packets. They give the entire info for an entire chunk (plus block data).

    You need to compress and decompress the data since they are compressed because they are so large.

    Alternatively, you could hack the light levels directly. They are in

    ((CraftChunk)chunk).getHandle().f
    ((CraftChunk)chunk).getHandle().g

    (I think)

    One is torch/block light (g) and the other is sky light (f).

    They should only be altered in the main thread ... and even then not sure :).

    Also, that would change it for everyone and also they might recalculate.

    The way to create one is:

    Code:
    new Packet51MapChunk(i, j, k, l, i1, j1, this.playerManager.world)
    
    This will create one based on the current world state and calls the compression system.

    I am not really sure if it is a good idea though :).
     
  30. Offline

    Alex Nolan

    I think we should be able only send part of the chuck (eg the space around the player), and not just the whole chunk.

    eg:
    Code:
    Packet lightP = new Packet51MapChunk(playerXPos - 5, playerYPos - 2, playerZPos - 5, playerXPos + 5, playerYPos + 2, playerZPos + 5, newLightWorld)
    To update a small block around the player. Of course we could update only the block in front of the player, but this is just simple psuedocode that assumes we manipulate the lighting of the "false" world as well.
     
Thread Status:
Not open for further replies.

Share This Page