Skip to main content

6 posts tagged with "MapTool"

View All Tags

路 2 min read
caution

This post describes a work in progress so details may change due to feedback. This is also the reason that the documentation is a bit sparse. Before creating any issues check the bottom of the post for things still to be implemented. These features required a HUGE amount of behind the scene changes to how events, lib:tokens, and Assets work, so there will be a large amount of testing that needs to be done, I am expecting that there are still several bugs that I have not been able to uncover yet with my testing. Any help testing would be grealy appreciated.

It should go without sayind please don't run your games with this yet.

Retrieving static data from Add-Ons#

You can retrieve the static data that is zipped up in an add-on with the following macro script function.

data.getStaticData(namespace, path)

If this macro function is run from the add-on then it is able to retrieve any file that is in the add-on.

If the macro function run from ouside of the add-on then it is only able to retrieve files in the public/ directory and only if the Allow URI Access flag is set.

If the path does not exist in the add-on (or a macro tries to read a file that is not in the public/ directory when not run from the add-on) then an empty string will be returned.

路 12 min read
caution

This post describes a work in progress so details may change due to feedback. This is also the reason that the documentation is a bit sparse. Before creating any issues check the bottom of the post for things still to be implemented. These features required a HUGE amount of behind the scene changes to how events, lib:tokens, and Assets work, so there will be a large amount of testing that needs to be done, I am expecting that there are still several bugs that I have not been able to uncover yet with my testing. Any help testing would be grealy appreciated.

It should go without sayind please don't run your games with this yet.

note

This information supercedes the previous blog post.

Add-On Libraries

MapTool 1.11 introduces add-on libraries which are intended to be an easier to work with replacement for Lib:Tokens while also offering a lot more functionality. Lib:Tokens will still function the way that they currently do in MapTool 1.11 and future versions, but will not be getting a lot of the new features that add-on libraries will have, so it is recommended that framework developers transition to add-on libraries if supporting MapTool 1.11 and above.

I have a very sparse and contrived add-on library I have been using for testing available at test-maptool-add-on-lib

Format of add-on library files#

Add-On libraries can be shared in a .mtlib file. This file is a zip file with a specific structure and content. You can import these libraries with the File -> Import Add-On Library menu option.

library.json            <-- Configuration information for the add-on librarymts_properties.json     <-- Properties for macro script functions in libraryevents.json             <-- Event definition for functions in the librarylibrary/                <-- Content of the librarylibrary/public          <-- Content of the library acessable via `lib:// URI`library/mtscript        <-- MTSCript fileslibrary/mtscript/public <-- MTSCript files that can be called via `[macro(): ]` outside of the library.

format of the configuration file#

The library.json configuration file is a json file with the following structure.

{  "name": "test-library",  "version": "1.0.0",  "website": "www.rptools.net",  "gitUrl": "github.com/RPTools/test-library",  "authors": [ "RPTools Team" ],  "license": "GPL 3.0",  "namespace": "net.rptools.maptool.test-library",  "description": "My new test library for stuff",  "shortDescription": "test library",  "allowsUriAccess": true}

format of the events configuration file#

This json file contains which files should be run for certain events.

{   "events": [      { "name": "onFirstInit", "mts": "onFirstInit" },      { "name": "onInit", "mts": "onInit"}   ],   "legacyEvents": [      { "name": "onInitiativeChangeRequest", "mts": "onInitiativeChangeRequest" },      { "name": "onInitiativeChange", "mts": "onInitiativeChange" },      { "name": "onTokenMove", "mts": "onTokenMove" },      { "name": "onMultipleTokensMove", "mts": "onMultipleTokensMove"}   ]}

Add ons do not respond to the "onCampaignLoad" event, instead they have 2 new events.

  • onFirstInit - This is called only once, when the add on is added. Add the same add on a second time overwriting the existing one it will not be called again unless the data for the add-on is removed first.
  • onInit - This is called every time the campaign is loaded (including after the inital onFirstInit event), and on the client when sent to a client. This functionality is very much similar to onCampaignLoad.

The other events must be in the "legacyEvents" section, as the name implies these events are now considered to be legacy events, new events will be added in the future to replace these (these will not be removed though).

Currently only macro scripts are supported, in the future JavaScript scripts will also be supported.

