This is the high-level interface to the system. At this point, it's not intended to be a replacement for the low-level interface, but rather just a set of convenient functions that work when they do what you want. In the future, this module may grow into a general-purpose replacement to the low-level interface.
- login :: String -> String -> String -> IO Circuit
- sendAgentThrottle :: Circuit -> Float -> Float -> Float -> Float -> Float -> Float -> Float -> IO ()
- botThrottle :: Circuit -> IO ()
- sendAgentUpdate :: Circuit -> IO ()
- agentName2Key :: Circuit -> String -> String -> IO (Maybe UUID)
- agentKey2Name :: Circuit -> UUID -> IO (Maybe (String, String))
- groupKey2Name :: Circuit -> UUID -> IO (Maybe String)
- sendSimpleIM :: Circuit -> UUID -> String -> IO Bool
- data ChatMethod
- sendChat :: Circuit -> Int -> ChatMethod -> String -> IO Bool
- whisper :: Circuit -> String -> IO Bool
- say :: Circuit -> String -> IO Bool
- shout :: Circuit -> String -> IO Bool
- getGroupRoles :: Circuit -> UUID -> IO (Maybe [(String, UUID)])
- getGroupMembers :: Circuit -> UUID -> IO (Maybe [UUID])
- addGroupRole :: Circuit -> UUID -> UUID -> UUID -> IO ()
- delGroupRole :: Circuit -> UUID -> UUID -> UUID -> IO ()
- inviteToGroup :: Circuit -> UUID -> UUID -> UUID -> IO ()
- acceptGroupInvite :: Circuit -> UUID -> UUID -> IO ()
- acceptFriendship :: Circuit -> UUID -> IO ()
- giveMoney :: Circuit -> UUID -> Int -> IO ()
- getBalance :: Circuit -> IO (Maybe Int)
- estateBan :: Circuit -> UUID -> IO ()
- estateUnban :: Circuit -> UUID -> IO ()
- setTerrainVariables :: Circuit -> Float -> Float -> Float -> Bool -> Bool -> Float -> IO ()
- handlePackets :: Chan (Maybe PacketBody) -> (PacketBody -> IO (Maybe a)) -> IO (Maybe a)
- handlePackets_ :: Chan (Maybe PacketBody) -> (PacketBody -> IO ()) -> IO ()
- expectResponse :: Circuit -> PacketBody -> (PacketBody -> IO (Maybe a)) -> IO (Maybe a)
- bytesToString :: ByteString -> String
- stringToBytes :: String -> ByteString
- module Network.Metaverse.Circuit
- module Network.Metaverse.PacketTypes
Connecting to the simulator
Logging in to a simulator is done with login
. The result is a Circuit
,
which is then passed to the other functions in this module. The low-level
module Network.Metaverse.Circuit also contains functions for managing
circuits.
While open, a circuit will automatically attempt to keep the connection open by acknowledging packets, responding to pings, and so forth.
Logs in to a Second Life simulator being tunneled through port 8001 on localhost. Tunneling is very important, as we don't use SSL here, but Second Life requires it.
:: Circuit | The circuit to operate in |
-> Float | Limit on resent reliable packets |
-> Float | Limit on land shapes and terraforming |
-> Float | Limit on wind speeds and directions |
-> Float | Limit on cloud locations |
-> Float | Limit on tasks such as agents or scripts |
-> Float | Limit on texture data downloads |
-> Float | Limit on asset data from inventory |
-> IO () |
Sends a message requesting the throttling of certain kinds of data from the server. This can be used to save some network bandwidth and processing time.
Limits bandwidths in a sensible way for a bot: that is, a non-graphical viewer that does not need to render the scene.
Sends an agent update message to the sim. This message updates the sim on the agent's idea of its current location, direction it is facing, etc. These are not sent automatically, and not sending them will tend to make the agent non-physical. However, they are not required to remain logged in, so some bots may not wish to bother with them.
Name/key conversion
:: Circuit | The circuit to operate in |
-> String | First name of the target avatar |
-> String | Last name of the target avatar |
-> IO (Maybe UUID) |
Converts an agent name to a key, by searching in the directory and looking for a matching agent.
:: Circuit | The circuit to operate in |
-> UUID | The key for which to look up a name |
-> IO (Maybe (String, String)) |
Converts an agent key to a matching first and last name.
Converts a group key to a matching group name.
Communicating
These provide a very simple set of functions for sending communications to other people in the sim. In general, receiving communication must be handled with the low-level interface at this time.
:: Circuit | The circuit to operate in |
-> UUID | The UUID of the intended recipient |
-> String | The message to send |
-> IO Bool |
Sends an instant message (IM) to another avatar. Waits for the sim to acknowledge receipt of the message, and returns True if it was received, or False if the message could not be sent.
data ChatMethod Source
A method of speaking. This controls the distance within which other tasks and avatars will hear the communication. Other avatar's clients will also typically display an indication if a communication is a whisper or shout.
Sends a whisper to normal chat.
Sends an ordinary message to normal chat.
Sends a shout to normal chat.
Group management
:: Circuit | The circuit to operate in |
-> UUID | UUID of the group to ask about |
-> IO (Maybe [(String, UUID)]) |
Retrieves a list of role names and their UUIDs in a group. Returns Nothing if such a list is not available (generally because the request could not be sent, or the circuit was closed before a reply was received.
Retrieves a list of members in a group. Returns Nothing if such a list is not available (generally because the request could not be sent, or the circuit was closed before a reply was received.
:: Circuit | The circuit to operate in |
-> UUID | UUID of the group in which to act |
-> UUID | UUID of the group member to act on |
-> UUID | UUID of the role to add |
-> IO () |
Adds a group member to a role. The member must already belong to the group.
:: Circuit | The circuit to operate in |
-> UUID | UUID of the group in which to act |
-> UUID | UUID of the group member to act on |
-> UUID | UUID of the role to delete |
-> IO () |
Removes a group member from a role. If the group member is not in that role or the group, has no effect.
:: Circuit | The circuit to operate in |
-> UUID | UUID of the group to which to invite |
-> UUID | UUID of the avatar to invite |
-> UUID | UUID of the role to invite to. The zero UUID is always the Everyone role. |
-> IO () |
Invites an avatar to join a group.
:: Circuit | The circuit to operate in |
-> UUID | UUID of the group to join |
-> UUID | UUID of the invitation we are accepting |
-> IO () |
Accepts a group invitation sent to this avatar. This requires a UUID for
the invitation, which is normally obtained from the
ImprovedInstantMessage
packet carrying the group invitation.
Note that if the invitation had a cost associated, then accepting it will cost money, so be careful about automatically accepting invitations.
Miscellaneous
Accepts a friendship offer from another avatar. This requires having a
UUID for the offer, usually obtained from the ImprovedInstantMessage
packet bearing the friendship offer.
Pays money to another avatar.
Requests this avatar's current balance of virtual currency. If the
balance is not available or the circuit is closed before it is received,
the result is Nothing
.
Bans a given avatar from the current estate. This requires that the avatar logged in on the circuit be an estate manager for the estate.
Unbans a given avatar from the current estate. This requires that the avatar logged in on the circuit be an estate manager for the estate.
:: Circuit | The circuit to operate in |
-> Float | Height of water, in meters |
-> Float | Limit for raising terrain |
-> Float | Limit for lowering terrain |
-> Bool | Use estate sun |
-> Bool | Use fixed sun |
-> Float | Sun position |
-> IO () |
Sets variables that control region terrain.
Low-level adapters
These functions provide a bridge from the high-level interface in this module to the low-level interface in some other modules. You can use these to define your own wrappers for parts of the protocol that don't yet have them.
:: Chan (Maybe PacketBody) | Channel to ask for packets |
-> (PacketBody -> IO (Maybe a)) | Handler for packets |
-> IO (Maybe a) |
Captures the general pattern of handling packets from a circuit channel
such as circuitIncoming
or a duplicate. The handler should return
Nothing
to continue processing packets, or Just
x
to finish with a
result of x
. If the circuit is closed before a Just
value is returned,
then the result of handlePackets
is Nothing
.
:: Chan (Maybe PacketBody) | Channel to ask for packets |
-> (PacketBody -> IO ()) | Handler for packets |
-> IO () |
A version of handlePackets for handlers that don't finish early. This will keep retrieving packets from the given channel and passing them off to the handler until the circuit is closed.
:: Circuit | The circuit to operate on |
-> PacketBody | The request packet to send |
-> (PacketBody -> IO (Maybe a)) | The handler for responses |
-> IO (Maybe a) |
Sends a packet, and expects another packet (or packets) in response. This
is a common pattern for many kinds of communication. It's implemented by
duplicating circuitIncoming
so that we can look ahead for responses while
still leaving other packets for independent tasks.
The handler should return Nothing
when the packet it received was not
the response it expected (or did not complete the response), and a Just
value when the response is complete. In turn, expectResponse
returns
Nothing
if the circuit is closed before the response is complete, and
a Just
value once the response is complete.
bytesToString :: ByteString -> StringSource
Converts a sequence of bytes in the form used for packets into a Haskell String.
stringToBytes :: String -> ByteStringSource
Converts a Haskell String into a sequence of bytes suitable to send in a packet.
module Network.Metaverse.Circuit