UserVariables dont support long???

Post here your questions about SFS2X. Here we discuss all server-side matters. For client API questions see the dedicated forums.

Moderators: Lapo, Bax

Post Reply
SmartfoxEnjoyer
Posts: 93
Joined: 13 Dec 2023, 20:39

UserVariables dont support long???

Post by SmartfoxEnjoyer »

Hi,

Ive been working with sfs2x for some time now and dont understand why there are so many limitations, its very frustrating.
Why dont you add support for a LONG user var??
Yes we have double, which is only 53 bits, so if we store a long inside this double which SFS2X does when we put a long inside an UserVar then the bits 54-63 will become corrupted and unreadable!

I cannot use .getDoubleValue().longValue() either, the double is still corrupt.
HOWEVER, on csharp side i can actually just do:
(long) .getDoubleValue(); // directly cast to long and then i can read the long corrrectly, but java doesnt support this, we get a class cast exception and when i try to use the java .longValue() method of the Double class it just returns garbage instead.

Code: Select all

            long packedTypeData = 0;
            packedTypeData |= ((long) MMOItemTypes.NPC_ENEMY.ordinal() & 0xFF) << 56; // bits 56-63
            packedTypeData |= ((long) (_anchorCornerX - _halfWorldSize) & 0xFFFF) << 40; // bits 40-55
            packedTypeData |= ((long) (_anchorCornerZ - _halfWorldSize) & 0xFFFF) << 24; // bits 24-39
            packedTypeData |= ((long) _soEnemy.ID & 0xFFFF) << 8; // bits 8-23 // SONPC ID
            _variables.add(new MMOItemVariable("n", packedTypeData));
// This becomes a double, why not add support for LONG variable??
[/code]


Then later i try to unpack it in java but its not working:

Code: Select all

 long packedTypeData = mmoItem.getVariable("n").getDoubleValue().longValue();
                            MMOItemTypes mmoItemType = MMOItemTypes.FromByte((byte) ((packedTypeData & 0xFF) >> 56)); // bits
                                                                                                                      // 56-63
                            StaticResources.Trace("MMOItemtype: " + mmoItemType); // always 0, corrupted bits
                           



Listen, sorry if i sound angry, because im really frsutrated, its simple stuff, why isnt there support for a long value in user vars? It doesnt make any sense to me.

Cheers

EDIT: Also i tried .getVariable("n").GetValue(), but its exactly the same it just returns a double value.
Last edited by SmartfoxEnjoyer on 08 Aug 2025, 12:43, edited 1 time in total.
SmartfoxEnjoyer
Posts: 93
Joined: 13 Dec 2023, 20:39

Re: UserVariables dont support long???

Post by SmartfoxEnjoyer »

Code: Select all

  // Packing
            _variables.clear();
            long packedTypeData = 0;

            int originalType = MMOItemTypes.NPC_ENEMY.ordinal(); // Example ordinal
            int originalCornerX = _anchorCornerX - _halfWorldSize;
            int originalCornerZ = _anchorCornerZ - _halfWorldSize;
            int originalId = _soEnemy.ID;

            packedTypeData |= ((long) originalType & 0xFF) << 56; // bits 56-63
            packedTypeData |= ((long) originalCornerX & 0xFFFF) << 40; // bits 40-55
            packedTypeData |= ((long) originalCornerZ & 0xFFFF) << 24; // bits 24-39
            packedTypeData |= ((long) originalId & 0xFFFF) << 8; // bits 8-23

            MMOItemVariable typeVar = new MMOItemVariable("n", packedTypeData);
            _variables.add(typeVar);

            // Immediately unpack for validation
            double rawDouble = typeVar.getDoubleValue();
            long unpackedTypeData = Double.doubleToRawLongBits(rawDouble);

            // Unpack fields
            byte unpackedType = (byte) ((unpackedTypeData >> 56) & 0xFF);
            int unpackedCornerX = (int) ((unpackedTypeData >> 40) & 0xFFFF);
            int unpackedCornerZ = (int) ((unpackedTypeData >> 24) & 0xFFFF);
            int unpackedId = (int) ((unpackedTypeData >> 8) & 0xFFFF);

            // MMOItemTypes unpackedMmoItemType = MMOItemTypes.FromByte(unpackedType);

            // Tracing everything
            StaticResources.Trace("=== Packed + Unpacked Debug ===");
            StaticResources.Trace("Original packedTypeData (hex): 0x" + Long.toHexString(packedTypeData));
            StaticResources.Trace("Raw double: " + rawDouble);
            StaticResources.Trace("Unpacked long (hex): 0x" + Long.toHexString(unpackedTypeData));

            StaticResources.Trace("Original Type ordinal: " + originalType + " → Unpacked: " + unpackedType);
            StaticResources.Trace("Original CornerX: " + originalCornerX + " → Unpacked: " + unpackedCornerX);
            StaticResources.Trace("Original CornerZ: " + originalCornerZ + " → Unpacked: " + unpackedCornerZ);
            StaticResources.Trace("Original ID: " + originalId + " → Unpacked: " + unpackedId);

            StaticResources.Trace("=== End Debug ===");