MTScript macros#

  • library/public is only exposed via lib:// URI if allowsUriAccess is set (see configuration file)
  • MTScript macros must all end with the file extension .mts to be recognised.
  • Any Only MTScript files in content/mtscript/public can be called using [macro():] from outside of the add-on

The path of the file becomes that macroname for [macro(): ] the namespace of the add-on library is used for the @ portion.

Add-On libraries support both public and private macro functions. Public macro functions must reside in the mtscript/public and can be called from anywhere (chat, other add-ons, lib:tokens, macro buttons). You can call them using the following syntax [macro("mtscript1@lib:net.rptools.maptool.test-library")] executes MTScript macro in the file content/mtscript/public/mtscript1.mts.

note

The "public/" is ommited from the macro name when calling it. You can also use subdirectories to organise your macros and would call them like [macro("subdir/script@lib:net.rptools.maptool.test-library")]

The @this shorthand can also be used for calling a macro from within the same add-on, similar to how it works for lib:Tokens. For example [macro("mtscript2@this")]

Macro script files that are not in the "public/" directory can only be called from within the add-on itself or by events. Given a library with the namespace net.mylib.addon with the following files.

mtsscript/func1.mtsmtsscript/public/func2.mts

[macro("func1@lib:net.mylib.addon")] can be called from anywhere, but [macro("func2@lib:net.mylib.addon")] can only be called from a macro that is on the net.mylib.addon add-on.

note

Since the "public/" is not required, if you have to files with the same name excluding the "public/" part, for example mtscript/public/funct1.mts mtscript/funct1.mts

Then only the one in public/ will be able to be executed, you will not be able to call the other macro

