Low Entry Plugins

Is it possible to add sorting of a struct array based on it’s variables that are inside the struct (int/float/string/etc…)?

Maybe I can make something like this work, I’ll have to do some research before I know for certain.

I’ll let you know when I have an answer.

Hey Guys,

thanks for the amazing free plugin.

I’m not very familiar with hashing but i do have one question regarding the BCrypt: Isn’t it supposed to generate random salts automatically and include them into the hash? Plus should the hash look different to include the version and strength used in its creation?

something like this: $2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa

What am i missing here? Thanks a lot in advance!

Thanks, that would really help :smiley:

Sorting structs turned out to not be possible, because there is no way of defining a wildcard/base for structs.

I did add a sorting blueprint for Objects, which was possible because Objects have UObject as a wildcard/base class.

The object sorting blueprint works by using a comparator function (which requires 2 Objects and output a boolean), which you can implement to define how the Objects should be sorted.

If you mouse-over the blueprint in the editor it will give you all the information you need to make it work.

Ehm no, what you’ve posted was a base64-ed BCrypt hash with the metadata included.
More specifically, what you have is: $<id>$<cost>$<salt><digest>

You could add these values yourself (with the Merge Bytes blueprint for example), but it is very inconvenient to have these automatically included.

Just as a simple example, say you already have a salt generated (on the server side for example), and now you want to create a BCrypt hash with that salt, to send back to the server, to validate your data/digest. This would be impossible if the salt would always be automatically generated.

K, will try it out

I’d like to ask for some guidance before I proceed. :slight_smile:

My intention is to send a structure through the socket connection as one packet.

The structure represents a single player inventory item. The structure has 21 variables of int, float, string, and object reference variable types. The variables are not ordered. In particular, strings appear at varied positions in the structure.

Converting the variables to bytes appears rather straightforward with the ToBytes nodes available. (The object references I intend to convert to full path names and send as strings.)

These can then be merged with the MergeBytes node in a similarly straightforward manner.

My major concern is decoding the packet on the server.

The Byte Data example seems to indicate that various types of variables can be read from the message using the provided functions.

My first tests indicate that a packet composed of a string (random chars) and an int (13) and output using reader.getStringUtf8() and reader.getInteger()); produce a symbol that appears to be infinity for the string and zero for the int.

First, do I need to read the MESSAGE byte, then the packet length byte (from the SEND MESSAGE node tooltip), then start reading the string and int?

Do I need to send a byte specifying the length of the string?

In the MERGE BYTES node, does the process include the length of the individual byte arrays?

The MESSAGE byte etc is all done internally, the byte array you receive won’t contain any of this data.

MergeBytes really only merges bytes, it doesn’t add lengths or anything.

If you use a ByteDataReader to read the data, the data will also have to be made with a ByteDataWriter, not with bytesToString and mergeBytes. This is because the ByteDataReader/Writer convert data to and from bytes slightly differently, writer.addString will for example also add the length of the string whereas bytesToString won’t.

When it comes to serialization, I recommend adding a toBytes method to every class in Java that will return a byte array of its data. If you’re going to add objects, get the object bytes with its toBytes method and add those bytes with writer.addByteArray.

I’ll make a small example of this tomorrow.

Thanks! Looking forward to it!

Based upon your comments, I have succeeded in getting a ByteDataWriter working in UE4 (4.11.2) and have successfully read the data in Eclipse with the ByteDataReader. :slight_smile:

Here’s a small example of how I would save and load my data.

public class Inventory
{
    public final ArrayList<InventoryItem> items = new ArrayList<InventoryItem>();
    
    
    public static byte] toBytes(Inventory inventory)
    {
        if(inventory == null)
        {
            return new byte[0];
        }
        ByteDataWriter writer = .writeByteData();
        
        {// writes the data >>
            writer.addInteger(inventory.items.size());
            for(InventoryItem item : inventory.items)
            {
                writer.addByteArray(InventoryItem.toBytes(item));
            }
        }// writes the data <<
        
        return writer.getBytes();
    }
    
    
    public static Inventory fromBytes(byte] bytes)
    {
        if((bytes == null) || (bytes.length == 0))
        {
            return null;
        }
        ByteDataReader reader = .readByteData(bytes);
        Inventory inventory = new Inventory();
        
        {// reads the data >>
            int itemCount = reader.getInteger();
            for(int i = 0; i < itemCount; i++)
            {
                inventory.items.add(InventoryItem.fromBytes(reader.getByteArray()));
            }
        }// reads the data <<
        
        return inventory;
    }
}

public class InventoryItem
{
    private int itemId = 0;
    
    
    public static byte] toBytes(InventoryItem item)
    {
        if(item == null)
        {
            return new byte[0];
        }
        ByteDataWriter writer = .writeByteData();
        
        {// writes the data >>
            writer.addInteger(item.itemId);
        }// writes the data <<
        
        return writer.getBytes();
    }
    
    
    public static InventoryItem fromBytes(byte] bytes)
    {
        if((bytes == null) || (bytes.length == 0))
        {
            return null;
        }
        ByteDataReader reader = .readByteData(bytes);
        InventoryItem item = new InventoryItem();
        
        {// reads the data >>
            item.itemId = reader.getInteger();
        }// reads the data <<
        
        return item;
    }
}

