MT GUID generation method

If you have searched the other User Creations subforums and an answer to your question has not been found, please post here!

Moderators: dorpond, trevor, Azhrei, Gamerdude

Post Reply
bobifle
Giant
Posts: 219
Joined: Thu Oct 19, 2017 12:36 pm

MT GUID generation method

Post by bobifle »

Hello, I'm in the need of generating such GUID outside MT (in python to be more precise).

The thing is I cannot figure out how these are generated, they look like

Code: Select all

<baGUID>vf4hA5peQAyW34C31Vuh2g==</baGUID>
once serialized. By looking at GUID.java I found out that they are generated using a type 4 UUID (random) string representation, stripped of its '-' characters. This string is then given to

Code: Select all

HexCode.encode()
Hexcode is not a MT object, and I found no clue about this lib with google. I'm in a dead end.

I tried, base64 encoding and other types of encoding and didn't yield any positive results.

Phergus
Deity
Posts: 7132
Joined: Fri May 12, 2006 8:56 pm
Location: Middle of Nowhere, NM
Contact:

Re: MT GUID generation method

Post by Phergus »

HexCode is in the withay-util library. You'll find the jar file in the libs directory of a MT install.

The HexCode class:

Code: Select all

package com.withay.util;

import java.util.HashMap;
import java.util.Map;

public class HexCode
{

    public HexCode()
    {
    }

    public static byte[] decode(String s)
    {
        byte abyte0[] = new byte[s.length() / 2];
        char ac[] = s.toCharArray();
        int i = 0;
        for(int l = 0; l < ac.length; l += 2)
        {
            int j = getNibbleForChar(ac[l]);
            int k = getNibbleForChar(ac[l + 1]);
            abyte0[i++] = (byte)(j << 4 | k);
        }

        return abyte0;
    }

    public static String encode(byte abyte0[], boolean flag)
    {
        StringBuffer stringbuffer = new StringBuffer();
        char ac[];
        if(flag)
            ac = hexCharsLC;
        else
            ac = hexCharsUC;
        for(int k = 0; k < abyte0.length; k++)
        {
            int i = abyte0[k] >> 4 & 0xf;
            int j = abyte0[k] & 0xf;
            stringbuffer.append(ac[i]);
            stringbuffer.append(ac[j]);
        }

        return stringbuffer.toString();
    }

    private static int getNibbleForChar(char c)
    {
        return ((Integer)hexMap.get(new Character(c))).intValue();
    }

    private static char hexCharsLC[] = {
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
        'a', 'b', 'c', 'd', 'e', 'f'
    };
    private static char hexCharsUC[] = {
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
        'A', 'B', 'C', 'D', 'E', 'F'
    };
    private static Map hexMap;

    static 
    {
        hexMap = new HashMap();
        for(int i = 0; i < hexCharsLC.length; i++)
        {
            hexMap.put(new Character(hexCharsLC[i]), new Integer(i));
            if(hexCharsLC[i] != hexCharsUC[i])
                hexMap.put(new Character(hexCharsUC[i]), new Integer(i));
        }

    }
}

User avatar
JamzTheMan
Great Wyrm
Posts: 1872
Joined: Mon May 10, 2010 12:59 pm
Location: Chicagoland
Contact:

Re: MT GUID generation method

Post by JamzTheMan »

Those ID's are actually generated by XStream when we serialize the classes.

If you want to generate a UUID in Java, just use UUID.randomUUID() from java.util.UUID. If you want it as a string, UUID.randomUUID().toString(). If you want it without hyphens, UUID.randomUUID().toString().replaceAll("-", "")