The above works not just with `[macro():] but the other places you would expect it to as well such as defineFunction() for user defined functions and macro links.

mts_properties.json file#

The mts_properties.json file contains property information about macro scripts, it is not required and currrently only allows you to set properties used in macro links.

{   "properties": [     {      "filename": "public/auto_exec.mts",      "autoExecute": true,      "description": "Auto executable macro link"    },    {      "filename": "public/myUDF.mts",      "description": "My Test UDF in a drop in lib."    }  ]}

Where

  • filename is the path of the file for the MacroScript function (excluding mtscript/).
  • autoExecute determines if a macro link created for this macro will be auto executable or not.
  • description is the description that will appear in the UDF listing, unlike Lib:Token this is just a plain string and not evaluated if it contains []

public/ directory#

The contents of this directory are exposed as a lib:// URI as long as the allowsUriAccess is set to true in the configuration file. The public directory part of the filename is discared, for example public/myhttml.html -> lib://net.myaddons.addon1/myhtml.html

You can add images to this directory and use src="lib://" in image tags in HTML. It will eventually work with audio (probably aleady does but I haven't tested it yet so not claining it will yet :) )

These assets will be included correctly in the campaign file when saving, so you do not need to add them to image tables or image tokens or any other tricks to make sure that they are included.

New MTScript Library functions#

  • library.listAddOnLibraries() Lists the add on libraries
  • library.getInfo(namespace) Gets information about a library (either add on or lib:token)
  • library.listTokenLibraries() Lists the Lib:tokens in the campaign
  • library.getContents(namespace) Lists the contents of a library (trusted)
  • library.removeAddOn(namepsace) Removes an add-on (trusted) (used for testing only, probably wont make it into release)
  • library.removeAllAddOns() Removes all add-ons (trusted) (used for testing only, probably wont make it into release)

Add-On Libraries and Data#

As Add Ons do not live on a token there are no token properties for them. Instead there has been a new area created for storing data that is a lot more flexible -- and will allow data to be stored agisnt other entities like maps in the future. The existing lib property functions below have been modified to work with this new data store if called with an add-on as the target.

  • setLibProperty
  • getLibProperty
  • getLibPropertyNames
  • getMatchingLibProperties

There are some differences to be aware of when using lib property support for add-ons.

  • The name is case sensitive, unles tokens where it is not case sensitive.
  • The values stored do not need to be be converted to/from strings like they do with lib:tokens so in many cases for large json values this should result in a speed improvement.
  • The default properties list for the campain are not present for Add-Ons as they are not tokens unlike Lib:Tokens

Macro functions#

There are some macro functions that will be included in the alpha build for testing purposes that will allow you to clear/get/edit the data store. The data store is not intended to be used like this from macros so they will not be in the release build -- there will probably be something similar in 1.12 though.

  • data.createNamespace(type, namespace) - Creates namespace for data
  • data.listNamespaces(type) - Lists the created namespaces for a type
  • data.setData(type, namespace, name, value) - Sets a data value in the store
  • data.getData(type, namespace, name) - Gets a data value from the store
  • data.listData(type, namespace) - Lists the data stored in a namespace
  • data.clearData(type, namespace, name) - Clears the data for the given name in the data store
  • data.clearNamespace(type, namespace) - Clears all the data from a namespace
  • data.clearAllData() - Clears all the data in the data store

For add-ons the type will be 'addon:' and the namespace will be the namespace of the add-on.

Converting Lib:tokens#

The token popup menu includes a way to export your existing library tokens to an add-on. This is useful for starting the conversion of an existing token library to an add-on but in all but the simplest lib:tokens you will want edit the extracted data.

Convert and Export Lib:Tokens

Things you will want to change#

  • You should probably change the namespace in the library.json file to something that is unlikely to conflict with other users. Its a good practice to use a reversed hostname + add on name for this.
  • All macros (except event based ones) are created in mtscript/public with the pattern macro_{number>.mts, this is because macro names have many things that might make them invalid -- or worse dangerous -- filenames. There is a macro_script_map.txt file saved in the top level which contains the names of your macros and the filename that they were saved in.
  • Not all macro buttons on lib:tokens always contain MT Script macros, they are used for CSS etc as well so you will probably want to rename and move them to the library/public/ directory.
  • The onCampaignLoad macro will be saved as onInit
  • All properties are saved in the library/properties directory. These are saved with the names prop_{number}.txt and a mapping file prop_file_map.txt is created to map these. (this may change slightly when data access is introduced, more the location)
note

After doing the above you should REALLY take the opportunity to source control your Add-On...

Things not yet implemented but will be (so dont create issues for these or I will just close them)#

The things detailed below will probably only be implemented for add-ons and there will be no equivalent functionality for lib:tokens.

Will be added/addressed in 1.11#

  • There is currenlty no way to properly retrieve json or other data files as data, once this is added its recommended to store large static data here rather than in the data store as then it will only need to be sent to client once which can cache it
  • There is currently no way to remove add-ons
  • There is only minimal checking of data when importing add-ons so error reporting is not great.
  • More documentation

Possibly will be added/addressed in 1.11 depends on available time#

  • Many file types like text/markdown etc are allowed in tate he library but the functions to use them dont yet exist
  • Way to create user defined functions through property file (so you dont have to call defineFunction in onInit)

Probably added/addressed in 1.12#

  • No Management UI yet
  • Expanding of JavaScript API which will make this much more useful will be part of another change.
  • Displaying readme markdown file
  • Displaying more detailed license information
  • Start of support for Add-Ons to to be able to replace "standard" functionality, first things wil be
    • Add-On support for stat sheets (on mouseover on tokens)
    • Add-On support for map selection UI

Probably added/addressed in 1.13#

  • Ability to check URL for later version and update from that (most likely github to start with)
  • Link Maps to required Add-Ons when exporting/importing
  • Dcoumentation / Procuedures for creating a GitHub release for your Add-On.
  • The data store could be slightly smatter about large text blocks that remain static and attempt to cache them

Questions I need feedback on#

  • Add-Ons lack a built in UI, Lib:Tokens have the macro buttons but Add-Ons dont. Better UIs can now be created for Add-Ons using frame5/dialog5 with the lib:// URL support (we can expand that to added other things that are needed) but do we also need something similar to what lib:tokens have.

Other miscellaneous stuff / insanity#

One thing to realise is this change allows serveral things that are not immediately obvious. For example, experiment with frame5/dialog5 and lib:// URI support and ability to store images, you would be surprised how close it is to devloping a standard web site. Ass a proof of concept I have even been able to get a small React App written in TypeScript running realtively easily by using webpack to bundle it and copy it into the public directory. (Note the SVG for the beginner React app doesn't work correctly but replacing it with a png works).

路 5 min read

Note: This post describes a work in progress so details may change due to feedback. This is also the reason that the documentation is a bit sparse. Before creating any issues check the bottom of the post for things still to be implemented. Also the current code doesn't do much checking for the format of the config/property files this will be improved.

Add-On Libraries

MapTool 1.11 introduces add-on libraries which are intended to be an easier to work with replacement for Lib:Tokens while also offering a lot more functionality. Lib:Tokens will still function the way that they currently do in MapTool 1.11 and future versions, but will not be getting a lot of the new features that add-on libraries will have, so it is recommended that framework developers transition to add-on libraries if supporting MapTool 1.11 and above.

I have a very sparse and contrived add-on library I have been using for testing available at test-maptool-add-on-lib

Format of add-on library files#

Add-On libraries can be shared in a .mtlib file. This file is a zip file with a specific structure and content. You can import these libraries with the File -> Import Add-On Library menu option.

library.json            <-- Configuration information for the add-on librarymts_properties.json     <-- Properties for macro script functions in librarylibrary/                <-- Content of the librarylibrary/public          <-- Content of the library acessable via `lib:// URI`library/mtscript        <-- MTSCript fileslibrary/mtscript/public <-- MTSCript files that can be called via `[macro(): ]` outside of the library.
  • library/public is only exposed via lib:// URI if allowsUriAccess is set (see configuration file)
  • MTScript macros must all end with the file extension .mts to be recognised.
  • Only MTScript files in content/mtscript/public can be called using [macro():] from outside of the add-on