I see.

Thanks a lot

Epic just notified me that the marketplace version (aka the binary build) of the Extended Standard Library plugin has been updated, so you should be able to use the new blueprints now.

Ah, thanks a bunch!!!

On the small chance that someone might also encounter this problem, I thought that I would post my solution.

Let me preface this by saying that my project has gone through so many iterations that I am convinced that my code and blueprints are actually Martian invaders here to suck my soul out through my bone marrow, so the likelihood that this error would occur for anyone else is tiny.

I do not believe that this problem was related to the LE plugins themselves, but rather to the way that UE4 handles/manages/looks for plugins.

Also, this problem did not occur in a new project, only my existing one.

I had a problem trying to work with the plugins in my existing project. Although I added the plugins to the engine without difficulty, the project kept displaying an initial dialogue stating that the project required the Low Entry x plugin and would I like to download it. While this was annoying, it did not stop the project from loading and the plugins window showing the LE plugins were enabled.

I could also then proceed to add LE nodes to my GameInstance or other class without apparent error. However, after I saved, closed, then reopened the editor, a number of “Can’t find asset” errors occurred relating to the LE plugins and other assets failed to load.

My test case was a simple Low Entry Socket Connection variable. Creating this one item in any location broke the project on reload. For some reason, the variable always lost its Type and became simply an Object.

After a lot of web searches and trial and error over three days, I determined that my project was not able to access the plugins properly and came to this solution: I placed the LE plugins in a Plugins folder in the main project directory and edited the .uplugin files entry for “LoadingPhase” to read “PreDefault” in place of “Default”.

I am not sure that the last step was necessary.

If anyone has a proper way to sort this out, I’d be happy to see it. :slight_smile:

Oh wow that’s weird, let’s try to find out why that happened.

What engine version did this happen in?

Was it a C++ project?

Can you copy paste the content of your projects .uproperty file here (of one project that works and of one that doesn’t)?

4.11 and 4.12. I tried both (prior to my changes) and the result was the same. The project originated in 4.6 and has been continuously upgraded to each version since then.

Yes. However, the project has an inventory system and a social system (blueprints) from the marketplace and these are in a state of flux. I parented several classes from the blueprints to c++ classes.

They are essentially the same save for the standard library file name. The project source control files, which I have not yet updated, are from 4.11.


{

	"FileVersion": 3,

	"EngineAssociation": "4.12",

	"Category": "",

	"Description": "",

	"Modules": 

		{

			"Name": "Colony2",

			"Type": "Runtime",

			"LoadingPhase": "Default",

			"AdditionalDependencies": 

				"Engine"

			]

		}

	],

	"Plugins": 

		{

			"Name": "LowEntryExtStdLib",

			"Enabled": true,

			"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/offers/846c2ad08f164f45b0335ecebf85361e"

		},

		{

			"Name": "LowEntrySocketConnection",

			"Enabled": true,

			"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/offers/a8cf875efc8d4be3b2ab5f369241797c"

		}

	]

}

I forgot to mention that I also removed the plugins from the Marketplace folder under the Engine Plugin’s folder.

I have done this for both engine versions and cannot now recreate the error with the source from .svn. 4.11 still thinks it has the plugins installed, so I will have to re-install the engine to revert back to the original state. (The standard library for 4.11 and 4.12 are different and I no longer have a copy of the 4.11 standard library.)

I tried everything I could come up with, nothing bugged. My guess is that it was caused by a mistake/bug in the UE4 update conversion code (the functionality that converts your code from 4.x to 4.x).

I would post this in the answerhub bug reports if you haven’t yet, maybe Epic will be able to help you.

I haven’t gotten around to test this yet, but there is a bug being reported with volume value for UI on Android:

[Gear VR] How to do the required volume UI? - Programming & Scripting - Unreal Engine Forums by TrujaSanguinaria.

He wrote: “It would be much to ask how the ‘Get Volume’ node (from LE plugin) works? Cause I’ve tested it getting the volume and printing strings every time a volume button in gear is pressed, but the string does not seem to vary regardless of the phone’s volume. Have I to use this node to get the phone’s volume?”

Thanks beforehand :o

Ah thanks for letting me know.

He also sent me a private message about this, but I don’t know if his problem is solved yet though.

Either way, I haven’t tested the blueprint myself yet. In theory it should work (only on Android phones), but since my phone is using Android 2.2 or something ancient as that, I can’t actually test it lol.

Lastly, in newer versions of the Extended Standard Library plugin the blueprint has been be renamed to Get System Volume, because I think that name makes a lot more sense. The change still has to come live, but just so you know in case you can’t find it :stuck_out_tongue:

Edit: I forgot to tell you that the blueprint will only work on 4.10+, so that’s also something to take into account.

Edit 2: I found out why the blueprint didn’t work and I think I’ve fixed it.