Node Delivery Service
There are different ways of moving nodes from one Area Server to another.
The primary method is when root nodes are moved, such as when a character root node travels to a different Area, and all of its children nodes move with it. In that situation, travel is requested via the $TRAVEL system node.
The other method, is via the Node Delivery Service. This system is only for moving non-root nodes. For example, moving a backpack with all of its attached inventory, would use the Node Delivery Service.
How Nodes are moved
When using this system, there are a series of steps that take place. To describe these steps, consider the example of a player (Mickey) who has a backpack with various items in it. It is desired to remove the backpack from Mickey, and give it to Minnie, who is in a different Area.
- A destination mailbox must be declared. In this case, Minnie is the destination mailbox.
- The backpack is detached from Mickey, and sent in the direction of the Minnie mailbox.
- The backpack arrives in the Minnie mailbox, but Minnie doesn't know it yet.
- Minnie checks her mailbox, to see if anything has arrived. It tells her the node ID of the backpack
- Once the contents of her mailbox arrives, Minnie can then manipulate the backpack (such as placing it in her inventory).
- She then has access to the backpack, and all of its contents.
Nodes are loaded into an Area Server from the database. In order to prevent situations where a certain node might be loaded in twice, each node is linked by a single hard association to a parent node, which has a hard association to its own parent node, and all the way to a very specific class of nodes called Root Nodes. When nodes are loaded into the Area, they always start with the Root Node, and then work through the subnodes in that Root Node's hierarchy. This prevents conflicting situations where a certain node might be loaded into the Area twice.
There are three kinds of Root Nodes:
Sometimes, however, it is desired to transfer a sub-hierarchy of nodes from one root node hierarchy to another. If both root nodes are in the same local GOM, this transfer process is very simple. The sub-hierarchy simply breaks its hard association with one root node, and attaches itself to another.
The transfer process is very simple when both hierarchies are loaded into memory in the same local GOM. A simple removal of one association and addition of the new association will implement the transfer.
Where complications arise, is when nodes are transferred from a loaded hierarchy to a hierarchy that is in a non-local GOM, where it might be loaded *or* unloaded.
The GOM Mailbox system provides a storage area for node sub-hierarchies that are in the process of moving from one root to another. Five functions are exposed to the HSL scripts to allow for these transferrals:
Two rules have been introduced to simplify the use of these functions.
- The first rule is that a node must be registered as having a mailbox before is it valid to send mail to the mailbox. Without this rule, any node might be the target of mail, so all nodes would have to poll for mail, and it would be very likely that mail would not be handled properly in all cases.
- The second rule is that only persistent nodes are valid nodes for registering mailboxes and being sent as mail. This rule exists because the implementation of the mailboxes will be partially in the database, and it is not possible to keep track of non-persistent nodes in the database.
Note: Care must be taken to ensure that the transfer does not leave any sub-nodes in an orphaned state.
Create Mailbox for Node
external function CreateMailboxForNode(theNode as NodeRef) as Boolean
This function creates a mailbox for the given node, allowing it to be a valid target to send mail to. It will return true if everything is successful, or if the node already had a mailbox created for it. If the node is not persistent, a Script Error will be thrown.
Remove Mailbox for Node
external function RemoveMailboxForNode(theNode as NodeRef) as Boolean
This function removes a mailbox for the given node, if it existed. It returns true if the mailbox did not exist, or existed and was successfully removed. It returns false if the mailbox contained outstanding mail and the mailbox was not removed. If the node passed in is not persistent, a Script Error will be thrown.
external function SendMail(destinationNode as ID, package as NodeRef, package_title as String ) as Boolean
The package node and all its hard associated children will be unloaded from the local GOM and placed as mail in the destinationNode's mailbox. If the package node is not persistent, a Script Error will be thrown and the package will not be deleted. If the package is of a class that is a well known root type, such as AreaRoot or _PlayerAccount, a Script Error will be thrown and the package will not be unloaded. If any of the package node's children are not persistent, they will be deleted. If the destinationNode is not a valid mailbox, the function will return False without modifying the package. If all goes well, True will be returned. Package_title is seen with CheckMail, and has a maximum length of 250 characters.
external function CheckMail(mailboxNode as NodeRef) as List of Class MailInfo
This function will throw a Script Error if mailboxNode is not a valid mailbox. A list of the nodes currently in the mailbox will be returned. If there is no outstanding mail, the list will be empty.
The MailInfo class contains 3 fields, MailNode, MailTitle, and MailClass. They contain the id of the node that was mailed, the text of the title sent when the node was mailed, and the base class of the mailed node as a string.
external function GetMail(mailboxNode as NodeRef, attachNode as NodeRef, mailNode as ID)
A Script Error will be thrown if mailboxNode is not a valid mailbox, if attachNode is not a valid Node Ref, or if mailNode is not the id of an outstanding mail node. This function loads the given mail node sub-hierarchy and attaches it as a child of attachNode with the base_hard_association.
All these exposed functions are synchronous calls to the database. As such, they may take much longer than the average exposed function call. These functions also require the mailbox nodes to be persistent. A problem may exist with transferring nodes to a non-edit instance, since all nodes in a non-edit instance are non-persistent nodes. However, at this time there is no need being forecast for that possibility, since the main usage of the mail system will be to mail nodes between player nodes, or from the system to player nodes, and player nodes are always persistent. Please see Node Persistence for more information.