format of the configuration file#

The library.json configuration file is a json file with the following structure.

{  "name": "test-library",  "version": "1.0.0",  "website": "www.rptools.net",  "gitUrl": "github.com/RPTools/test-library",  "authors": [ "RPTools Team" ],  "license": "GPL 3.0",  "namespace": "net.rptools.maptool.test-library",  "description": "My new test library for stuff",  "shortDescription": "test library",  "allowsUriAccess": true}

MTScript macros#

The name of the file becomes that macroname for [macro(): ] the namespace of the add-on library is used for the @ portion. For example:

Add-On libraries support both public and private macro functions. Public macro functions must reside in the mtscript/public and can be called from anywhere (chat, other add-ons, lib:tokens, macro buttons). You can call them using the following syntax [macro("[email protected]")] executes MTScript macro in the file content/mtscript/public/mtscript1.mts.

note

The "public/" is ommited from the macro name when calling it. You can also use subdirectories to organise your macros and would call them like [macro("subdir/[email protected]")]

The @this shorthand can also be used for calling a macro from within the same add-on, similar to how it works for lib:Tokens. For example [macro("mtscript2@this")]

Macro script files that are not in the "public/" directory can only be called from within the add-on itself. Given a library with the namespace net.mylib.addon with the following files.

mtsscript/func1.mtsmtsscript/public/func2.mts

[macro("[email protected]")] can be called from anywhere, but [macro("[email protected]")] can only be called from a macro that is on the net.mylib.addon add-on.

note

Since the "public/" is not required, if you have to files with the same name excluding the "public/" part, for example mtscript/public/funct1.mts mtscript/funct1.mts

Then only the one in public/ will be able to be executed, you will not be able to call the other macro

