Rooms
packets9 packets
Rooms: joining one, and what the server says about it. Layouts are read from room/RoomXtCommManager.as and com/sbi/client/SFClient.as in the decompiled client (deploy 1829). Who is in a room arrives as avatar.joined and avatar.left (catalog/avatar.ts).
Hearing and sending packets
What the game sends is heard on phantom.packets.client, and what the server sends on phantom.packets.server. watch hears a packet after it has gone through; on hears it first and may change or drop it; send sends one to that end. See Packets.
Overview
| Packet | Command | Way | What it is |
|---|---|---|---|
RoomJoinRequest | rj | game → server | The player asks to join a room. |
RoomJoinResult | rj | server → game | The server says whether the player joined, and describes the room. |
RoomJoinRefused | rj | server → game | The server refuses a join, saying what about. |
RoomProperties | rp | server → game | The server says which room to load, and how. |
RoomLeaveRequest | rl | game → server | The player leaves an in room game’s room. |
RoomList | rl | server → game | The server lists the rooms the client knows. |
RoomListFromServer | rmList | server → game | SmartFox lists every room on the world as the connection opens. |
FirstFiveMinutesRoomRequest | rf | game → server | The player asks for their first five minutes room. |
FirstFiveMinutesRoom | rf | server → game | The server says whether the first five minutes room is ready. |
RoomJoinRequest
Asks to join a room (RoomXtCommManager.sendRoomJoinRequest): by name, such as jamaa_township.room_main, or by id.
Fields
| Field | Type | |
|---|---|---|
target | string | The room to join: its name, such as jamaa_township.room_main, or its id as text. |
confirmLanguageChange | boolean | The player has agreed to join a room in another language, so the client may load that language's pack (sendRoomJoinRequest's confirmLanguageChange). |
invisible | boolean | Join without being seen (sendRoomJoinRequest's forceInvisMode). |
joinType | string | How the server should place the player, from room.RoomJoinType (AUTO, DIRECT_JOIN_AND_HALT_ON_FAILURE or DIRECT_JOIN_AND_SEARCH_ON_FAILURE), sent as text. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the game sends it to the server, after it has gone through.
const stop = phantom.packets.client.watch(packets.RoomJoinRequest, (packet) => {
console.log(packet.target, packet.confirmLanguageChange, packet.invisible);
});RoomJoinResult
The server's answer to a join (RoomXtCommManager.roomJoinResponse). A successful join describes the room in joinedRoom (the packet's own room is the one the message was sent in) and the player's state in details. A message that ends right after the room, as short test messages do, reads with details null rather than failing.
Fields
| Field | Type | |
|---|---|---|
joined | boolean | The player joined the room. |
joinedRoom | JoinedRoom | null | The room joined, or null when the join failed. |
details | RoomJoinDetails | null | The rest of a successful join, or null when the message ends after the room. |
error | string | null | Why a join failed: N when the room is on another server node (the node follows in extra), BSJ, SSJ, CSJ, QSJL, RQJF and the like for the popups the client shows, or the text SFClient.handleRoomJoinError gets. Null on success. |
extra | string[] | Whatever follows, as it came. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the server sends it to the game, after it has gone through.
const stop = phantom.packets.server.watch(packets.RoomJoinResult, (packet) => {
console.log(packet.joined, packet.joinedRoom, packet.details);
});RoomJoinRefused
A join refused with what the refusal is about, the one field roomJoinResponse reads after the error: the node the room is on for N (the client signs in there and joins again), or what SFClient.handleRoomJoinError is given beside the error, such as the den's owner for a den refusal (DEN_JOIN_REFUSAL). A variant of room.join-result, which reads every rj:
%xt%rj%<room>%0%<error>%<subject>%
Fields
| Field | Type | |
|---|---|---|
error | string | Why, as room.join-result's error. |
subject | string | What it is about: the node's address for N, the den's owner for a den refusal. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the server sends it to the game, after it has gone through.
const stop = phantom.packets.server.watch(packets.RoomJoinRefused, (packet) => {
console.log(packet.error, packet.subject);
});RoomProperties
What to load for the room just joined (RoomXtCommManager.roomPropertiesResponse, passed on to RoomManagerWorld.loadRoom). The client may hold it until a language pack loads.
Fields
| Field | Type | |
|---|---|---|
pathName | string | The room's asset path, such as jamaa_township.room_main. |
environmentType | number | Land, ocean or both (AvatarManager.roomEnviroType). |
roomType | number | clientInfo.roomType: 2 for a den, 5 for a party, 7 for an adventure. |
secondaryDefId | number | clientInfo.secondaryDefId: the party's or den's own def, where the room type has one. |
zoom | number | How far the room is zoomed, as a percentage: 100 for the client's normal view. |
roomDefId | number | The room's def id, which the client looks up in its room defs. |
customData | string | null | JSON the client parses into clientInfo.customRoomData, or null when the message ends. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the server sends it to the game, after it has gone through.
const stop = phantom.packets.server.watch(packets.RoomProperties, (packet) => {
console.log(packet.pathName, packet.environmentType, packet.roomType);
});RoomLeaveRequest
Leaves a room inside the room, such as an in room game (RoomXtCommManager.sendRoomLeaveRequest, called only by MinigameManager). The message is sent in the sub room. A normal room is never left this way: joining another room leaves it.
Fields
| Field | Type | |
|---|---|---|
roomId | number | The id of the sub room to leave. The message is sent in that room too. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the game sends it to the server, after it has gone through.
const stop = phantom.packets.client.watch(packets.RoomLeaveRequest, (packet) => {
console.log(packet.roomId);
});RoomList
The rooms the client should know (RoomXtCommManager.roomListResponse, read by SFClient.setRoomList). The client treats the first as the limbo room.
Fields
| Field | Type | |
|---|---|---|
rooms | ListedRoom[] | The rooms, after their count. The first is the limbo room. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the server sends it to the game, after it has gone through.
const stop = phantom.packets.server.watch(packets.RoomList, (packet) => {
console.log(packet.rooms);
});RoomListFromServer
The same rooms, as SmartFox's own handshake sends them (handlers/SysHandler reading rmList into SmartFoxClient.setRoomList):
<msg t='sys'><body action='rmList' r='-1'> <rm id='2' priv='0' temp='0' game='0' ucnt='41' maxu='60' maxs='0'><n><![CDATA[jamaa_township]]></n></rm> ... </body></msg>
This is the one that arrives. The extension rl above is a reply to a request, and nothing in the client ever asks: the list a player's session actually gets is this one, sent once as the connection opens, holding every room on their world. A reader watching only room.list sees nothing on an ordinary session, which is what left phantom.world.rooms empty for good.
priv and lmb are SmartFox's own and the client reads them; neither is kept here, since the fields are the ones a ListedRoom has and the limbo room is the first either way.
Fields
| Field | Type | |
|---|---|---|
rooms | ListedRoom[] | The rooms, in the order the server wrote them. The first is the limbo room. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the server sends it to the game, after it has gone through.
const stop = phantom.packets.server.watch(packets.RoomListFromServer, (packet) => {
console.log(packet.rooms);
});FirstFiveMinutesRoomRequest
Asks the server to make the player's first five minutes room ready (RoomXtCommManager.sendRoomFFMRequest), the new player's walk through Jamaa. Its one caller, GuiManager.startFFM, asks only when the player is in no room yet, and joins ffm<userName> once the answer says the room is ready.
Fields
| Field | Type | |
|---|---|---|
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the game sends it to the server, after it has gone through.
const stop = phantom.packets.client.watch(packets.FirstFiveMinutesRoomRequest, (packet) => {
console.log('room.ffm-request');
});FirstFiveMinutesRoom
Whether the player's first five minutes room is ready (RoomXtCommManager.roomFFMResponse): the client runs its callback, which joins ffm<userName>, only when the first argument is 1.
Fields
| Field | Type | |
|---|---|---|
ready | boolean | The room is ready to join: the first argument is 1, the only answer the client acts on. |
extra | string[] | Whatever follows, as it came. |
room | number | The room the message was sent in, as the SmartFox room id; -1 when it names none. |
Example
// Each time the server sends it to the game, after it has gone through.
const stop = phantom.packets.server.watch(packets.FirstFiveMinutesRoom, (packet) => {
console.log(packet.ready, packet.extra);
});