If you need it in HexCode, you can use that class (IIRC it want's a byte[]). You can checkout our GUID.java class in the 1.4.1.8 fork or from my repo to see how we use that class to generate UUID's for tokens and such used internally.
-Jamz
____________________
Custom MapTool 1.4.x.x Fork: maptool.nerps.net
Custom TokenTool 2.0 Fork: tokentool.nerps.net
More information here: MapTool Nerps! Fork

User avatar
JamzTheMan
Great Wyrm
Posts: 1872
Joined: Mon May 10, 2010 12:59 pm
Location: Chicagoland
Contact:

Re: MT GUID generation method

Post by JamzTheMan »

Of course after typing this, I see you wanted this in Python.... I should learn how to read lol

https://stackoverflow.com/questions/534 ... -in-python

Code: Select all

>>> import uuid
>>> uuid.uuid4()
UUID('bd65600d-8669-4903-8a14-af88203add38')
>>> str(uuid.uuid4())
'f50ec0b7-f960-400d-91f0-c42a6d44e3d0'
>>> uuid.uuid4().hex
'9fe2c4e93f654fdbb24c02b15259716c'
-Jamz
____________________
Custom MapTool 1.4.x.x Fork: maptool.nerps.net
Custom TokenTool 2.0 Fork: tokentool.nerps.net
More information here: MapTool Nerps! Fork

Phergus
Deity
Posts: 7132
Joined: Fri May 12, 2006 8:56 pm
Location: Middle of Nowhere, NM
Contact:

Re: MT GUID generation method

Post by Phergus »

Doesn't MT reassign UUIDs when a token is loaded? If so, it doesn't really matter what UUID he puts in the token does it?

User avatar
JamzTheMan
Great Wyrm
Posts: 1872
Joined: Mon May 10, 2010 12:59 pm
Location: Chicagoland
Contact:

Re: MT GUID generation method

Post by JamzTheMan »

If it's for the tokens UUID yes, I believe you could but just about anything in there (copy an existing one) as it would get a new UUID when you drop it on the map (otherwise dropping the same token multiple times would cause a problem).

There's other instances of <baGUI> in token serializations though like grid and such. However, you can strip down a token xml to just a few tags (it doesn't need ALL of them). BUT, if you are doing this to create tokens externally, YMMV. IF the token class itself is changed, your tokens may or may not work after that. They may or may not work in other (older/newer) versions of MapTool as well. Heck, there's no guarantee that Xstream can/will be used going forward past Java 10.

Personally, I don't suggest doing external rptok files for that reason. MT could really use a Token API that could accept a set XML or JSON payload and create the tokens for you from that unchanging universal format. Any takers? :)
-Jamz
____________________
Custom MapTool 1.4.x.x Fork: maptool.nerps.net
Custom TokenTool 2.0 Fork: tokentool.nerps.net
More information here: MapTool Nerps! Fork

bobifle
Giant
Posts: 219
Joined: Thu Oct 19, 2017 12:36 pm

Re: MT GUID generation method

Post by bobifle »

@Jamz: yep I've been able to generate an uuid4, but your GUIDs seems rather different, or rencoded, they're formed with alphanumeric characters, not only hex characters.

@Phergus: you're right (and Jamz as a consequence). I didn't think of it, but yeah anyway token GUIDs are reassigned upon dropping the rptok file. I still may need to generate valid GUID in the future though, as I plan to inject tokens directly into a cmpgn file, and I'm trying to figure out how I can make it work.


As for Jamz's remark about generating stuff externally, I totally agree with the argument, but for now, for me the existing alternative is not acceptable, refactoring stuff is way too painful manually. I could not do it in MT macros, as I'm not Wolf42's sidekick :mrgreen:.

If MT would accept json data with post commands, I would certainly use it (well it would probably still python feeding the data) but at least it would ensure the correct data serialization/deserialization among multiple java version and I wouldn't need to care about MT internal specifics.

FYI, my work is kinda working... from a simple json structure, I can rebuild from scratch a set of cmpgn and rptok files.

Code: Select all