The above works not just with `[macro():] but the other places you would expect it to as well such as defineFunction() for user defined functions and macro links.

mts_properties.json file#

The mts_properties.json file contains property information about macro scripts, it is not required and currrently only allows you to set properties used in macro links.

{   "properties": [     {      "filename": "public/auto_exec.mts",      "autoExecute": true,      "description": "Auto executable macro link"    },    {      "filename": "public/myUDF.mts",      "description": "My Test UDF in a drop in lib."    }  ]}

Where

  • filename is the path of the file for the MacroScript function (excluding mtscript/).
  • autoExecute determines if a macro link created for this macro will be auto executable or not.
  • description is the description that will appear in the UDF listing, unlike Lib:Token this is just a plain string and not evaluated if it contains []

public/ directory#

The contents of this directory are exposed as a lib:// URI as long as the allowsUriAccess is set to true in the configuration file. The public directory part of the filename is discared, for example public/myhttml.html -> lib://net.myaddons.addon1/myhtml.html

You an add images to this directory and use src="lib://" in image tags in HTML. It will eventually work with audio (probably aleady does but I haven't tested it yet so not claining it will yet :) )

New MTScript functions#

  • library.listAddOnLibraries() Lists the add on libraries
  • library.getInfo(namespace) Gets information about a library (either add on or lib:token)
  • library.listTokenLibraries(namespace) Lists the Lib:tokens in the campaign
  • library.getContents(namespace) Lists the contents of a library (trusted)
  • library.removeAddOn(namepsace) Removes an add-on (trusted) (used for testing only, probably wont make it into release)
  • library.removeAllAddOns() Removes all add-ons (trusted) (used for testing only, probably wont make it into release)

Things not yet implemented but will be (so dont create issues for these or I will just close them)#

  • libProperty acces, including listing, setting, gettting
  • No UI yet
  • No onCampaignLoad etc events yet.
  • There is currenlty no way to access files not in public/ or mtscript/
  • Many file types like text/markdown etc are allowed in the library but the functions to use them dont yet exist
  • Expanding of JavaScript API which will make this much more useful will be part of another change.

路 5 min read

Issues with HTML/CSS/JavaScript Prior to MapTool 1.10#

Prior to MapTool 1.10 creating HTML pages is unnecessary cumbersome. To create HTML dialogs, frames, and overlays you use the following roll options.

  • [frame(): { } ]
  • [frame5(): { } ]
  • [dialog(): { } ]
  • [dialog5(): { } ]
  • [overlay(): { } ]

The HTML is included in the [ ] which means it has to processed by the MTScript parser. This has both benefits and drawbacks. The main benefit is that you can use [ ] to execute MTScript elements as a form of templating the HTML, for example

[frame("test): {    [r: getName() ]}]

The major drawback is that everything included must be able to pass through the MTScript parser, often this will not be the case especially where CSS or JavaScript are concerned. You can work around this problem by using macros functions to fetch text from macro, for example:

[frame5("test"): {    [r: getMacroCommand(number(getMacroIndexes("test/test.html"))) ]}]

Changes in MapTool 1.10#

In MapTool 1.10 there is a change that allows you to access properties and macros on Lib:Tokens via a URI of the form

  • lib://<token name>/macro/<macro name>
  • lib://<token name>/property/<property name>
note

By default the text fetched using the URI is cached, if you make changes to the content it will not be reflected until you restart MapTool. To work around this you can add the cachelib=false query string as show in examples later on in this post.

Where <token name> is the name of the Lib:Token after the Lib: prefix, for example Lib:HTMLTest would be HTMLTest

Allowing URI access#

There are no special requirements on ownership for the Lib:Token, to allow URI access to Lib:Token properties and macros, anyone will be able to access these values via a URI if the "Allow URI Access" flag needs is set, you can do this via the edit token dialog. Allow URI access

or the setAllowsURIAccess() macro function.

Reserved names
Some names are reserved for future internal usage and you will not be able set the "Allows URI Access" flags on Lib:Tokens
Reserved names are: Lib tokens with the following names (after the lib: part)
  • rptools
  • maptool
  • maptools (because people often call it maptools)
  • internal
  • builtin
  • standard
Lib tokens starting with the following names (after the lib: part)
  • rptools.
  • maptool.
  • maptools. (because people often call it maptools)
  • tokentool.
  • net.rptools.
  • internal.
  • _
  • builtin.
  • standard.
  • .

Macro functions#

Two new MTScript functions have been added that allow you to set or get the "Allows URI access" flag for a token. These can only be run from a trusted macro.

  • getAllowsURIAccess([<token name>], [<map name>])
  • setAllowsURIAccess(<0|1>, [<token name>, [<map name>])

Uses for lib:// URIs#

Lib:// URIs are useful for both CSS and JavaScript inclusion in HTML files, creating frames/dialogs/overlays with HTML, and the js.evalURI() MTScript functions.

Including JavaScript and CSS in HTML using a lib:// URI#

<html>  <head>    <link      rel="stylesheet"      href="lib://HTMLTest/macro/test/test.css?cachelib=false"    />  </head>  <body>    <h1>This is a test</h1>    <div id="test1" />    <script src="lib://HTMLTest/macro/test/test.js?cachelib=false"></script>    <img src="asset://87f4e9bfa4f1f3db250b57b3599fa4e9" />  </body></html>

This will include CSS from the macro called test/test.css and the JavaScript from a macro called test/test.js on the Lib:HTMLTest token.

Creating frames/dialogs/overlays using a lib:// URI#

There are also new MTScript functions that allow you to create frames/dialogs/overlays by passing a lib:// URI which contains the HTML. These are

  • html.dialog(<dialog name>, <libURI>, [<options>])
  • html.dialog5(<dialog name>, <libURI>, [<options>])
  • html.frame(<frame name>, <libURI>, [<options>])
  • html.frame5(<frame name>, <libURI>, [<options>])
  • html.overlay(<overlay name>, <libURI>, [<options>])

The optional "options" argument contains the same arguments and format as the frame/dialog/overlay roll options

Relative paths#

When using the following functions

  • html.dialog5(<dialog name>, <libURI>, [<options>])
  • html.frame5(<frame name>, <libURI>, [<options>])
  • html.overlay(<overlay name>, <libURI>, [<options>])

The URLs in the HTML file can also be specified using relative paths, for example Given

Relative paths macros

If the HTML is loaded from test/test.html you can use relative paths for the other macros as below

<html><head>    <link rel="stylesheet" href="./test.css?cachelib=false"></head><body>    <h1>This is a test</h1>    <div id='test1'/>    <script>        document.getElementById('test1').innerHTML = '...This is a test!';    </script>    <script src="./test.js?cachelib=false"></script>    <img src="asset://87f4e9bfa4f1f3db250b57b3599fa4e9"/>    <a href="./test2.html">test2</a></body>

This will even work for hyperlink navigation as seen in the link to ./test2.htlm aboove

Relative Path Navigation Example

Running JavaScript from a lib:// URI#

In addition to being able to include JavaScript in HTML via the <script> tag, lib:// URIs can be used to execute JavaScript via the js.evalUI()macro function.

  • js.evalURI(<namespace>, <libURI>, [arg1, ... argN])

Where

  • <namespace> is the namespace of the JavaScript context to run the script in.
  • <libURI> is the lib:// URI to fetch the JavasScript from.
  • [arg1, ... argN] is a comma-separated list of arguments to be passed to the script

路 7 min read

Authentication types#

Prior to version 1.10 MapTool only supported a single method of authentication which is role based authentication. Each Role (GM and Player) has a password and any client that connects and authenticates with either of these passwords gets that role. There is no restriction player names other than everyone has to have a unique name.

In MapTool 1.10 there are three authentication methods.

  • Role based
  • Player specific passwords
  • Public Key

Using Player Specific Authentication#

For player specific passwords and public keys authentication a password file must be used as these require that the name of the players are fixed so that they can be matched to the specific password or public key. When starting the server you can specify that a password file is used. Start Server Dialog

This will load the password file or create a new one if it doesn't exist.

Clients Connecting With Public Keys#

So that the user does not have to type in a password that will not be used they can check "connect using public Key" from the connect to server dialog.

Connect To Sever Dialog

They do not have to check this box as if the server requests the client attempts to authenticates via public key the client will do so even if the user has specified a password. If this value is checked the only way the client can authenticate is via public key so any password in the password text field will be ignored.

Adding, Editing, or Removing Players#

The menu option to edit player passwords is under the file menu. Player Database Menu Option

This opens the player database dialog which can be used to add, edit, and remove players. This dialog shows the following information

Player Database#

Edit Player Dialog

  • Player name
  • Role, Player or GM
  • Authentication Type, Password or Public Key
  • Is the player Blocked Blocked players will not be able to log in. When they try to connect they will get a message with a reason that they are blocked.
note

New, Added, or Modifications to players take effect immediately but the changes will not be written to the password file until this dialog is closed (either with Ok button or dialog close button). This is so that the file will not be continually overwritten many times when making several changes at once.

Adding or Editing Player#

Clicking on the Edit or Add button will open a dialog where you can provide the player details. Edit Player Dialog This dialog is used to provide the information required for the player database entry.

  • Player Name (only editable for Add)
  • Role, Player or GM
  • If the player has been blocked from logging in, and if so the reason why
  • Authentication Type, password or public key
  • Player Password (only if authentication type is password)
  • Public Key (only if authentication type is public key)

The password is hashed which is a one way operation, so you will not be able to see a players password so if you and the player forget it you will have to change it to a new one.

Its recommended that if you want to use player specific authentication you use public keys as that way neither you or the player will need to remember the password. You can add more than one public key in the public key text field so you can easily support players who have multiple computers.

If you still prefer to use a password over a public key it is strongly recommended you use the Generate New Password button so that no one is sharing passwords they may be using elsewhere.

note

Setting a plyer to blocked will not kick the player, it will only stop them from attempting to connect to the server. You will need to kick the player if you also want to remove them immediately. At this time kicking a blocked player will not send them the reason that they are blocked/kicked but will do so in a future version.

Obtaining The Players Public Key#

There is a new Authentication tab on the preferences dialog which contains the public key for your client. If you have multiple machines each will have its a different public key, its also possible if you have multiple versions installed with different data directories then these may also have different public keys.

Players Public Key

You can regenerate your public key but if you do so then you will not be able to connect to any server that has your old public key so you will need to ensure you let the person running the server know that your public key has been changed.

Your public key is also stored in the file .maptool-rptools/config/public.key (or equivalent data directory).

Warning: Your private key is also stored in this directory, do not share this with anyone as if they have both your public and private key they will be able to log in as you on other servers your public key is registered with.

Password File#

The location of the password file -- assuming the standard data directory -- is .maptool-rptools/config/passwords.json always ensure that you make a backup before editing it as if you make mistakes and you don't have a backup you may need to regenerate new passwords for all players. Also never update the password file while the server is running. Public keys for players are stored in the the .maptool-rptools/config/keys directory. If you use multiple computers or share GM duties with someone else you can copy the passwords.json file and keys directory and place them in the same directory on the second computer as they contain nothing specific to the computer it was generated on. You should still endeavour to make sure that this password file is shard with as little number of people as possible. Also never use passwords that you have used anywhere else in this file even though they are hashed. If you must use passwords use the button to generate new passwords, but you should prefer public keys!

Format of the Password File#

The password file uses json format.

  "passwords": [    {      "username": "p1",      "password": "/49vX2/i/5YhQZTaalYnoA",      "salt": "DZAp3sKZSY/vWuLfTG26mhQbOx5PLNT0tRdNvTNMn8KjDlY3jJg180ZBN56ehfkygOk6v0CgySZaufGkOKj7RqOwudzoWZhtNGSabkbI4s85TG7Ecfz8HQQRfIi1XtWrlqkrnuiyD8zQFg9zNr0xvQlUwzL5UOK7emt/xPr2QfU",      "role": "Player"    },    {      "username": "sp1",      "publicKeys": [        "pk1.key"      ],      "role": "Player"    },    {      "username": "g1",      "password": "9SH7OrqlXyRMrSXy2fQHaw",      "salt": "LOWXSGZ5tNeCwVpzNFuK/4EC+9jHMPmgpZ3Q05kElZyJKSWk0dGQOuZWADH2ZYAs4UvN3DVczMbAO6Dm5+NdnvsZsb/SnZ/xEM0QZ5yvmOh0bGjWEHwqTwFBbRUrzlpzy1nNKdJU8e7G2qWmaLUCDSV5Ut50l9aBfeL29d5btLA",      "role": "GM"    },    {      "username": "Test4",      "password": "ZyZpHxUR18RdhQpFk4n+jA",      "salt": "SucHGWjcbeDcegZo8A6jekB56iICulF3OtbcomJ+MsShuhKrrls2ZE+T25aTj/xAFu5wZlfE129LgBYvw/C3q2zeEyvjEmXprq5rzW8+c8VaXIRPSHbz5ursX5pRL8qcxbsCm4RFozld6R9/P6+IC3TC3DWoq6CRsvzHpIO2Nnc",      "role": "Player"    },    {      "username": "Test3",      "password": "EyFrs4pM6Euy5zQLHrFoOw",      "salt": "Fpvg/PJZGIp7N68OmxMaEGOA1mo4vdg7KoRUDik3Q6P6VovI0YOOdNi3iyo9WgcuukhXjlSoxBqG3Cz/hNQRVVgsXdGwcb86K20imFBbfyzpuNt3a/51u9HTQuYoE8FzzNsTdCI/VPmyQjgvP+AwSYT0i7m/GRXdtugoOWGnDgY",      "role": "Player"    }  ]}

A player entry that uses a public key will look like the following

    {      "username": "sp1",      "publicKeys": [        "pk1.key"      ],      "role": "Player"    }

The value in publicKeys is the name of the file in the keys directory that contains the public keys for the player.

A player entery that uses a password will look like the following

    {      "username": "Test3",      "password": "EyFrs4pM6Euy5zQLHrFoOw",      "salt": "Fpvg/PJZGIp7N68OmxMaEGOA1mo4vdg7KoRUDik3Q6P6VovI0YOOdNi3iyo9WgcuukhXjlSoxBqG3Cz/hNQRVVgsXdGwcb86K20imFBbfyzpuNt3a/51u9HTQuYoE8FzzNsTdCI/VPmyQjgvP+AwSYT0i7m/GRXdtugoOWGnDgY",      "role": "Player"    }

The password field contains the hashed password for the player, the salt field is a randomised value that is used in the function used hash the password.

If you want to add players you will not be able to -- or be expected to -- generate the hashed password and salt instead you can instead specify the plaintext password and no salt like the following.

    {      "username": "Test3",      "password": "You-Are-Using-A-Random-Password-Arent-You?",      "role": "Player"    }

Then the next time the server is started this file will be read and the password will be hashed and the file overwritten to only contain hashed passwords and the salt for the password. This will also generate a passwords.json.backup before overwriting, ensure that you delete this file after testing as it contains then non hashed version of the passwords. But you did remember to use randome passwords and not passwords that you use elsehwere correct?

路 3 min read

Callouts#

One of the new additions in MapTool 1.10 is the ability to override the name that appears in the speech or thought bubble callouts in MapTool.

For those that are not already familiar with the functionality MapTool provides the ability to display the following callouts on all clients

  • Pointer - Spacebar
    Pointer

  • Speech Bubble - Control + Spacebar
    Speech Bubble

  • Thought Bubble - Shift + Spacebar
    Thought Bubble

  • Pointing Finger - Control + Shift + Spacebar
    Pointing Finger

Setting the Speech/Thought Callout Name#

Previously these callouts always render the name of the player regardless of where the callout is or impersonation status. In MapTool 1.10 tokens can have a speech name, this can affect the name displayed for both thought and speech bubbles when the mouse pointer is over the token, or the token is impersonated.

This can be set when dragging a new token on to the map
New Token Dialog

Or by editing existing tokens. Edit Token Dialog

Or via macro.
setSpeechName("Speech bubble name", tokenId)

Related Macros#

There are two related macros getSpeechName() which returns the speech name for the current token. There is also a trusted variant getSpeechName(tokenId) which will return the speech name for the token with the specified id.

setSpeechName(SpeechBubbleName) sets the speech name for the current token. There is also a trusted variant setSpeechName(SpeechBubbleName, tokenId) which will set the speech name for the token with the specified id.

Examples#

In the following examples the speech and thought bubbles look different to previous versions as another fix in MapTool 1.10 is to size them dynamically so large names wont be rendered outside of the bubbles.

No impersonated token or token under mouse No Token

Token with Speech Name Token With Speech Name

Token with really long speech name Really Long Name

Both the eagle and the Dragon have a speech name Impersonated

Mage and Familiar with Speech Name, mouse over Mage Mage

Mage and Familiar with Speech Name, mouse over Familiar Mage

Determining which name is displayed#

In general when deciding which name to use in speech and thought bubbles MapTool will attempt to show the name associated with the following precedence

  1. Token under the mouse with speech name(if player owns it or is GM)
  2. Impersonated Token with speech name
  3. The players name

Below is a more detailed overview of the logic if you really want to know what it is.

flowchart TD; Start([Start]) --> mouseOver{Mouse Over<br/>Token} --> |Yes| isOwner{Player Owns} mouseOver --> |No| impersonated isOwner --> |No| impersonated{Token<br/> Impersonated?} isOwner --> |Yes| hasSpeechName{Has Speech<br/> Name} hasSpeechName --> |Yes| speechName[Use Token<br/>Speech Bubble Name] hasSpeechName --> |No| impersonated impersonated --> |No| playerName[Use Player Name] impersonated --> |Yes| impersonatedHasSpeech{Token Has<br/>Speech Name?} impersonatedHasSpeech --> |Yes| impersonatedSpeech[Use Impersonated<br/>Token Speech Name] impersonatedHasSpeech --> |No| playerName

If there are multiple tokens under the mouse (e.g. a Token Stack) and at least one has a speech name then the following logic will be used to determine which is used.

flowchart TD; Start([Start]) --> hasImpersonated{Token<br/> Impersonated?} hasImpersonated --> |Yes| impersonatedUnder{Impersonated Token<br/>in Stack?} impersonatedUnder --> |Yes| useImpersonated[Use Impersonated<br/>Token Speech Name] impersonatedUnder --> |No| topHasSpeech hasImpersonated --> |No| topHasSpeech{Top Token<br/>Has Speech Name?} topHasSpeech --> |Yes| useTop[Use Top Token<br/>Speech Name] topHasSpeech --> |No| useOther[Use Any Token<br/>in Stack<br/>Speech Name]