14:41:38,271 INFO [pool-1-thread-2] Extensions - {__lib__}: === Packed + Unpacked Debug ===
14:41:38,271 INFO [pool-1-thread-2] Extensions - {__lib__}: Original packedTypeData (hex): 0x1ffd4ffd9000700
14:41:38,271 INFO [pool-1-thread-2] Extensions - {__lib__}: Raw double: 1.44067908421551872E17
14:41:38,272 INFO [pool-1-thread-2] Extensions - {__lib__}: Unpacked long (hex): 0x437ffd4ffd900070
14:41:38,272 INFO [pool-1-thread-2] Extensions - {__lib__}: Original Type ordinal: 1 → Unpacked: 67
14:41:38,273 INFO [pool-1-thread-2] Extensions - {__lib__}: Original CornerX: -44 → Unpacked: 32765
14:41:38,273 INFO [pool-1-thread-2] Extensions - {__lib__}: Original CornerZ: -39 → Unpacked: 20477
14:41:38,273 INFO [pool-1-thread-2] Extensions - {__lib__}: Original ID: 7 → Unpacked: 36864
14:41:38,274 INFO [pool-1-thread-2] Extensions - {__lib__}: === End Debug ===
SmartfoxEnjoyer
Posts: 93
Joined: 13 Dec 2023, 20:39

Re: UserVariables dont support long???

Post by SmartfoxEnjoyer »

In csharp we can get the original hex value back, but on java even getRawLongBits doesnt work
SmartfoxEnjoyer
Posts: 93
Joined: 13 Dec 2023, 20:39

Re: UserVariables dont support long???

Post by SmartfoxEnjoyer »

So it took an hour to figure this out and a lot of frustration, and for what? Why not just add support for a long???

Code: Select all

 double rawDouble = mmoItem.getVariable("n").getDoubleValue();
                            long unpackedTypeData = (long) rawDouble; // now i dont get class cast exception anymore??

                            MMOItemTypes mmoItemType = MMOItemTypes.FromByte((byte) ((unpackedTypeData >> 56) & 0xFF)); // 56-63


This works for anyone in the future who needs to unpack a double back to long in sfs2x, have fun.
User avatar
Lapo
Site Admin
Posts: 23438
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: UserVariables dont support long???

Post by Lapo »

Hi,
that was a design decision taken a long time ago, with the idea that Variables would mostly use simple types (ints / strings) to hold data such as some character properties, scores, coordinates, etc.

Code: Select all

MMOItemTypes mmoItemType = MMOItemTypes.FromByte((byte) ((unpackedTypeData >> 56) & 0xFF)); // 56-63

Instead of doing bitwise shift hacks I'd suggest a simpler solution: wrapping your data in an SFSObject.

Code: Select all

var data = new SFSObject();
data.putLong("big", Long.MAX_VALUE);
data.putByte("small", Byte.MIN_VALUE);
//etc...

var myUv = new SFSUserVariable("d", data);
// Send the UserVariable(s)


Thanks

p.s. = this will be changed in SFS3, fwiw.
Lapo
--
gotoAndPlay()
...addicted to flash games
Post Reply