# An eclipse phase 2nd edition framework
campaign_props='''[
{"name": "aptitudes", "showOnSheet": true, "value": "COG {cognition} | INT {intuition} | REF {reflex} | SAV {savvy} | SOM {somatics} | WIL {willpower}"},
{"name": "pools", "showOnSheet": true, "value": "Ins {insight} | Mox {moxie} |Vig {vigor} | Flex {flex}"},
{"name": "initiative", "showOnSheet": true, "value": "{(reflex + intuition)/5}"},
{"name": "lucidity", "showOnSheet": true, "value": "{willpower*2}"},
{"name": "insanity", "showOnSheet": true, "value": "{lucidity*2}"},
{"name": "trauma", "showOnSheet": true, "value": "{lucidity/5}"},
{"name": "infection", "showOnSheet": true, "value": "{psi*10}"}
]
''

tokens='''
{	"_type" : "Character", 
	"name" : "Amal",
	"attributes": [
		{"somatics":15},
		{"reflex": 20},
		{"savvy": 15},
		{"intuition": 20},
		{"cognition": 15},
		{"willpower" : 15}
		],
	"pools": [
		{"insight":1},
		{"moxie":0},
		{"vigor":4},
		{"flex": 1},
		{"ego_flex": 1}
		],
	"skills": [
		{"melee":55},
		{"psi":0}
		]

}
'''
If I want to change the name of a property, it's a matter a seconds to rebuild the campaign and all the tokens.

Anyway, I really do appreciate your help, thank you !

bobifle
Giant
Posts: 219
Joined: Thu Oct 19, 2017 12:36 pm

Re: MT GUID generation method

Post by bobifle »

I may have figured it out.

The GUID, a byte[] is stored by XStream as a b64 encoded string.

The python code to generate a bytes [] GUID

Code: Select all

guid = uuid.uuid4().bytes
To generate a XStream serialized GUID

Code: Select all

guid = base64.b64encode(uuid.uuid4().bytes)

User avatar
JamzTheMan
Great Wyrm
Posts: 1872
Joined: Mon May 10, 2010 12:59 pm
Location: Chicagoland
Contact:

Re: MT GUID generation method

Post by JamzTheMan »

There ya go! Will done!

Btw, can I ask what you are doing, or rather why you are creating the campaign file like this?

Just curious is all. I'm guessing you must have some external play going on with your players or something? Who knows, it might spark some me feature...
-Jamz
____________________
Custom MapTool 1.4.x.x Fork: maptool.nerps.net
Custom TokenTool 2.0 Fork: tokentool.nerps.net
More information here: MapTool Nerps! Fork

bobifle
Giant
Posts: 219
Joined: Thu Oct 19, 2017 12:36 pm

Re: MT GUID generation method

Post by bobifle »

The main objective is to build a Eclipse phase framework, with all lib tokens, and examples/characters tokens included, possibly some maps and a DM screen.

And the reasons why I'm doing it this way are numerous, and some of them are properly invalid and the direct consequence of my bad knowledge of MT but since you asked:
  • I don't know why, I'm having fun retro engineering MT files, 5 geek points
  • I like automation, I like automating using python, 7 geek points
  • I watched 300+ DnD tokens being built, comfortably seated in my chair while doing nothing but looking at my logs. 12 lazy points
  • As I added a new feature to my tokens, I really enjoyed looking at python working instead of me, taking a sip of beer. 8 lazy points
  • I dislike the Mt macro language. Some ppl doing amazing things with it, but as I dig into the code from the DND 5e framework for instance, I almost got blind. It's not for me, so I resort to other means to do the heavy manipulations. 3 Troll points
  • Refactoring is a breeze, I'm currently building a framework from scratch, Eclipse Phase 2nd, for educational purpose, and it's a lot of try and error. As I change things around, it takes me 5 sec to regenerate the cmpgn file with all its properties/states/lights and all its tokens. (I currently have few tokens, but I probably end up with dozens if not hundreds. This is probably my only valid and strong point for building MT file externally. 3 valid points
  • versioning a framework built this way is made easy. 1 valid point
  • I know very little about java and its ecosystem, I tried using eclipse, and I failed miserably. I mean I've been able to run MT from eclispe but that's pretty much it. And I don't think I'm willing to spend that much time learning it, otherwise I agree that would be a much better solution to actually improve MT itself instead of relying on 3rd party tools. 7 lame points
So if I summarize, I'm mainly doing this because I'm a lame and lazy geek, bad at java programming who like to troll from time to time :mrgreen:

User avatar
JamzTheMan
Great Wyrm
Posts: 1872
Joined: Mon May 10, 2010 12:59 pm
Location: Chicagoland
Contact:

Re: MT GUID generation method

Post by JamzTheMan »

I like the point system :)

Thanks for sharing! +9 sharing points!
All seems valid reasons. Pretty nifty project i would say. And I get the lazy factor 100%! It's why I wrote the Hero lab integration. Drag token out of HL -> MT -> Token 100% stat and ready! Make a change in HL -> Updated in MT! Oh course, That still relied on Macro logic but I did throw in some xpath logic because I disliked the regular expression logic (get complicated quickly!)

Glad you are getting some enjoyment out of it too! That's the #1 reason to do it, where geek points and lazy points intersect!
-Jamz
____________________
Custom MapTool 1.4.x.x Fork: maptool.nerps.net
Custom TokenTool 2.0 Fork: tokentool.nerps.net
More information here: MapTool Nerps! Fork

Post Reply

Return to “Requests for HELLLLP!”