Dbserver-to-mapserver: Difference between revisions

From OuroDev
Asuffield (talk | contribs)
Asuffield (talk | contribs)
 
(42 intermediate revisions by the same user not shown)
Line 14: Line 14:


Otherwise, dbserver sends these commands back to the MapServer:
Otherwise, dbserver sends these commands back to the MapServer:
 
* [[#DBSERVER_TIMEOFFSET|DBSERVER_TIMEOFFSET]] is sent with values based on the system clock.
DBSERVER_TIMEOFFSET:
* [[#DBSERVER_OVERRIDDEN_AUTHBITS|DBSERVER_OVERRIDDEN_AUTHBITS]] is sent based on OverrideAuthBit lines in servers.cfg.
bits(32) seconds_since_2000
* For each DisabledZoneEvents line in servers.cfg, dbserver sends one [[#DBSERVER_DISABLED_ZONE_EVENTS|DBSERVER_DISABLED_ZONE_EVENTS]].
float32 time_zone_delta
* If user reactivation is active, dbserver sends a [[#DBSERVER_NOTIFY_REACTIVATION|DBSERVER_NOTIFY_REACTIVATION]].
 
* [[#DBSERVER_UPDATE_LOG_LEVELS|DBSERVER_UPDATE_LOG_LEVELS]] is sent based on SetLogLevel lines in servers.cfg.
These values are set based on the system clock. ''time_zone_delta'' is the difference between UTC and local time, in hours.
* [[#DBSERVER_ACCOUNTSERVER_CATALOG|DBSERVER_ACCOUNTSERVER_CATALOG]] is sent based on account_server.cfg.
 
DBSERVER_OVERRIDDEN_AUTHBITS
bits(1024) overridden_auth_bits
 
The value of ''overridden_auth_bits'' is set based on OverrideAuthBit lines in servers.cfg.
 
If any DisabledZoneEvents entries are present in servers.cfg, dbserver sends a DBSERVER_DISABLED_ZONE_EVENTS command:
repeated string event
 
One entry for each DisabledZoneEvents line in servers.cfg
 
If user reactivation is active, dbserver sends a DBSERVER_NOTIFY_REACTIVATION message, with no body.
 
DBSERVER_UPDATE_LOG_LEVELS:
repeated LOG_LEVELS times:
  packint(1) log_level
 
These are the log levels, as managed by log.h, for all logging types in order from 0 to LOG_LEVELS. They are set in servers.cfg with SetLogLevel lines.
 
DBSERVER_ACCOUNTSERVER_CATALOG:
autobits catalog_timestamp
autobits auth_timeout
string mtx_environment
string play_span_domain
string play_span_url_home
string play_span_url_categoryview
string play_span_url_itemview
string play_span_url_showcart
string play_span_url_addtocart
string play_span_url_manageaccount
string play_span_url_supportpage
string play_span_url_supportpage_de
string play_span_url_supportpage_fr
string play_span_url_updatetovip
string coh_url_newfeatures
string coh_url_newfeaturesupdate
autobits play_span_store_flags
 
These appear to be values set in account_server.cfg. Most of them are URLs.


== DBCLIENT_READY ==
== DBCLIENT_READY ==
Line 126: Line 87:
  packint(1) map_id
  packint(1) map_id


This message is sent by MapServer when it has finished settup in the map. It marks the MapCon as not starting. If the MapCon has been marked for shutdown in the dbserver, then the dbserver will respond with an empty DBSERVER_TEAM_LEFT_MISSION message.
This message is sent by MapServer when it has finished settup in the map. It marks the MapCon as not starting. If the MapCon has been marked for shutdown in the dbserver, then the dbserver will respond with an empty [[#DBSERVER_TEAM_LEFT_MISSION|DBSERVER_TEAM_LEFT_MISSION]] message.


== DBCLIENT_CONTAINER_INFO ==
== DBCLIENT_CONTAINER_INFO ==
Line 175: Line 136:
''debugdiff_str'' is only sent when debugdiff is not 0, otherwise it is skipped
''debugdiff_str'' is only sent when debugdiff is not 0, otherwise it is skipped


dbserver stores the containers, and responds with DBSERVER_CONTAINER_ACK to most messages:
dbserver stores the containers, and responds with [[#DBSERVER_CONTAINER_ACK|DBSERVER_CONTAINER_ACK]] to most messages. The ''ack_id'' values will be the ''container_id'' values that were updated.
packint(1) list_id
packint(1) callback_id
packint(1) count
repeated count times:
  packint(1) ack_id
 
The ''ack_id'' values will be the ''container_id'' values that were updated.


One DBSERVER_CONTAINER_ACK response is sent after '''every''' update is applied, containing all acks so far (this appears to be a bug, and not used for anything). Acks are used by MapServer to return the container_id when creating containers, and otherwise ignored.
One DBSERVER_CONTAINER_ACK response is sent after '''every''' update is applied, containing all acks so far (this appears to be a bug, and not used for anything). Acks are used by MapServer to return the container_id when creating containers, and otherwise ignored.
Line 207: Line 161:
All other values of ''cmd'' will apply the update to an existing container.
All other values of ''cmd'' will apply the update to an existing container.


If an error occurs, dbserver will abandon processing of the rest of the message, and respond with DBSERVER_CLIENT_CMD_FAILED:
If an error occurs, dbserver will abandon processing of the rest of the message, and respond with [[#DBSERVER_CLIENT_CMD_FAILED|DBSERVER_CLIENT_CMD_FAILED]]. This occurs in the following scenarios:
  packint(1) fail_code
  string str
 
This occurs in the following scenarios:
* ''id'' is -1 for commands other than CREATE and CREATE_MODIFY, or ''id'' being any value other than -1 for CREATE, will return CONTAINER_ERR_DOESNT_EXIST
* ''id'' is -1 for commands other than CREATE and CREATE_MODIFY, or ''id'' being any value other than -1 for CREATE, will return CONTAINER_ERR_DOESNT_EXIST
* Parse errors for the container in ''str'' will return CONTAINER_ERR_CANT_COMPLETE_SERIOUS
* Parse errors for the container in ''str'' will return CONTAINER_ERR_CANT_COMPLETE_SERIOUS
Line 255: Line 205:
  ... more data that dbserver does not parse
  ... more data that dbserver does not parse


If ''list_id'' is not recognised, or no server has that DbList locked, then dbserver will respond with DBSERVER_CONTAINER_RECEIPT:
If ''list_id'' is not recognised, or no server has that DbList locked, then dbserver will respond with [[#DBSERVER_CONTAINER_RECEIPT|DBSERVER_CONTAINER_RECEIPT]], where ''error_code'' will be CONTAINER_ERR_CANT_COMPLETE.
packint(1) cmd
packint(1) list_id
packint(1) cid
packint(1) user_cmd
packint(1) user_data
packint(1) error_code
string error_msg
 
where ''error_code'' will be CONTAINER_ERR_CANT_COMPLETE.


Otherwise, dbserver will forward the message to the server which has locked that DbList, as DBSERVER_CONTAINER_RELAY:
Otherwise, dbserver will forward the message to the server which has locked that DbList, as [[#DBSERVER_CONTAINER_RELAY|DBSERVER_CONTAINER_RELAY]].
packint(1) cmd
packint(1) list_id
packint(1) cid
packint(1) user_cmd
packint(1) user_data
packint(1) lock_id
... everything else from the DBCLIENT_CONTAINER_RELAY is copied here


This is used for MapServer to send messages to RaidServer.
This is used for MapServer to send messages to RaidServer.
Line 346: Line 280:
If the map is instanced or static, a MapServer will be started for it.
If the map is instanced or static, a MapServer will be started for it.


The entity ''entity_id'' will be added to the list of entities waiting for this map, and when that MapServer is ready (possibly immediately), dbserver will send DBSERVER_MAP_XFER_READY to the MapServer which send the transfer request:
The entity ''entity_id'' will be added to the list of entities waiting for this map, and when that MapServer is ready (possibly immediately), dbserver will send [[#DBSERVER_MAP_XFER_READY|DBSERVER_MAP_XFER_READY]] to the MapServer which sent the transfer request.
packint(1) entity_id
 
packint(1) new_map_id
MapServer sends this message to dbserver in order to begin the map transfer process.


== DBCLIENT_MAP_XFER ==
== DBCLIENT_MAP_XFER ==
Line 360: Line 294:
dbserver might override map_id to a different value in some scenarios (relating to Praetorian progression).
dbserver might override map_id to a different value in some scenarios (relating to Praetorian progression).


If the map_id is the one where the entity is currently present, then dbserver responds with DBSERVER_MAP_XFER_FAIL:
If the map_id is the one where the entity is currently present, then dbserver responds with [[#DBSERVER_MAP_XFER_FAIL|DBSERVER_MAP_XFER_FAIL]].
packint(1) entity_id
string error_message


Otherwise, the entity container is unlocked, as the originated MapServer is giving up ownership of this entity, and the map transfer process begins, launching a new MapServer if necessary.
Otherwise, the entity container is unlocked, as the originated MapServer is giving up ownership of this entity, and the map transfer process begins, launching a new MapServer if necessary.
Line 368: Line 300:
The entity container is updated with "MapId" set to the map id, and if the map is static, then also "StaticMapId" is set to the map id.
The entity container is updated with "MapId" set to the map id, and if the map is static, then also "StaticMapId" is set to the map id.


The entity is then locked to the MapServer for the new map id, and a DBSERVER_CONTAINERS is sent to that MapServer with the entity container.
The entity is then locked to the MapServer for the new map id, and a [[#DBSERVER_CONTAINERS|DBSERVER_CONTAINERS]] is sent to that MapServer with the entity container.


Notifications are sent for the entity.  
Notifications are sent for the entity.  


If the account for this entity has a loyalty status, then DBSERVER_ACCOUNTSERVER_LOYALTY is sent to the new MapServer:
If the account for this entity has a loyalty status, then [[#DBSERVER_ACCOUNTSERVER_LOYALTY|DBSERVER_ACCOUNTSERVER_LOYALTY]] is sent to the new MapServer:
  autobits entity_id
  autobits entity_id
  bits(128) loyalty
  bits(128) loyalty
Line 385: Line 317:
If ''list_id'' is not CONTAINER_ENTS, the dbserver will treat it as an EntCon type anyway and probably crash (!!!).
If ''list_id'' is not CONTAINER_ENTS, the dbserver will treat it as an EntCon type anyway and probably crash (!!!).


MapServer only sends this message in response to DBSERVER_CONTAINERS for entities.
MapServer only sends this message in response to [[#DBSERVER_CONTAINERS|DBSERVER_CONTAINERS]] for entities.


If cookie is 0, the entity will be deleted. If cookie is 1, the entity will be unloaded.
If cookie is 0, the entity will be deleted. If cookie is 1, the entity will be unloaded.


If this is part of a map transfer flow, then dbserver will send a DBSERVER_MAP_XFER_OK to the MapServer. If this is part of a login flow, then dbserver will send DBGAMESERVER_MAP_CONNECT to the game client (possibly via QueueServer). Either way, the message will contain:
If this is part of a map transfer flow, then dbserver will send a [[#DBSERVER_MAP_XFER_OK|DBSERVER_MAP_XFER_OK]] to the MapServer. If this is part of a login flow, then dbserver will send [[#DBGAMESERVER_MAP_CONNECT|DBGAMESERVER_MAP_CONNECT]] to the game client (possibly via QueueServer).
packint(1) entity_id
packint(1) map_id
packint(1) ip
packint(1) ip
packint(1) udp_port
packint(1) tcp_port
packint(1) cookie
 
where ''ip'' is the same both times. ''ip'', ''udp_port'', and ''tcp_port'' are the connection information for the game client to connect to the new MapServer. ''cookie'' is copied from the input message.


After this, the entity is marked as '''active''', and its '''logging in''' status is cleared.
After this, the entity is marked as '''active''', and its '''logging in''' status is cleared.
Line 415: Line 338:
  repeated count times:
  repeated count times:
   string door_info
   string door_info
MapServer sends this message with all the doors that it found in the map which it has loaded. Only static maps will send doors; any non-static (mission) MapServer will send an empty list instead.


dbserver finds the map ''map_id'', and marks it as '''running'''.
dbserver finds the map ''map_id'', and marks it as '''running'''.
Line 424: Line 349:
If door info was sent, each one is parsed in turn. dbserver scans existing doors to see if any are in approximately the same location. If none are found, then this door is added to the door containers. Any door containers that are not included in this list are deleted.
If door info was sent, each one is parsed in turn. dbserver scans existing doors to see if any are in approximately the same location. If none are found, then this door is added to the door containers. Any door containers that are not included in this list are deleted.


If any changes were made to door containers, then every eligible MapServer will be sent the door list; otherwise, only the MapServer which sent this request will be updated (if eligible). A MapServer is eligible for a door update if its map is static, or a supergroup base. A door list is sent in a DBSERVER_SEND_DOORS message:
If any changes were made to door containers, then every eligible MapServer will be sent the door list; otherwise, only the MapServer which sent this request will be updated (if eligible). A MapServer is eligible for a door update if its map is static, or a supergroup base. A door list is sent in a [[#DBSERVER_SEND_DOORS|DBSERVER_SEND_DOORS]] message, sending all door containers.
packint(1) count
zipped data
where data is a zipped copy of all the door containers in text format.


== DBCLIENT_SAVELISTS ==
== DBCLIENT_SAVELISTS ==
Line 519: Line 441:


For each container being broadcast to:
For each container being broadcast to:
* If ''list_id'' is a group DbList, then all entities in the group are selected. If it is a Supergroup, and it has a base, then the mapserver for that base is also selected. If it is a statserver group, then statserver is also selected.
* If ''list_id'' is a MapGroup, all mapservers for that group are selected.
* [[#DBSERVER_BROADCAST_MSG|DBSERVER_BROADCAST_MSG]] is sent to all selected links, with the same parameters as the original message. However, instead of the original list of ids, it will be either the member list of the group (if ''list_id'' is a group), or the entity (if ''list_id'' is CONTAINER_ENTS), or empty for all other DbLists.


If ''list_id'' is a group DbList, then all entities in the group are selected. If it is a Supergroup, and it has a base, then the mapserver for that base is also selected. If it is a statserver group, then statserver is also selected.
Note that one DBSERVER_BROADCAST_MSG is sent for every ''id'' in the input.
 
If ''list_id'' is a MapGroup, all mapservers for that group are selected.
 
DBSERVER_BROADCAST_MSG is sent to all selected links, with the same parameters as the original message. However, instead of the original list of ids, it will be either the member list of the group (if ''list_id'' is a group), or the entity (if ''list_id'' is CONTAINER_ENTS), or empty for all other DbLists.


== DBCLIENT_REQ_GROUP_NAMES ==
== DBCLIENT_REQ_GROUP_NAMES ==
Line 604: Line 525:
* The dbserver process exits
* The dbserver process exits


The DBSERVER_SHUTDOWN message sent to mapservers will be:
The DBSERVER_SHUTDOWN message sent to mapservers will have ''terminal'' set to 1, directing the MapServer to exit.
packint(1) terminal
string msg
where ''terminal'' is 1 and ''msg'' is the string passed in the request.


== DBCLIENT_WHO ==
== DBCLIENT_WHO ==
Line 660: Line 578:
If ''server_id'' is negative, all active MapServers are selected. Otherwise, the MapServer for this map is selected.
If ''server_id'' is negative, all active MapServers are selected. Otherwise, the MapServer for this map is selected.


The selected servers are sent DBSERVER_RELAY_CMD:
The selected servers are sent [[#DBSERVER_RELAY_CMD|DBSERVER_RELAY_CMD]].
string msg


== DBCLIENT_RELAY_CMD_BYENT ==
== DBCLIENT_RELAY_CMD_BYENT ==
Line 675: Line 592:
where ''success'' is 1 if the player is online or ''force'' is not 0, and ''online'' is sent only if ''success'' is 1, and will be 1 if the player is online.
where ''success'' is 1 if the player is online or ''force'' is not 0, and ''online'' is sent only if ''success'' is 1, and will be 1 if the player is online.


DBSERVER_RELAY_CMD is sent to the MapServer where the player is loaded:
[[#DBSERVER_RELAY_CMD|DBSERVER_RELAY_CMD]] is sent to the MapServer where the player is loaded, relaying the command.
string msg


== DBCLIENT_RELAY_CMD_TOGROUP ==
== DBCLIENT_RELAY_CMD_TOGROUP ==
Line 685: Line 601:
''list_id'' must be a group, or dbserver will break (bug).
''list_id'' must be a group, or dbserver will break (bug).


All members of the group identified by ''list_id'' and ''id'' will have DBSERVER_RELAY_CMD sent to their mapserver:
All members of the group identified by ''list_id'' and ''id'' will have [[#DBSERVER_RELAY_CMD|DBSERVER_RELAY_CMD]] sent to their mapserver.
string msg


== DBCLIENT_REQ_ONLINE_ENTS ==
== DBCLIENT_REQ_ONLINE_ENTS ==
Line 703: Line 618:
The data returned by dbserver is cached, with a 5 second TTL. It will be computed when this message is sent, if necessary.
The data returned by dbserver is cached, with a 5 second TTL. It will be computed when this message is sent, if necessary.


dbserver responds with DBSERVER_ONLINE_ENTS:
dbserver responds with [[#DBSERVER_ONLINE_ENTS|DBSERVER_ONLINE_ENTS], including all online players.
bits(32) bit_length
bits(32) size
zipped stream
where these three fields describe a byte-aligned bitstream and its contents. The contents of that bitstream are:
repeated:
  packint(20) entity_id
  packint(8) map_id
  packint(8) static_map_id
  packint(4) team_member_count
  packint(1) entity_is_team_leader
  packint(10) hide_field
  packint(10) lfg_field
  packint(6) level
  string archetype
  string origin
  packint(2) player_type
  packint(2) player_type_by_location
  packint(2) player_sub_type
  packint(3) praetorian_progress
  packint(1) arena_map
  packint(1) mission_map
  packint(1) can_co_faction
  packint(1) faction_same_map
  packint(1) can_co_universe
  packint(1) universe_same_map
  bits(32) last_active
  bits(32) member_since
  bits(32) prestige
  packint(8) league_member_count
  packint(1) is_league_leader
packint(20) zero // will be 0
 
Each entry describes one entity; all online players are included.


== DBCLIENT_REQ_ONLINE_ENT_COMMENTS ==
== DBCLIENT_REQ_ONLINE_ENT_COMMENTS ==
Line 849: Line 731:
  packint(1) influence_type
  packint(1) influence_type


If entity entity_id is not loaded, dbserver responds with DBSERVER_CLIENT_CMD_FAILED, error code CONTAINER_ERR_DOESNT_EXIST.
If entity entity_id is not loaded, dbserver responds with [[#DBSERVER_CLIENT_CMD_FAILED|DBSERVER_CLIENT_CMD_FAILED]], error code CONTAINER_ERR_DOESNT_EXIST.


The influence type is set to ''influence_type', and dbserver responds with DBSERVER_CONTAINER_ACK.
The influence type is set to ''influence_type'', and dbserver responds with [[#DBSERVER_CONTAINER_ACK|DBSERVER_CONTAINER_ACK]].


== DBCLIENT_DEPRECATED ==
== DBCLIENT_DEPRECATED ==
Line 1,152: Line 1,034:


== DBSERVER_SEND_DOORS ==
== DBSERVER_SEND_DOORS ==
packint(1) count
zipped data
where data is a zipped copy of all the door containers in text format.
MapServer clears its current door list, and replaces it with door entries parsed from this message.
The zipped data is formatted as text strings, with each door container represented as a line:
1 "..."
where the first parameter is the container ID, and the quoted string is a double-escaped copy of the door container.
The door list is used for this MapServer to know where to send an Entity, when it uses a door. Notably, this is how MapServer knows to transfer the Entity to another map, and which map to send it to.
== DBSERVER_BROADCAST_MSG ==
== DBSERVER_BROADCAST_MSG ==
packint(1) list_id
packint(1) msg_type
packint(1) sender_id
packint(1) count
string msg
repeated count times:
  packint(1) id
This is sent by dbserver in response to DBCLIENT_SEND_MSG. It is normally used to send an update to all members of a group, but can also be directed towards a single entity.
''msg'' is a command, followed by a colon, then the rest of the data.
The valid commands are below. If the command is not recognised, this message is ignored.
=== AllianceChatMsg ===
The data is split by colons, with the first two fields being the sender's supergroup ID and rank, and the rest being the body of the message.
If this is an allied supergroup and permissions do not allow members of this rank to send messages, then nothing happens. Otherwise, it is sent as a chat message, of type ''msg_type''.
=== Email ===
SERVER_SEND_EMAIL_HEADERS is sent to the client.
=== ChatMsg ===
The data is sent as a chat message, of type ''msg_type''.
=== CoHChatMsg ===
The data is sent as a chat message, of type ''msg_type''. It is considered an enemy message if the entity is a villain.
=== CoVChatMsg ===
The data is sent as a chat message, of type ''msg_type''. It is considered an enemy message if the entity is a hero.
=== StoryarcTaskRefresh ===
SERVER_CONTACT_STATUS, SERVER_TASK_VISITLOCATION_UPDATE, and SERVER_TASK_STATUS are sent to the entity, with current data.
=== StoryarcFullRefresh ===
SERVER_CONTACT_STATUS, SERVER_ACCESSIBLE_CONTACT_STATUS, SERVER_TASK_VISITLOCATION_UPDATE, SERVER_CLUE_UPDATE, SERVER_KEYCLUE_UPDATE, SERVER_SOUVENIRCLUE_UPDATE, and SERVER_TASK_STATUS are sent to the entity, with current data.
=== MissionComplete ===
The data is parsed as a mission ID, which is four colon-separated fields: owner, context, subhandle, compoundPos.
SERVER_SEND_FLOATING_INFO is sent to announce mission completion, and if this is a taskforce flashback, SERVER_SEND_DESATURATE_INFO is also sent.
If the teamup is on this mission, it is updated to record success.
=== MissionFailed ===
The data is parsed as a mission ID, which is four colon-separated fields: owner, context, subhandle, compoundPos.
SERVER_SEND_FLOATING_INFO is sent to announce mission failure.
If the teamup is on this mission, it is updated to record failure.
=== MissionStoppedRunning ===
The data is parsed as a mission ID, which is four colon-separated fields: owner, context, subhandle, compoundPos.
If the teamup is on this mission, and it is on an instanced mission map, it is detached from that map (cleaning up clues etc).
=== MissionObjective ===
The data is parsed as a mission objective, which is six comma-separated fields: owner, context, subhandle, compoundPos, objective number, success.
If the teamup is on this mission, the objective is added.
=== TeamTaskSelected ===
SERVER_TASK_SELECT is sent.
If this entity is not the teamup leader, then the chat message TeamTaskChanged is sent, with type INFO_SVR_COM.
=== TaskForceResumeTeam ===
=== TaskForceGetCredit ===
=== TFChallengeFailed ===
=== TFChallengeShowSummary ===
=== MapListRefresh ===
The data is parsed as an integer map_id, and recorded in the team and league as the current map of the sender.
=== SupergroupRefresh ===
=== PaymentRemainTime ===
=== ArchitectComplete ===
=== ArchitectCompleteMission ===
=== TaskForceComplete ===
== DBSERVER_SEND_ENT_NAMES ==
== DBSERVER_SEND_ENT_NAMES ==
== DBSERVER_SEND_GROUP_NAMES ==
== DBSERVER_SEND_GROUP_NAMES ==
Line 1,158: Line 1,144:
== DBSERVER_CONTAINER_ID ==
== DBSERVER_CONTAINER_ID ==
== DBSERVER_SHUTDOWN ==
== DBSERVER_SHUTDOWN ==
packint(1) terminal
string msg
In local server mode, this message is ignored.
If ''terminal'' is 0 then the mission shutdown process is run. Otherwise, the MapServer shuts down:
* All entities are sent to dbserver, and MapServer waits for them all to be acked.
* All connected clients are logged out, with reason KICKTYPE_FROMDBSERVER.
* Shared memory is cleaned up.
* MapServer waits to finish writing its logs.
* The process exits.
== DBSERVER_WHO ==
== DBSERVER_WHO ==
== DBSERVER_RELAY_CMD ==
== DBSERVER_RELAY_CMD ==
string msg
''msg'' is split on spaces. The first word is interpreted as a command. The commands below are recognised, and all others are ignored.
=== silenceall ===
Example usage:
silenceall 1
With a non-zero parameter, this prevents players from sending chat messages.
=== cmdrelay ===
Example usage:
cmdrelay
SetMARTYStatusRelay 1
Everything after the first line is parsed as a server command, as if it had been sent with access level ACCESS_USER and no client.
=== server_sgstat_cmd ===
=== cmdrelay_dbid ===
Example usage:
cmdrelay_dbid 15
conprint "message"
The first parameter to cmdrelay_dbid is an entity ID. If that entity is loaded here, then everything after the first line is parsed as a server command, as if it had been sent by the client for that entity with access level ACCESS_INTERNAL.
If a second optional parameter is given, then responses to the command will be sent to that entity, instead of to the entity which ran the command.
If the entity ID is not loaded in this MapServer, then the rest of the message is sent back to dbserver in [[#DBCLIENT_RELAY_CMD_BYENT|DBCLIENT_RELAY_CMD_BYENT]], with a cmdrelay_dbid prefix. Only the first parameter is preserved when this happens (bug!!!).
=== cmdrelay_db_no_ent ===
Example usage:
cmdrelay_db_no_ent
check_player_name 1 2 "name"
Everything after the first line is parsed as a server command, as if it had been sent with access level ACCESS_INTERNAL and no client.
== DBSERVER_LOST_MEMBERSHIP ==
== DBSERVER_LOST_MEMBERSHIP ==
== DBSERVER_CLIENT_CMD_FAILED ==
== DBSERVER_CLIENT_CMD_FAILED ==
  packint(1) fail_code
  string str
MapServer logs the error. If ''fail_code'' is CONTAINER_ERR_CANT_COMPLETE_SERIOUS and piggs/texts.pigg does not exist, MapServer will assert (!!!).
Otherwise, ''fail_code'' is stored as an errno-like value in {{ms|last_db_error_code}}, which is checked by many container operations.
== DBSERVER_SEND_MAPNAMES ==
== DBSERVER_SEND_MAPNAMES ==
== DBSERVER_SEND_DELETED_CHARS ==
== DBSERVER_SEND_DELETED_CHARS ==
Line 1,167: Line 1,209:
== DBSERVER_OFFLINE_CHARACTER_RSLT ==
== DBSERVER_OFFLINE_CHARACTER_RSLT ==
== DBSERVER_ONLINE_ENTS ==
== DBSERVER_ONLINE_ENTS ==
bits(32) bit_length
bits(32) size
zipped stream
where these three fields describe a byte-aligned bitstream and its contents. The contents of that bitstream are:
repeated:
  packint(20) entity_id
  packint(8) map_id
  packint(8) static_map_id
  packint(4) team_member_count
  packint(1) entity_is_team_leader
  packint(10) hide_field
  packint(10) lfg_field
  packint(6) level
  string archetype
  string origin
  packint(2) player_type
  packint(2) player_type_by_location
  packint(2) player_sub_type
  packint(3) praetorian_progress
  packint(1) arena_map
  packint(1) mission_map
  packint(1) can_co_faction
  packint(1) faction_same_map
  packint(1) can_co_universe
  packint(1) universe_same_map
  bits(32) last_active
  bits(32) member_since
  bits(32) prestige
  packint(8) league_member_count
  packint(1) is_league_leader
packint(20) zero // will be 0
MapServer unpacks this data and stores it. It is used to implement searching for players, when game clients request it.
== DBSERVER_MAP_XFER_LOADING ==
== DBSERVER_MAP_XFER_LOADING ==
autobits entity_id
bits(1) on
MapServer sends the entity SERVER_MAP_XFER_LOADING. It otherwise ignores this message.
dbserver sends this message to MapServer when it needs to launch a new MapServer, which is expected to take some time.
== DBSERVER_MAP_XFER_READY ==
== DBSERVER_MAP_XFER_READY ==
packint(1) link_id
packint(1) new_map_id
MapServer finds the entity for ths ''link_id'', and updates its status to set '''map_ready''', unset '''waiting_map_xfer''', and record ''new_map_id'' as its destination.
== DBSERVER_MAP_XFER_OK ==
== DBSERVER_MAP_XFER_OK ==
packint(1) entity_id
packint(1) map_id
packint(1) ip
packint(1) ip
packint(1) udp_port
packint(1) tcp_port
packint(1) cookie
''ip'' is the same both times. ''ip'', ''udp_port'', and ''tcp_port'' are the connection information for the game client to connect to the new MapServer. ''cookie'' is copied from the [[#DBCLIENT_CONTAINER_ACK|DBCLIENT_CONTAINER_ACK]] message that triggered this.
MapServer sends [[Client-to-mapserver#SERVER_MAP_XFER|SERVER_MAP_XFER]] to the client for this Entity, forwarding the same information.
== DBSERVER_MAP_XFER_FAIL ==
== DBSERVER_MAP_XFER_FAIL ==
packint(1) entity_id
string error_message
MapServer sends SERVER_DOOR_CMD to the client for this Entity, and puts the Entity back on its own map as if it had just joined.
== DBSERVER_CUSTOM_DATA ==
== DBSERVER_CUSTOM_DATA ==
== DBSERVER_CLEAR_PNAME_CACHE_ENTRY ==
== DBSERVER_CLEAR_PNAME_CACHE_ENTRY ==
== DBSERVER_TEAM_LEFT_MISSION ==
== DBSERVER_TEAM_LEFT_MISSION ==
This message has no body.
If there is an active mission with an owner, then MapServer processes a missionrequestshutdown command on behalf of that owner.
If there is no active mission or the mission has no owner, then MapServer shuts it down:
* a DBCLIENT_CLOSE_INSTANCE is sent to dbserver, to notify turnstileserver of the instance closing
* dbserver marks itself as quitting, and begins the process of transferring all connected players to other maps
* when no players are connected, MapServer disconnects from dbserver, waits for its logs to finish writing, and exits
== DBSERVER_RELAY_CMD_RESPONSE ==
== DBSERVER_RELAY_CMD_RESPONSE ==
== DBSERVER_ARENA_ADDRESS ==
== DBSERVER_ARENA_ADDRESS ==
Line 1,183: Line 1,298:
== DBSERVER_CONTAINER_SERVER_NOTIFY ==
== DBSERVER_CONTAINER_SERVER_NOTIFY ==
== DBSERVER_CONTAINER_RELAY ==
== DBSERVER_CONTAINER_RELAY ==
packint(1) cmd
packint(1) list_id
packint(1) cid
packint(1) user_cmd
packint(1) user_data
packint(1) lock_id
... everything else from the DBCLIENT_CONTAINER_RELAY is copied here
MapServer ignores this message; it is sent to RaidServer.
== DBSERVER_CONTAINER_RECEIPT ==
== DBSERVER_CONTAINER_RECEIPT ==
packint(1) cmd
packint(1) list_id
packint(1) cid
packint(1) user_cmd
packint(1) user_data
packint(1) error_code
string error_msg
== DBSERVER_CONTAINER_REFLECT ==
== DBSERVER_CONTAINER_REFLECT ==
packint(1) list_id
packint(1) cmd
packint(1) target_count
repeated target_count times:
  packint(1) target_list
  packint(1) target_cid
  packint(1) target_dbid
  packint(1) del
packint(1) count
repeated count times:
  packint(1) id
optionally repeated count times:
  string data
MapServer treats this message as an error for all values of ''list_id'' other than CONTAINER_BASERAITS, CONTAINER_ITEMSOFPOWER, and CONTAINER_ITEMOFPOWERGAMES.
== DBSERVER_MISSION_PLAYER_COUNT ==
== DBSERVER_MISSION_PLAYER_COUNT ==
== DBSERVER_SEND_STATSERVER_CMD ==
== DBSERVER_SEND_STATSERVER_CMD ==
Line 1,203: Line 1,352:
== DBSERVER_ACCOUNTSERVER_NOTIFYSAVED ==
== DBSERVER_ACCOUNTSERVER_NOTIFYSAVED ==
== DBSERVER_ACCOUNTSERVER_CATALOG ==
== DBSERVER_ACCOUNTSERVER_CATALOG ==
autobits catalog_timestamp
autobits auth_timeout
string mtx_environment
string play_span_domain
string play_span_url_home
string play_span_url_categoryview
string play_span_url_itemview
string play_span_url_showcart
string play_span_url_addtocart
string play_span_url_manageaccount
string play_span_url_supportpage
string play_span_url_supportpage_de
string play_span_url_supportpage_fr
string play_span_url_updatetovip
string coh_url_newfeatures
string coh_url_newfeaturesupdate
autobits play_span_store_flags
== DBSERVER_ACCOUNTSERVER_CLIENTAUTH ==
== DBSERVER_ACCOUNTSERVER_CLIENTAUTH ==
== DBSERVER_ACCOUNTSERVER_PLAYNC_AUTH_KEY ==
== DBSERVER_ACCOUNTSERVER_PLAYNC_AUTH_KEY ==
Line 1,223: Line 1,390:
== DBSERVER_MISSIONSERVER_BAN_STATUS ==
== DBSERVER_MISSIONSERVER_BAN_STATUS ==
== DBSERVER_OVERRIDDEN_AUTHBITS ==
== DBSERVER_OVERRIDDEN_AUTHBITS ==
bits(1024) overridden_auth_bits
== DBSERVER_EVENT_WAIT_TIMES ==
== DBSERVER_EVENT_WAIT_TIMES ==
== DBSERVER_QUEUE_STATUS ==
== DBSERVER_QUEUE_STATUS ==
Line 1,233: Line 1,402:
== DBSERVER_MISSIONSERVER_ARCDATA_OTHERUSER ==
== DBSERVER_MISSIONSERVER_ARCDATA_OTHERUSER ==
== DBSERVER_DISABLED_ZONE_EVENTS ==
== DBSERVER_DISABLED_ZONE_EVENTS ==
repeated string event
== DBSERVER_NOTIFY_REACTIVATION ==
== DBSERVER_NOTIFY_REACTIVATION ==
This message has no body.
If MapServer receives this message, then it enables character reactivation globally for this MapServer.
== DBSERVER_EVENTHISTORY_RESULTS ==
== DBSERVER_EVENTHISTORY_RESULTS ==
== DBSERVER_REJOIN_FAIL ==
== DBSERVER_REJOIN_FAIL ==
Line 1,240: Line 1,416:
== DBSERVER_ACCOUNTSERVER_CERTIFICATION_REFUND ==
== DBSERVER_ACCOUNTSERVER_CERTIFICATION_REFUND ==
== DBSERVER_UPDATE_LOG_LEVELS ==
== DBSERVER_UPDATE_LOG_LEVELS ==
repeated LOG_LEVELS times:
  packint(1) log_level
MapServer sets its log levels as directed. It also relays them to ArenaServer directly, as an ARENACLIENT_SET_LOG_LEVELS message, and to RaidServer indirectly by relaying RAIDCLIENT_SET_LOG_LEVELS to the CONTAINER_BASERAIDS container, via dbserver.
== DBSERVER_TEST_LOG_LEVELS ==
== DBSERVER_TEST_LOG_LEVELS ==
== DBSERVER_ACCOUNTSERVER_MULTI_GAME_TRANSACTION ==
== DBSERVER_ACCOUNTSERVER_MULTI_GAME_TRANSACTION ==

Latest revision as of 15:43, 26 May 2019

dbserver listens on port 6997 for its db service, and MapServer and RaidServer connect to it.

(For other services that dbserver presents, see Dbserver-protocols.)

Every NetLink for the db server has a unique lock_id, starting from 0. They are used to identify current connections to MapServer in order to send messages.

Commands with names starting with DBSERVER are sent by dbserver, and names starting with DBCLIENT are sent to dbserver.

DBCLIENT_INITIAL_CONNECT

optional packint(1) map_protocol

If map_protocol is not present (the body is empty), it is 0. If map_protocol is not equal to DBSERVER_PROTOCOL_VERSION (currently 20110503) then dbserver will respond with DBSERVER_CLIENT_CMD_FAILED and close the NetLink.

Otherwise, dbserver sends these commands back to the MapServer:

DBCLIENT_READY

This message is understood by dbserver, but does not appear to be sent by mapserver; it is suspected to be historical debris.

DBCLIENT_REGISTER

packint(1) map_id
packint(1) local_ip
packint(1) remote_ip
packint(1) udp_port
packint(1) tcp_port
packint(1) static_link
packint(1) cookie
string patch_version
optional string map_name

A MapServer sends this message when it starts up, immediately after DBCLIENT_INITIAL_CONNECT.

static_link is set based on the command line of the MapServer

map_id is a signed int, set on the command line of the MapServer. Negative values mean that a map_name field will be sent and edit mode will be used.

If map_id is non-negative, then dbserver selects the container for this mapserver based on map_id, and closes the link if the map_id is not known. Otherwise, dbserver selects the container based on map_name, and enables edit mode on this container. If static_link is set, then dbserver searches for a map with this name. If static_link is not set, or no map of this name is found, then a new map container is created and populated with the data in the map_name field.

udp_port and tcp_port are the ports on which the MapServer will listen for game clients, and are set on the command line.

cookie is set on the command line of the MapServer, and sent as-is. If the cookie is non-zero, then dbserver will validate that it matches the cookie matches the container referenced by map_id, and will close the link if it does not match. This is used to ensure the MapServer is the one this dbserver wanted to spawn, and not from a previous instance of dbserver.

local_ip and remote_ip are sent by the mapserver, based on the result of gethostbyname(NULL). They will use the first two results from this function. If one of those results is an rfc1918 address, or 127.0.0.1 (none of the other loopback addresses are recognised as "local"), then it will be local_ip; otherwise local_ip will be the first result from gethostbyname() and remote_ip will be the second.

The map container in the dbserver will have its link set to the link which sent this message, and will be marked starting and active. dbserver will respond to the MapServer with DBSERVER_CONTAINERS, sending the container for map_id followed by the containers for all static maps.

DBCLIENT_REGISTER_CONTAINER_SERVER

packint(1) list_id

The client attempts to claim ownership of the DbList identified by list_id. This is used by RaidServer to register itself with dbserver. Only one link may own a DbList at a time. If another link has claimed the DbList, then this one is marked as waiting for it. If the owner of the DbList is disconnected, then a link which is waiting for it will become the owner.

When a link becomes the owner of a DbList, then dbserver sends it a DBSERVER_CONTAINER_SERVER_ACK:

packint(1) list_id
packint(1) max_session_id

Owning a DbList affects the handling of DBCLIENT_CONTAINER_RELAY and DBCLIENT_REGISTER_CONTAINER_SERVER_NOTIFY messages.

DBCLIENT_REGISTER_CONTAINER_SERVER_NOTIFY

packint(1) notify_mask

All DbLists owned by this link have their notify mask set to notify_mask.

notify_mask is a bitmask, where each bit corresponds to a ContainerType value. For each bit set, when a notification for that DbList is available, a DBSERVER_CONTAINER_SERVER_NOTIFY will be sent:

packint(1) list_id
packint(1) container_id
packint(1) member_id
bits(1) is_added

Notifications are only sent for the addition of Ents (player characters loading onto a map), deletion of containers, and for adding and removing group members. When an Ent is added, an add notification is sent for all groups that Ent is currently a member of.

is_added is 1 if a thing is being added, and 0 if a thing is being removed.

container_id is the id of the container being updated - either the group where members are being added or removed, or the container being deleted.

member_id is 0 if the operation is the removal of a group (supergroup deletion, etc), or the member ID if the operation is adding or removing a member from a group.

DBCLIENT_READY_FOR_PLAYERS

packint(1) map_id

This message is sent by MapServer when it has finished settup in the map. It marks the MapCon as not starting. If the MapCon has been marked for shutdown in the dbserver, then the dbserver will respond with an empty DBSERVER_TEAM_LEFT_MISSION message.

DBCLIENT_CONTAINER_INFO

This message has no body. dbserver will respond with DBSERVER_CONTAINER_INFO:

packint(1) count
string dbserver_status
repeated count-1 times:
  string container_status

dbserver_status will be a string like "DbServer started on %s, Up %d hours, %d minutes"

container_status will be a string like "0040 Ent (1)", giving the number of allocated containers in the each DbList, and its name and ContainerType value.

This message is sent by MapServer when handling the dbquery command, or by the dbquery command-line tool.

DBCLIENT_REQ_CONTAINERS

packint(1) user_data
packint(1) list_id
packint(1) cmd
packint(1) count
repeated count times:
  packint(1) container_id

dbserver will respond to this message with DBSERVER_CONTAINERS, with some containers selected from DbList list_id. user_data is returned in the DBSERVER_CONTAINERS response.

If cmd is CONTAINER_CMD_LOAD_ALL, count is ignored and all containers in the list are selected. Otherwise, container_id values are sent in the message, and those containers are selected.

Depending on the command selected, three other operations might be performed on this list:

  • With CONTAINER_CMD_LOCK_AND_LOAD, CONTAINER_CMD_LOAD_ALL, CONTAINER_CMD_TEMPLOAD, or CONTAINER_CMD_TEMPLOAD_OFFLINE the containers will be loaded if necessary. Otherwise, containers that are not loaded will return an error code of CONTAINER_ERR_DOESNT_EXIST for that container.
  • With CONTAINER_CMD_LOCK or CONTAINER_CMD_LOCK_AND_LOAD the containers will be locked to this link. Any container which is already locked by another link will return an error code of CONTAINER_ERR_ALREADY_LOCKED for that container.
  • With CONTAINER_CMD_TEMPLOAD or CONTAINER_CMD_TEMPLOAD_OFFLINE any containers that have to be loaded for this message will be unloaded after it is finished.
  • With CONTAINER_CMD_TEMPLOAD_OFFLINE the special handling for offline players (???) is used.

DBCLIENT_SET_CONTAINERS

packint(1) list_id
packint(1) cmd
packint(1) callback_id
packint(1) count
repeated count times:
  packint(1) container_id
  packint(1) notdiff
  packint(1) debugdiff
  string str
  optional string debugdiff_str

debugdiff_str is only sent when debugdiff is not 0, otherwise it is skipped

dbserver stores the containers, and responds with DBSERVER_CONTAINER_ACK to most messages. The ack_id values will be the container_id values that were updated.

One DBSERVER_CONTAINER_ACK response is sent after every update is applied, containing all acks so far (this appears to be a bug, and not used for anything). Acks are used by MapServer to return the container_id when creating containers, and otherwise ignored.

The exception to this are:

  • when list_id is the AutoCommands list, in which case dbserver will instead respond by broadcasting a DBSERVER_CONTAINERS message to all active MapServers with the new container value
  • when the container is a GroupCon type, and cmd is not CONTAINER_CMD_UNLOCK_NOMODIFY, in which case dbserver will instead respond by broadcasting a DBSERVER_CONTAINERS message to all interested links:
    • MapServers that are running members of a MapGroup
    • MapServers that have connected Ents for other groups
    • the MapServer for a supergroup base
    • the statserver for a statserver group
    • the link that sent the DBCLIENT_SET_CONTAINERS message)

In these cases, no DBSERVER_CONTAINER_ACK messages are sent.

Possible values for cmd are:

  • CONTAINER_CMD_CREATE, in which case id must be -1 and the container will be created.
  • CONTAINER_CMD_CREATE_MODIFY, in which case id may be -1 and the container will be created if no container with this id exists.
  • CONTAINER_CMD_DELETE, which will mark the container for deletion. str is ignored.
  • CONTAINER_CMD_UNLOCK, which will apply updates and then unlock the container if this link has it locked.
  • CONTAINER_CMD_UNLOCK_NOMODIFY, which will unlocked the container if this link has it locked, and not attempt to update the container. str is ignored
  • CONTAINER_CMD_TEMPLOAD, which will load the container before updating it, and unload it after updating it, regardless of whether it was already loaded.

All other values of cmd will apply the update to an existing container.

If an error occurs, dbserver will abandon processing of the rest of the message, and respond with DBSERVER_CLIENT_CMD_FAILED. This occurs in the following scenarios:

  • id is -1 for commands other than CREATE and CREATE_MODIFY, or id being any value other than -1 for CREATE, will return CONTAINER_ERR_DOESNT_EXIST
  • Parse errors for the container in str will return CONTAINER_ERR_CANT_COMPLETE_SERIOUS
  • An attempt to create an Ent on an account without free character slots will return CONTAINER_ERR_CANT_COMPLETE
  • An attempt to create an Ent where the character name cannot be parsed will return CONTAINER_ERR_CANT_COMPLETE
  • For DbList other than maps, a container that exists must not be locked to a link other than this one, or it will return CONTAINER_ERR_ALREADY_LOCKED
  • For DbList other than maps, and commands other than CREATE_MODIFY, the container must be locked or it will return CONTAINER_ERR_NOT_LOCKED
  • If the container does not exist for whatever reason (after processing creation), it will return CONTAINER_ERR_DOESNT_EXIST

Applying container updates

str will be treated as a diff if notdiff is 0, or as a full copy of the container if notdiff is 1.

If the container does not have a template, then the string supplied always treated as a complete replacement, and the content of the container is simply set to this value, then special column processing is run.

If the container has a template, and notdiff is 1, then a diff will be computed from the current value of the template to the string supplied, and then processing will continue as if a diff had been sent.

If the container has a template, then the string will be parsed into a line list, and then merged into the current line list. Next, special column processing is run. The computed updates are then added to the queue of sql writes, and if the container has an update callback, it is called (this is probably a bug: it will be called twice).

Special columns processing begins by calling the update callback. It then runs through a list of commands, which identify fields in the line list by name. The values of these fields will be written into some address inside the DbContainer struct, as identified by the command. In the particular case of CMD_MEMBER, special tracking is done of memberships, which may result in sending notifications to servers that requested them with DBCLIENT_REGISTER_CONTAINER_SERVER_NOTIFY.

Special hackery

If the command is CREATE and the DbList is Ents (creating a player), then the player name will be uniquified (by appending or incrementing a number).

If the DbList is maps, and there is a map name in str, and a container with that name exists, then id is ignored and the container with that name is updated instead.

If the DbList is Ents and the container exists, and str contains a MapId field, then it must be equal to the map_id in the Ent or the server will assert (!!!).

If debugdiff is set, then the debugdiff_str field must be precisely equal to the observed diff to the container after the operation, or the server will assert (!!!).

If the command is CREATE and the DbList is Teamups, Supergroups, Taskforces, or Leagues, and the DbList is being stored in sql, then an sql barrier will be generated (all workers will synchronise).

If the DbList is maps, and the container is not being deleted, then dbserver will ask a launcher to start a MapServer if it does not have a link from a MapServer on this container.

DBCLIENT_CONTAINER_RELAY

packint(1) cmd
packint(1) list_id
packint(1) cid
packint(1) user_cmd
packint(1) user_data
... more data that dbserver does not parse

If list_id is not recognised, or no server has that DbList locked, then dbserver will respond with DBSERVER_CONTAINER_RECEIPT, where error_code will be CONTAINER_ERR_CANT_COMPLETE.

Otherwise, dbserver will forward the message to the server which has locked that DbList, as DBSERVER_CONTAINER_RELAY.

This is used for MapServer to send messages to RaidServer.

DBCLIENT_CONTAINER_RECEIPT

packint(1) lock_id
... more data that dbserver does not parse

dbserver finds the MapServer connection corresponding to lock_id and proxies the message to that MapServer as DBSERVER_CONTAINER_RECEIPT:

... all the data from the input message

This is used by RaidServer to acknowledge messages from MapServer.

DBCLIENT_CONTAINER_REFLECT

packint(1) list_id
packint(1) cmd
packint(1) target_count
repeated target_count times:
  packint(1) target_list
  packint(1) target_cid
  packint(1) target_dbid
  packint(1) del
packint(1) count
repeated count times:
  packint(1) id
optionally repeated count times:
  string data

data is present only when cmd is not CONTAINER_CMD_DELETE

If cmd is CONTAINER_CMD_CREATE_MODIFY, then dbserver will update each container id with the corresponding data, which is a full copy of the new container value. If cmd is CONTAINER_CMD_DELETE, then dbserver will delete each container id. No locking is checked for these updates.

dbserver now assembles a list of MapServers that these containers will be reflected to. The list is composed by going through the target block, and for each one:

  • target_list is a list_id, target_cid is a container ID in that list
  • If this target is a group container, and it is loaded, then the current MapServer for every loaded and connected member of that group is included
  • If this target is an Ent, then its current MapServer is included
  • If target_list is CONTAINER_MAPS and target_cid is -1, every MapServer is included
  • If this target is a map, then its current MapServer is included
  • If target_list is REFLECT_LOCKID then target_cid is a lock_id, not a container id, and the relevant MapServer is included

For each identified MapServer, dbserver sends it a DBSERVER_CONTAINER_REFLECT, with the same format as the input packet. The target list is changed to be the actual targets, discarding anything that could not be resolved to a MapServer.

DBCLIENT_REQ_CONTAINER_STATUS

packint(1) user_data
packint(1) list_id
packint(1) count
repeated count times:
  packint(1) id

If id is -1 then it means all active containers. If it is -2 then it means all containers. The concept of active means something different for different container types. Notably, the map for a connected MapServer, and an Ent that is connected to a MapServer, will both be active.

dbserver responds with DBSERVER_CONTAINER_STATUS. For each selected container, it sends a status string which will be either a DbList-specific status string, or "%3d Active %d locked %d", populated with container id, active status, and locked status.

DBCLIENT_REQUEST_MAP_XFER

packint(1) map_id
string mapinfo
packint(1) find_best_map
packint(1) entity_id
bits(1) have_extra_data
optional autobits extra_crc
optional zipped extra_data

The extra_crc and extra_data fields are present only if have_extra_data is not 0. If this happens, dbserver will respond with an error. This appears to be a removed feature.

If mapinfo is not empty, then it identifies an instanced map. Otherwise, map_id identifies a specific map.

dbserver might override map_id to a different value in some scenarios (relating to Praetorian progression).

If find_best_map is 1, then dbserver will look for a clone of the map and select one based on the number of players currently on it.

If the map is instanced or static, a MapServer will be started for it.

The entity entity_id will be added to the list of entities waiting for this map, and when that MapServer is ready (possibly immediately), dbserver will send DBSERVER_MAP_XFER_READY to the MapServer which sent the transfer request.

MapServer sends this message to dbserver in order to begin the map transfer process.

DBCLIENT_MAP_XFER

packint(1) map_id
packint(1) count
repeated count times:
  packint(1) entity_id

Each entity in the list is processed separately.

dbserver might override map_id to a different value in some scenarios (relating to Praetorian progression).

If the map_id is the one where the entity is currently present, then dbserver responds with DBSERVER_MAP_XFER_FAIL.

Otherwise, the entity container is unlocked, as the originated MapServer is giving up ownership of this entity, and the map transfer process begins, launching a new MapServer if necessary.

The entity container is updated with "MapId" set to the map id, and if the map is static, then also "StaticMapId" is set to the map id.

The entity is then locked to the MapServer for the new map id, and a DBSERVER_CONTAINERS is sent to that MapServer with the entity container.

Notifications are sent for the entity.

If the account for this entity has a loyalty status, then DBSERVER_ACCOUNTSERVER_LOYALTY is sent to the new MapServer:

autobits entity_id
bits(128) loyalty

DBCLIENT_CONTAINER_ACK

packint(1) list_id
packint(1) count
repeated count times:
  packint(1) id
  packint(1) cookie

If list_id is not CONTAINER_ENTS, the dbserver will treat it as an EntCon type anyway and probably crash (!!!).

MapServer only sends this message in response to DBSERVER_CONTAINERS for entities.

If cookie is 0, the entity will be deleted. If cookie is 1, the entity will be unloaded.

If this is part of a map transfer flow, then dbserver will send a DBSERVER_MAP_XFER_OK to the MapServer. If this is part of a login flow, then dbserver will send DBGAMESERVER_MAP_CONNECT to the game client (possibly via QueueServer).

After this, the entity is marked as active, and its logging in status is cleared.

DBCLIENT_TEST_MAP_XFER

packint(1) list_id // must be CONTAINER_ENTS
packint(1) map_id
packint(1) count // not used
packint(1) entity_id

dbserver sends DBSERVER_TEST_MAP_XFER to the MapServer where the entity is currently located, with a body identical to the message received.

DBCLIENT_SEND_DOORS

packint(1) map_id
packint(1) count
repeated count times:
  string door_info

MapServer sends this message with all the doors that it found in the map which it has loaded. Only static maps will send doors; any non-static (mission) MapServer will send an empty list instead.

dbserver finds the map map_id, and marks it as running.

If this map is not static, then dbserver continues as if count is 0 (no doors are sent), regardless of the data sent.

If the map has a base map, then that map is used instead for the remained of this message.

If door info was sent, each one is parsed in turn. dbserver scans existing doors to see if any are in approximately the same location. If none are found, then this door is added to the door containers. Any door containers that are not included in this list are deleted.

If any changes were made to door containers, then every eligible MapServer will be sent the door list; otherwise, only the MapServer which sent this request will be updated (if eligible). A MapServer is eligible for a door update if its map is static, or a supergroup base. A door list is sent in a DBSERVER_SEND_DOORS message, sending all door containers.

DBCLIENT_SAVELISTS

This message has no body and receives no response. dbserver will write all the door containers to a flat file.

DBCLIENT_ADDDEL_MEMBERS

packint(1) list_id
packint(1) add
packint(1) id
packint(1) notdiff
packint(1) debug
string update
optional string not_used // present if debug is not 0
packint(1) count
repeated count times:
  packint(1) member_id
bits(1) autolock

If list_id is CONTAINER_SUPERGROUPS, then the container id will be loaded. Otherwise, the container id is selected only if it is loaded, and otherwise dbserver will respond with DBSERVER_CLIENT_CMD_FAILED, error code CONTAINER_ERR_DOESNT_EXIST.

add mode

If add is not 0, then dbserver will attempt to add all members to the group.

If the group container is locked by a different link, or if autolock is set and the container is locked by this link, then dbserver will respond with DBSERVER_CLIENT_CMD_FAILED, error code CONTAINER_ERR_ALREADY_LOCKED.

If autolock is set and update is not the empty string, dbserver will respond with DBSERVER_CLIENT_CMD_FAILED, error code CONTAINER_ERR_NOT_LOCKED.

Otherwise, the change will be applied.

When an add operation is applied:

  • If update is not the empty string, then it is applied to the container. If notdiff is set then it replaces the container, otherwise it is applied as a diff.
  • All members are added to the container (which must be a group. bug: dbserver will break if it is not).
  • If autolock is set then the group will be locked
  • If the group is locked then dbserver will respond with DBSERVER_CONTAINERS, containing the new value of the group.
  • If the group is not locked (which means this is adding members without updating the container), then dbserver will instead broadcast the container in the same way as DBCLIENT_SET_CONTAINERS does.

remove mode

If add is 0, then dbserver will attempt to remove all members from the group.

If autolock is set and the group is not locked, dbserver will respond with DBSERVER_CLIENT_CMD_FAILED, error code CONTAINER_ERR_NOT_LOCKED.

If the group is locked by a different link, dbserver will respond with DBSERVER_CLIENT_CMD_FAILED, error code CONTAINER_ERR_ALREADY_LOCKED.

Otherwise, the change will be applied.

When a remove operation is applied:

  • If update is not the empty string, then it is applied to the container. If notdiff is set then it replaces the container, otherwise it is applied as a diff.
  • All members are removed from the container (which must be a group. bug: dbserver will break if it is not).
  • If autolock is set, then the group is unlocked
  • If the group is locked then dbserver will respond with DBSERVER_CONTAINERS, containing the new value of the group.
  • If the group is not locked (which happens if autolock is set), then dbserver will instead broadcast the container in the same way as DBCLIENT_SET_CONTAINERS does.

DBCLIENT_PLAYER_DISCONNECT

packint(1) entity_id
packint(1) logout
packint(2) logout_login

If entity_id is not loaded, does not exist, or is locked by another link, then dbserver does nothing and processing stops.

If logout_login is 2 and the queue server is in use, then the entity's account name is added to the auto-login list.

If the entity is in the queue, then it is unlocked and dbserver does nothing.

If logout is 0 or logout_login is 2 then the account will not be logged out.

Otherwise:

  • The entity container is backed up.
  • If logout is not 0 or logout_login is not 2 then account logout is sent:
    • dbserver sends ACCOUNT_CLIENT_LOGOUT_ACCOUNT to accountserver
    • dbserver sends AS_QUIT_GAME to authserver, with reason set to 4
  • The player is unloaded:
    • dbserver sends DBSERVER_REMOVE_FROM_QUEUE to turnstileserver, with remove_from_group set to 1
    • If the entity is part of a Teamup, then they are removed from it.
    • If the entity is part of a League, then they are removed from it, and statserver is sent DBSERVER_SEND_STATSERVER_CMD, with command set to "statserver_league_quit %d 0 0" % entity_id
    • If the entity was waiting for transfer to a mapserver, then its game client is sent an error message, as DBGAMESERVER_MSG or DBSERVER_MAP_XFER_FAIL.
    • The entity is unloaded

DBCLIENT_SEND_MSG

packint(1) list_id
packint(1) msg_type
packint(1) sender_id
packint(1) count
string msg
repeated count times:
  packint(1) id

For each id in list_id, msg is broadcast to that container. If id is -1, then all containers in that DbList are broadcast to.

For each container being broadcast to:

  • If list_id is a group DbList, then all entities in the group are selected. If it is a Supergroup, and it has a base, then the mapserver for that base is also selected. If it is a statserver group, then statserver is also selected.
  • If list_id is a MapGroup, all mapservers for that group are selected.
  • DBSERVER_BROADCAST_MSG is sent to all selected links, with the same parameters as the original message. However, instead of the original list of ids, it will be either the member list of the group (if list_id is a group), or the entity (if list_id is CONTAINER_ENTS), or empty for all other DbLists.

Note that one DBSERVER_BROADCAST_MSG is sent for every id in the input.

DBCLIENT_REQ_GROUP_NAMES

packint(1) list_id
packint(1) count
repeated count times:
  packint(1) id

If any of the containers id in list_id are not loaded, then an SQL query will be run to get the Name field of every container. Otherwise, the response will be sent from loaded containers. In both cases the response should be the same.

dbserver responds with DBSERVER_SEND_GROUP_NAMES:

packint(1) list_id
packint(1) count
repeated count times:
  packint(1) id
  string name

where name is the Name field of each container.

DBCLIENT_REQ_ENT_NAMES

packint(1) list_id
packint(1) count
repeated count times:
  packint(1) entity_id

list_id should be CONTAINER_ENTS but is ignored.

dbserver responds with DBSERVER_SEND_ENT_NAMES, populating it with every entity in the request:

packint(1) list_id
packint(1) count
repeated count times:
  packint(1) entity_id
  string name
  packint(3) gender
  packint(3) name_gender
  packint(1) player_type
  autobits player_sub_type
  autobits player_type_by_location
  autobits praetorian_progress
  packint(1) auth_id

list_id in the response will be equal to the input, even though the response is always from CONTAINER_ENTS.

DBCLIENT_CONTAINER_FIND_BY_ELEMENT

packint(1) list_id
string element
string value
packint(1) online_only
packint(1) search_offline_ents

If list_id is CONTAINER_MAPS, then value is interpreted as an integer and the map with this ID is selected.

For all other values of list_id, element is a field name and value is an exact value to search for. A container with that value will be selected. The value is a string, unless the field is ContainerId, when it will be an integer.

If online_only is set and either:

  • element is ContainerId
  • element is Name and the DbList is entities or a group

then only loaded containers will be searched.

If element is Name, list_id is CONTAINER_ENTS, and a container has not yet been found, then special handling of offline players is performed (???).

dbserver responds with DBSERVER_CONTAINER_ID:

packint(1) list_id
packint(1) id
packint(1) map_id

where id will be -1 if no container was found, and map_id will be -1 unless the container is an active entity, in which case it will be the id of that entity's current map.

DBCLIENT_SHUTDOWN

string msg

When this message is received, the dbserver will shutdown.

The following steps will occur:

  • All backups are flushed.
  • All mapservers (other than the one used by the client from which this command was sent) are sent DBSERVER_SHUTDOWN and turnstileserver is sent DBSERVER_TS_CRASHEDMAP for each non-static map where mission_info starts with the letter 'E'.
  • dbserver waits for 60 seconds, or until all non-edit-mode mapservers are inactive.
  • The same procedure is run for the mapserver used by the client from which this command was sent.
  • All pending SQL commands are flushed, and dbserver waits for them to finish.
  • dbserver attempts to shut down the logging thread, waiting up to 8 minutes
  • The dbserver process exits

The DBSERVER_SHUTDOWN message sent to mapservers will have terminal set to 1, directing the MapServer to exit.

DBCLIENT_WHO

string cmd

The rest of the request depends on the value of cmd. In all cases, the response is DBSERVER_WHO:

string msg

where the contents of the message is a string intended for display to a user.

serverwho

packint(1) map_id

If map_id is negative, dbserver reports on the number of zone (static), edit mode, and mission maps, and sums the rest of the stats for all of them. Otherwise, dbserver reports on the single map selected.

dbserver reports on the number of players playing and connecting, the number of entities, and the number of monsters.

who

string name

If the named player is online, dbserver reports on their account and auth, group memberships, and location.

supergroupwho

string name

dbserver reports on the supergroup allies and members.

teamupwho, raidwho, levelingpactwho, leaguewho

packint(1) id

dbserver finds the relevant group and reports its members

DBCLIENT_SERVER_STATS_UPDATE

packint(1) num_entities
packint(1) num_players
packint(1) num_monsters
packint(1) num_players_connecting
float32 ticks_sec
float32 long_tick
packint(1) num_hero_players
packint(1) num_villain_players
packint(1) num_relay_cmds
optional packint(9) average_ping
optional packint(9) min_ping
optional packint(9) max_ping

This is message is sent by mapserver to record its stats in ram. It is used for relaying to ServerMonitor and to respond to DBCLIENT_WHO.

DBCLIENT_RELAY_CMD

packint(1) map_id
string msg

If server_id is negative, all active MapServers are selected. Otherwise, the MapServer for this map is selected.

The selected servers are sent DBSERVER_RELAY_CMD.

DBCLIENT_RELAY_CMD_BYENT

packint(1) entity_id
packint(1) force
string msg

If force is not 0 and the entity is not online, they are loaded onto their last map.

dbserver responds with DBSERVER_RELAY_CMD_RESPONSE:

packint(1) success
optional packint(1) online

where success is 1 if the player is online or force is not 0, and online is sent only if success is 1, and will be 1 if the player is online.

DBSERVER_RELAY_CMD is sent to the MapServer where the player is loaded, relaying the command.

DBCLIENT_RELAY_CMD_TOGROUP

packint(1) id
packint(1) list_id
string msg

list_id must be a group, or dbserver will break (bug).

All members of the group identified by list_id and id will have DBSERVER_RELAY_CMD sent to their mapserver.

DBCLIENT_REQ_ONLINE_ENTS

packint(1) arena_map
packint(1) mission_map
packint(1) coed_faction_map
packint(1) coed_universe_map
autobits count
repeated count times:
  autobits entity_id
  packint(1) faction_same_map
  packint(1) universe_same_map

All loaded entities in the list are updated with the map settings given.

The data returned by dbserver is cached, with a 5 second TTL. It will be computed when this message is sent, if necessary.

dbserver responds with [[#DBSERVER_ONLINE_ENTS|DBSERVER_ONLINE_ENTS], including all online players.

DBCLIENT_REQ_ONLINE_ENT_COMMENTS

This request has no body.

dbserver caches the response data with a 5 second TTL.

dbserver will respond with DBSERVER_ONLINE_ENT_COMMENTS:

repeated:
  packint(20) entity_id
  string comment
packint(20) zero // will be 0

One entry will be sent for each logged-in player.

DBCLIENT_PLAYER_KICKED

packint(1) player_id
packint(1) ban

If player_id is not a loaded entity, nothing happens.

Otherwise, dbserver sends AS_KICK_ACCOUNT (when ban is 0) or AS_BAN_USER (when ban is not 0) to authserver:

U32 auth_id
U16 reason

where reason will be 0.

DBCLIENT_REQ_CUSTOM_DATA

bits(32) callback
packint(1) container_id
string limit
string restrict
string columns
packint(1) list_id
string table_name

dbserver runs an sql query on the named table, using the given query parameters, for the container identified by list_id and container_id.

If container_id is 0, dbserver will insert a write barrier before running the query.

It responds with DBSERVER_CUSTOM_DATA:

bits(32) callback
packint(1) container_id
packint(1) row_count
repeated row_count times:
  oneof:
    string attribute
    string str
    packint(1) number
    float32 float
    bits(32) time

The caller has to know the data types in the table in order to parse the packet.

DBCLIENT_EXECUTE_SQL

string statement

The SQL statement is executed on the database. No response is returned. No barriers are used, so ordering is unpredictable.

This is used in exactly one place, in the email system.

DBCLIENT_DISCONNECT_MAPSERVER

packint(1) map_id

If map_id is at least CRASHED_MAP_BASE_ID (90000) then it identifies a CrashedMaps container, which will be deleted.

If map_id is at least 0 and less than CRASHED_MAP_BASE_ID then it identifies a maps container and associated MapServer. If it has a link, that link will be disconnected. Otherwise, its container will be freed immediately. In either case, all entities on the map will be logged out. If it has been over 15 seconds since a message was received for this map, then a CrashedMaps container will be created and special handling for launcher crashes will be run.

If map_id is negative, this process will be run on all MapServers which have not responded in 30 seconds. If map_id is -2, MapServers which are starting will be included, otherwise they will be skipped.

DBCLIENT_PLAYER_RENAME

packint(1) callback
packint(1) entity_id
string name

If entity_id is not loaded, dbservers responds with DBSERVER_CLIENT_CMD_FAILED, error code CONTAINER_ERR_DOESNT_EXIST.

name will be escaped (backslashing \ \n \r \t " ' % characters). If the resulting string is the same as the current name ignoring case, then the name change will be allowed, otherwise it will be checked for collisions with existing entities and will return DBSERVER_CLIENT_CMD_FAILED with error code CONTAINER_ERR_CANT_COMPLETE if there is one.

The entity container will be updated with the new name, and dbserver will respond with DBSERVER_CONTAINER_ACK.

DBCLIENT_PLAYER_CHANGETYPE

packint(1) callback
packint(1) entity_id
packint(1) player_type

If entity entity_id is not loaded, dbserver responds with DBSERVER_CLIENT_CMD_FAILED, error code CONTAINER_ERR_DOESNT_EXIST.

The player type is set to player_type, and dbserver responds with DBSERVER_CONTAINER_ACK.

DBCLIENT_PLAYER_CHANGESUBTYPE

packint(1) callback
packint(1) entity_id
packint(1) player_sub_type

If entity entity_id is not loaded, dbserver responds with DBSERVER_CLIENT_CMD_FAILED, error code CONTAINER_ERR_DOESNT_EXIST.

The player subtype is set to player_sub_type, and dbserver responds with DBSERVER_CONTAINER_ACK.

DBCLIENT_PLAYER_CHANGEPRAETORIANPROGRESS

packint(1) callback
packint(1) entity_id
packint(1) praetorian_progress

If entity entity_id is not loaded, dbserver responds with DBSERVER_CLIENT_CMD_FAILED, error code CONTAINER_ERR_DOESNT_EXIST.

The praetorian progress is set to praetorian_progress', and dbserver responds with DBSERVER_CONTAINER_ACK.

DBCLIENT_PLAYER_CHANGEINFLUENCETYPE

packint(1) callback
packint(1) entity_id
packint(1) influence_type

If entity entity_id is not loaded, dbserver responds with DBSERVER_CLIENT_CMD_FAILED, error code CONTAINER_ERR_DOESNT_EXIST.

The influence type is set to influence_type, and dbserver responds with DBSERVER_CONTAINER_ACK.

DBCLIENT_DEPRECATED

This message is ignored.

DBCLIENT_REQ_ARENA_ADDRESS

DBCLIENT_REQ_SG_ELDEST_ON

DBCLIENT_REQ_SG_CHANNEL_INVITE

DBCLIENT_SGRP_STATSADJ

DBCLIENT_DESTROY_BASE

DBCLIENT_MISSION_PLAYER_COUNT

DBCLIENT_SEND_STATSERVER_CMD

DBCLIENT_REQUEST_SHUTDOWN

DBCLIENT_EMERGENCY_SHUTDOWN

DBCLIENT_OFFLINE_CHAR

DBCLIENT_RESTORE_DELETED_CHAR

DBCLIENT_LIST_DELETED_CHARS

DBCLIENT_BACKUP

DBCLIENT_BACKUP_SEARCH

DBCLIENT_BACKUP_APPLY

DBCLIENT_BACKUP_VIEW

DBCLIENT_REQ_SOME_ONLINE_ENTS

DBCLIENT_OVERRIDE_START_ZONE

DBCLIENT_AUCTION_REQ_INV

DBCLIENT_AUCTION_REQ_HISTINFO

DBCLIENT_AUCTION_XACT_REQ

DBCLIENT_AUCTION_XACT_UPDATE

DBCLIENT_AUCTION_PURGE_FAKE

DBCLIENT_AUCTION_XACT_MULTI_REQ

DBCLIENT_MININGDATA_RELAY

DBCLIENT_SEND_AUCTIONSERVER_CMD

DBCLIENT_ACCOUNTSERVER_CMD

DBCLIENT_ACCOUNTSERVER_SHARDXFER

DBCLIENT_ACCOUNTSERVER_ORDERRENAME

DBCLIENT_GET_PLAYNC_AUTH_KEY

DBCLIENT_ACCOUNTSERVER_CHARCOUNT

DBCLIENT_RENAME_RESPONSE

string auth_name
string name

dbserver finds the game client identified by auth_name and sends it DBGAMESERVER_RENAME_RESPONSE:

string name

DBCLIENT_CHECK_NAME_RESPONSE

autobits auth_id
string result
autobits success
autobits temp_lock_name

dbserver finds the game client link identified by auth_id. If no such link exists, processing ends here.

If success is not 0 and temp_lock_name is not 0, dbserver will add a temporary lock on the name.

dbserver sends the game client DBGAMESERVER_CHECK_NAME_RESPONSE:

autobits success
autobits temp_lock_name

where temp_lock_name will be set to 0 if success is 0, and otherwise will be the same as the request.

DBCLIENT_ACCOUNTSERVER_GET_INVENTORY

DBCLIENT_ACCOUNTSERVER_CHANGE_INV

DBCLIENT_ACCOUNTSERVER_UPDATE_EMAIL_STATS

DBCLIENT_ACCOUNTSERVER_CERTIFICATION_TEST

DBCLIENT_ACCOUNTSERVER_CERTIFICATION_GRANT

DBCLIENT_ACCOUNTSERVER_CERTIFICATION_CLAIM

DBCLIENT_ACCOUNTSERVER_CERTIFICATION_REFUND

DBCLIENT_ACCOUNTSERVER_MULTI_GAME_TRANSACTION

DBCLIENT_ACCOUNTSERVER_TRANSACTION_FINISH

DBCLIENT_ACCOUNTSERVER_RECOVER_UNSAVED

DBCLIENT_ACCOUNTSERVER_LOYALTY_CHANGE

DBCLIENT_ACCOUNTSERVER_LOYALTY_EARNED_CHANGE

DBCLIENT_ACCOUNTSERVER_LOYALTY_RESET

DBCLIENT_MISSIONSERVER_COMMAND

DBCLIENT_MISSIONSERVER_PUBLISHARC

DBCLIENT_MISSIONSERVER_SEARCHPAGE

DBCLIENT_MISSIONSERVER_ARCINFO

DBCLIENT_MISSIONSERVER_BANSTATUS

DBCLIENT_MISSIONSERVER_ALLARCS

DBCLIENT_MISSIONSERVER_ARCDATA

DBCLIENT_MISSIONSERVER_ARCDATA_OTHERUSER

DBCLIENT_MISSIONSERVER_INVENTORY

DBCLIENT_MISSIONSERVER_CLAIM_TICKETS

DBCLIENT_MISSIONSERVER_BUY_ITEM

DBCLIENT_ACCOUNTSERVER_ORDERRESPEC

DBCLIENT_DELETE_PLAYER

autobits entity_id

If a MapServer has entity entity_id locked, it will be sent DBSERVER_FORCE_LOGOUT:

packint(1) entity_id
packint(1) reason

where reason will be -3.

If no MapServer has the entity loaded, then authserver and accountserver will be notified of the logout with reason 6.

The entity container will be moved to offline storage with status kOfflineObjStatus_DELETED.

The entity will then be deleted, removing it from all groups and sending notifications.

DBCLIENT_QUEUE_FOR_EVENTS

DBCLIENT_REMOVE_FROM_QUEUE

DBCLIENT_EVENT_READY_ACK

DBCLIENT_EVENT_RESPONSE

DBCLIENT_MAP_ID

DBCLIENT_TURNSTILE_PING

DBCLIENT_DEBUG_SHARD_XFER_OUT

DBCLIENT_DEBUG_SHARD_XFER_BACK

DBCLIENT_GROUP_UPDATE

DBCLIENT_EVENTHISTORY_FIND

DBCLIENT_CLOSE_INSTANCE

DBCLIENT_REJOIN_INSTANCE

DBCLIENT_PLAYER_LEAVE

DBCLIENT_MAP_WEEKLY_TF_ADD_TOKEN

DBCLIENT_MAP_WEEKLY_TF_REMOVE_TOKEN

DBCLIENT_MAP_WEEKLY_TF_SET_EPOCH_TIME

DBCLIENT_TEST_LOGGING

DBCLIENT_INCARNATETRIAL_COMPLETE

DBCLIENT_QUEUE_FOR_SPECIFIC_MISSION_INSTANCE

DBCLIENT_TS_ADD_BAN_DBID

DBCLIENT_MAP_SET_MARTY_STATUS

bits(1) marty_enabled

This message sends DBSERVER_RELAY_CMD to all MapServers, with:

cmdrelay
SetMARTYStatusRelay %i

populated with marty_enabled.

It also records the state of the flag in server_cfg, which does not do anything (bug: because MapServer flags are only computed on startup).

DBCLIENT_GRANT_CHARSLOT

autobits auth_id
autobits delta

The ShardAccount auth_id will be loaded, and delta will be added to its SlotCount field.

DBCLIENT_PLAYER_UNLOCK

autobits callback_id
autobits entity_id

If entity_id is not loaded, dbservers responds with DBSERVER_CLIENT_CMD_FAILED, error code CONTAINER_ERR_DOESNT_EXIST.

The entity's container is updated to set IsSlotLocked to 0.

The ShardAccount of the entity is updated to set ShowPremiumSlotLockNag to 0.

dbserver responds with DBSERVER_CONTAINER_ACK.

DBCLIENT_ACCOUNT_ADJUST_SERVER_SLOTS

DBCLIENT_UNLOCK_CHARACTER_RESPONSE

DBCLIENT_DEBUG_SET_VIP

autobits auth_id
autobits vip

Nothing happens unless fake auth is enabled.

If fake auth is used, the ShardAccount vip status is set to vip.

DBSERVER_TIMEOFFSET

bits(32) time
float32 timezone_delta

time is expressed as seconds since 2000. time_zone_delta is the difference between UTC and local time, in hours.

dbserver sends this message in response to DBCLIENT_INITIAL_CONNECT. MapServer uses it to approximately synchronise its clock with dbserver, in case MapServer instances are running on machines with incorrectly set clocks.

DBSERVER_CONNECT_DENIED

Not used.

DBSERVER_CONTAINERS

packint(1) user_data
packint(1) list_id
packint(1) count
repeated count times:
  packint(1) id
  packint(1) has_error
  packint(1) is_map_xfer
  packint(1) is_static_map
  packint(1) locked
  packint(1) is_deleting
  packint(1) demand_loaded
  packint(1) member_count
  repeated member_count times:
    packint(1) member_id
  string text

If has_error is 1, then the block for this container is replaced by:

  packint(1) map_id
  packint(1) has_error
  packint(1) error_code

The error_code will be CONTAINER_ERR_DOESNT_EXIST if the container was not found or not loaded, and CONTAINER_ERR_ALREADY_LOCKED if this was an attempt to lock the container and another link already has this container locked. In all cases, errors are on a per-container basis, and the rest of the request will be processed.

This message is used to send containers to the MapServer. It will be sent when:

  • responding to DBCLIENT_REGISTER, to send map containers
  • responding to DBCLIENT_REQ_CONTAINERS
  • broadcasting the results of DBCLIENT_SET_CONTAINERS to interested MapServers
  • loading an entity onto a MapServer, as part of login (when handling DBGAMECLIENT_CHOOSE_PLAYER or DBGAMECLIENT_CHOOSE_VISITING_PLAYER) or map transfer (when handling DBCLIENT_MAP_XFER from another MapServer)
  • when handling DBCLIENT_ADDDEL_MEMBERS, either responding or broadcasting the result

The contents of the container is represented in the text string.

user_data is only set in response to DBCLIENT_REQ_CONTAINERS, and is 0 in other scenarios. It returns the value sent in the request. (bug!!! MapServer packs a pointer into this field, which may break on 64-bit systems)

locked will be 1 if the container has now been locked to this link, and 0 if the locking state is unchanged.

If the container is a group, then a member_id list will be sent. Otherwise, member_count will be 0.

is_map_xfer will be 0 unless the container is an Ent.

is_static_map will be 0 unless the container is a Map.

MapServer handles this message differently depending on whether user_data is set, or on the value of list_id. If user_data is not 0, then MapServer interprets it as a function pointer and calls it. This will be a callback function that was originally passed to dbAsyncContainerRequest or dbSyncContainerRequestCustom.

Otherwise, if the container is an Entity, then MapServer will load all of the containers, generate login cookies for them, and respond with DBCLIENT_CONTAINER_ACK to send the cookies back to dbserver.

Otherwise, if the container is a map, then if this is the first map received since sending DBCLIENT_REGISTER then this is stored as the map for this MapServer, and MissionInfo is parsed. This sets up the MapServer as an arena, sgbase, raid, endgame raid, or mission. Regardless of whether or not this is the first map, the container is read and the map name is added to the name/id lookup table.

For all other scenarios, including the case where dbSyncContainerRequest was called with the no_process flag, the container is simply read into cache. If the container is an Entity, MapGroup, Group, or AutoCommand then MapServer has extra processing to do.

For an Entity:

  • If this Entity is already loaded, and has a client link, then this is a reconnecting client and the old link is disconnected.
  • The Entity is fully unpacked into memory. See Entity_(container)#unpackEnt for a detailed discussion.
  • If the Entity last logged in over 15 minutes ago, then the character is reset (clearing hitpoints, endurance, powers, buffs, toggles, etc)
  • Synchronous container requests are sent for the taskforce, supergroup, teamup, levelingpact, and league which the Entity is a member of, waiting for a response to each before continuing (which means those containers are fully processed)
  • MapListRefresh:%d is broadcast to all members of the teamup and league, with the ID of the current map
  • Alignment is updated based on the map that the Entity has loaded into, if necessary
  • A custom SQL query is sent to dbserver for supergroup members
  • If the Entity is in a supergroup, DBCLIENT_CONTAINER_RELAY is sent for CONTAINER_BASERAIDS (should notify RaidServer that the player has logged in)
  • The Entity is placed on the map, according to dbflags indicating which door they enter from
  • If this is a map transfer, then LinkEnt and Status are sent to dbserver as LOG_SHARDCHAT messages
  • If this is a fresh login, then teamup and league memberships are cleared, taskforce membership is restored, and a task is selected
  • If the character is dead, they are positioned appropriately
  • MapServer attempts to repair corrupted Entities and SuperGroups
  • A login cookie is generated
  • The teamup is updated, and sent to dbserver

For a MapGroup:

  • If this MapGroup has an active event, and it is not currently running, then the relevant script is started

For a Group:

  • If this is the architect taskforce for this MapServer, it is loaded and set up
  • For each member, the relevant parts of the group are unpacked into the Entity
  • If the container is not locked by this message, then deletes and leaders are checked and updates sent to the game clients involved
  • If the group is coed (mixed factions) and this map does not allow that, kick from the team as needed.
  • If the group is a levelling pact, it is applied

For an AutoCommand:

  • It is inserted into or removed from the list of autocommands, replacing any other with the same ID

DBSERVER_CONTAINER_INFO

packint(1) count
string dbserver_status
repeated count-1 times:
  string container_status

This message is sent in response to DBCLIENT_CONTAINER_INFO. The response is returned to the client that sent the query (either the dbquery command-line tool or server command).

DBSERVER_DISCONNECT_ACK

This message has no body and is ignored.

DBSERVER_CONTAINER_STATUS

packint(1) user_data
packint(1) list_id
packint(1) count
repeated count times:
  packint(1) exists
  string status

dbserver sends this message in response to DBCLIENT_REQ_CONTAINER_STATUS.

MapServer interprets user_data as a function pointer and calls it. (Bug: this is probably broken for 64-bit builds)

When used from the dbquery -getstatus command, the results are returned to the client as a message.

Otherwise, the list is assumed to be maps and the strings returned are parsed for information about the status of the MapServer. This is used to check whether players should be transferred onto mission maps.

DBSERVER_CONTAINER_ACK

packint(1) list_id
packint(1) callback
packint(1) count
repeated count times:
  packint(1) entity_id

dbserver sends this message after processing a modification to a container, sent by this MapServer.

If list_id is CONTAINER_ENTS or CONTAINER_SHARDACCOUNT, then this message is ignored.

Otherwise, the entity_id is returned to the sender, using callback to identify where it should go. This is used when creating groups and bases for MapServer to get the ID of the newly created container.

DBSERVER_TEST_MAP_XFER

Not used.

DBSERVER_MAP_REG_CALLBACK

Not used.

DBSERVER_SEND_DOORS

packint(1) count
zipped data

where data is a zipped copy of all the door containers in text format.

MapServer clears its current door list, and replaces it with door entries parsed from this message.

The zipped data is formatted as text strings, with each door container represented as a line:

1 "..."

where the first parameter is the container ID, and the quoted string is a double-escaped copy of the door container.

The door list is used for this MapServer to know where to send an Entity, when it uses a door. Notably, this is how MapServer knows to transfer the Entity to another map, and which map to send it to.

DBSERVER_BROADCAST_MSG

packint(1) list_id
packint(1) msg_type
packint(1) sender_id
packint(1) count
string msg
repeated count times:
  packint(1) id

This is sent by dbserver in response to DBCLIENT_SEND_MSG. It is normally used to send an update to all members of a group, but can also be directed towards a single entity.

msg is a command, followed by a colon, then the rest of the data.

The valid commands are below. If the command is not recognised, this message is ignored.

AllianceChatMsg

The data is split by colons, with the first two fields being the sender's supergroup ID and rank, and the rest being the body of the message.

If this is an allied supergroup and permissions do not allow members of this rank to send messages, then nothing happens. Otherwise, it is sent as a chat message, of type msg_type.

Email

SERVER_SEND_EMAIL_HEADERS is sent to the client.

ChatMsg

The data is sent as a chat message, of type msg_type.

CoHChatMsg

The data is sent as a chat message, of type msg_type. It is considered an enemy message if the entity is a villain.

CoVChatMsg

The data is sent as a chat message, of type msg_type. It is considered an enemy message if the entity is a hero.

StoryarcTaskRefresh

SERVER_CONTACT_STATUS, SERVER_TASK_VISITLOCATION_UPDATE, and SERVER_TASK_STATUS are sent to the entity, with current data.

StoryarcFullRefresh

SERVER_CONTACT_STATUS, SERVER_ACCESSIBLE_CONTACT_STATUS, SERVER_TASK_VISITLOCATION_UPDATE, SERVER_CLUE_UPDATE, SERVER_KEYCLUE_UPDATE, SERVER_SOUVENIRCLUE_UPDATE, and SERVER_TASK_STATUS are sent to the entity, with current data.

MissionComplete

The data is parsed as a mission ID, which is four colon-separated fields: owner, context, subhandle, compoundPos.

SERVER_SEND_FLOATING_INFO is sent to announce mission completion, and if this is a taskforce flashback, SERVER_SEND_DESATURATE_INFO is also sent.

If the teamup is on this mission, it is updated to record success.

MissionFailed

The data is parsed as a mission ID, which is four colon-separated fields: owner, context, subhandle, compoundPos.

SERVER_SEND_FLOATING_INFO is sent to announce mission failure.

If the teamup is on this mission, it is updated to record failure.

MissionStoppedRunning

The data is parsed as a mission ID, which is four colon-separated fields: owner, context, subhandle, compoundPos.

If the teamup is on this mission, and it is on an instanced mission map, it is detached from that map (cleaning up clues etc).

MissionObjective

The data is parsed as a mission objective, which is six comma-separated fields: owner, context, subhandle, compoundPos, objective number, success.

If the teamup is on this mission, the objective is added.

TeamTaskSelected

SERVER_TASK_SELECT is sent.

If this entity is not the teamup leader, then the chat message TeamTaskChanged is sent, with type INFO_SVR_COM.

TaskForceResumeTeam

TaskForceGetCredit

TFChallengeFailed

TFChallengeShowSummary

MapListRefresh

The data is parsed as an integer map_id, and recorded in the team and league as the current map of the sender.

SupergroupRefresh

PaymentRemainTime

ArchitectComplete

ArchitectCompleteMission

TaskForceComplete

DBSERVER_SEND_ENT_NAMES

DBSERVER_SEND_GROUP_NAMES

DBSERVER_FORCE_LOGOUT

DBSERVER_CONTAINER_ID

DBSERVER_SHUTDOWN

packint(1) terminal
string msg

In local server mode, this message is ignored.

If terminal is 0 then the mission shutdown process is run. Otherwise, the MapServer shuts down:

  • All entities are sent to dbserver, and MapServer waits for them all to be acked.
  • All connected clients are logged out, with reason KICKTYPE_FROMDBSERVER.
  • Shared memory is cleaned up.
  • MapServer waits to finish writing its logs.
  • The process exits.

DBSERVER_WHO

DBSERVER_RELAY_CMD

string msg

msg is split on spaces. The first word is interpreted as a command. The commands below are recognised, and all others are ignored.

silenceall

Example usage:

silenceall 1

With a non-zero parameter, this prevents players from sending chat messages.

cmdrelay

Example usage:

cmdrelay
SetMARTYStatusRelay 1

Everything after the first line is parsed as a server command, as if it had been sent with access level ACCESS_USER and no client.

server_sgstat_cmd

cmdrelay_dbid

Example usage:

cmdrelay_dbid 15
conprint "message"

The first parameter to cmdrelay_dbid is an entity ID. If that entity is loaded here, then everything after the first line is parsed as a server command, as if it had been sent by the client for that entity with access level ACCESS_INTERNAL.

If a second optional parameter is given, then responses to the command will be sent to that entity, instead of to the entity which ran the command.

If the entity ID is not loaded in this MapServer, then the rest of the message is sent back to dbserver in DBCLIENT_RELAY_CMD_BYENT, with a cmdrelay_dbid prefix. Only the first parameter is preserved when this happens (bug!!!).

cmdrelay_db_no_ent

Example usage:

cmdrelay_db_no_ent
check_player_name 1 2 "name"

Everything after the first line is parsed as a server command, as if it had been sent with access level ACCESS_INTERNAL and no client.

DBSERVER_LOST_MEMBERSHIP

DBSERVER_CLIENT_CMD_FAILED

 packint(1) fail_code
 string str

MapServer logs the error. If fail_code is CONTAINER_ERR_CANT_COMPLETE_SERIOUS and piggs/texts.pigg does not exist, MapServer will assert (!!!).

Otherwise, fail_code is stored as an errno-like value in last_db_error_code, which is checked by many container operations.

DBSERVER_SEND_MAPNAMES

DBSERVER_SEND_DELETED_CHARS

DBSERVER_OFFLINE_RESTORE_RSLT

DBSERVER_OFFLINE_CHARACTER_RSLT

DBSERVER_ONLINE_ENTS

bits(32) bit_length
bits(32) size
zipped stream

where these three fields describe a byte-aligned bitstream and its contents. The contents of that bitstream are:

repeated:
  packint(20) entity_id
  packint(8) map_id
  packint(8) static_map_id
  packint(4) team_member_count
  packint(1) entity_is_team_leader
  packint(10) hide_field
  packint(10) lfg_field
  packint(6) level
  string archetype
  string origin
  packint(2) player_type
  packint(2) player_type_by_location
  packint(2) player_sub_type
  packint(3) praetorian_progress
  packint(1) arena_map
  packint(1) mission_map
  packint(1) can_co_faction
  packint(1) faction_same_map
  packint(1) can_co_universe
  packint(1) universe_same_map
  bits(32) last_active
  bits(32) member_since
  bits(32) prestige
  packint(8) league_member_count
  packint(1) is_league_leader
packint(20) zero // will be 0

MapServer unpacks this data and stores it. It is used to implement searching for players, when game clients request it.

DBSERVER_MAP_XFER_LOADING

autobits entity_id
bits(1) on

MapServer sends the entity SERVER_MAP_XFER_LOADING. It otherwise ignores this message.

dbserver sends this message to MapServer when it needs to launch a new MapServer, which is expected to take some time.

DBSERVER_MAP_XFER_READY

packint(1) link_id
packint(1) new_map_id

MapServer finds the entity for ths link_id, and updates its status to set map_ready, unset waiting_map_xfer, and record new_map_id as its destination.

DBSERVER_MAP_XFER_OK

packint(1) entity_id
packint(1) map_id
packint(1) ip
packint(1) ip
packint(1) udp_port
packint(1) tcp_port
packint(1) cookie

ip is the same both times. ip, udp_port, and tcp_port are the connection information for the game client to connect to the new MapServer. cookie is copied from the DBCLIENT_CONTAINER_ACK message that triggered this.

MapServer sends SERVER_MAP_XFER to the client for this Entity, forwarding the same information.

DBSERVER_MAP_XFER_FAIL

packint(1) entity_id
string error_message

MapServer sends SERVER_DOOR_CMD to the client for this Entity, and puts the Entity back on its own map as if it had just joined.

DBSERVER_CUSTOM_DATA

DBSERVER_CLEAR_PNAME_CACHE_ENTRY

DBSERVER_TEAM_LEFT_MISSION

This message has no body.

If there is an active mission with an owner, then MapServer processes a missionrequestshutdown command on behalf of that owner.

If there is no active mission or the mission has no owner, then MapServer shuts it down:

  • a DBCLIENT_CLOSE_INSTANCE is sent to dbserver, to notify turnstileserver of the instance closing
  • dbserver marks itself as quitting, and begins the process of transferring all connected players to other maps
  • when no players are connected, MapServer disconnects from dbserver, waits for its logs to finish writing, and exits

DBSERVER_RELAY_CMD_RESPONSE

DBSERVER_ARENA_ADDRESS

DBSERVER_ONLINE_ENT_COMMENTS

DBSERVER_SG_ELDEST_ON

DBSERVER_SG_CHANNEL_INVITE

DBSERVER_SGRP_STATSADJ

DBSERVER_CONTAINER_SERVER_ACK

DBSERVER_CONTAINER_SERVER_NOTIFY

DBSERVER_CONTAINER_RELAY

packint(1) cmd
packint(1) list_id
packint(1) cid
packint(1) user_cmd
packint(1) user_data
packint(1) lock_id
... everything else from the DBCLIENT_CONTAINER_RELAY is copied here

MapServer ignores this message; it is sent to RaidServer.

DBSERVER_CONTAINER_RECEIPT

packint(1) cmd
packint(1) list_id
packint(1) cid
packint(1) user_cmd
packint(1) user_data
packint(1) error_code
string error_msg

DBSERVER_CONTAINER_REFLECT

packint(1) list_id
packint(1) cmd
packint(1) target_count
repeated target_count times:
  packint(1) target_list
  packint(1) target_cid
  packint(1) target_dbid
  packint(1) del
packint(1) count
repeated count times:
  packint(1) id
optionally repeated count times:
  string data

MapServer treats this message as an error for all values of list_id other than CONTAINER_BASERAITS, CONTAINER_ITEMSOFPOWER, and CONTAINER_ITEMOFPOWERGAMES.

DBSERVER_MISSION_PLAYER_COUNT

DBSERVER_SEND_STATSERVER_CMD

DBSERVER_BACKUP_SEARCH

DBSERVER_BACKUP_APPLY

DBSERVER_BACKUP_VIEW

DBSERVER_SOME_ONLINE_ENTS

DBSERVER_AUCTION_SEND_INV

DBSERVER_AUCTION_SEND_HIST

DBSERVER_AUCTION_XACT_CMD

DBSERVER_AUCTION_XACT_ABORT

DBSERVER_AUCTION_XACT_COMMIT

DBSERVER_MININGDATA_RELAY

DBSERVER_AUCTION_XACT_FAIL

DBSERVER_AUCTION_BATCH_INFO

DBSERVER_ACCOUNTSERVER_NOTIFYREQUEST

DBSERVER_ACCOUNTSERVER_NOTIFYTRANSACTION

DBSERVER_ACCOUNTSERVER_NOTIFYSAVED

DBSERVER_ACCOUNTSERVER_CATALOG

autobits catalog_timestamp
autobits auth_timeout
string mtx_environment
string play_span_domain
string play_span_url_home
string play_span_url_categoryview
string play_span_url_itemview
string play_span_url_showcart
string play_span_url_addtocart
string play_span_url_manageaccount
string play_span_url_supportpage
string play_span_url_supportpage_de
string play_span_url_supportpage_fr
string play_span_url_updatetovip
string coh_url_newfeatures
string coh_url_newfeaturesupdate
autobits play_span_store_flags

DBSERVER_ACCOUNTSERVER_CLIENTAUTH

DBSERVER_ACCOUNTSERVER_PLAYNC_AUTH_KEY

DBSERVER_ACCOUNTSERVER_CHARCOUNT

DBSERVER_ACCOUNTSERVER_INVENTORY

DBSERVER_ACCOUNTSERVER_LOYALTY

DBSERVER_CHECK_NAME

DBSERVER_MISSIONSERVER_SEARCHPAGE

DBSERVER_MISSIONSERVER_ARCINFO

DBSERVER_MISSIONSERVER_ARCDATA

DBSERVER_MISSIONSERVER_INVENTORY

DBSERVER_MISSIONSERVER_CLAIM_TICKETS

DBSERVER_SEND_STATSERVER_INACTIVE_ACCOUNT

DBSERVER_MESSAGEENTITY

DBSERVER_CREATE_EMAIL

DBSERVER_MISSIONSERVER_ITEM_BOUGHT

DBSERVER_MISSIONSERVER_ITEM_REFUND

DBSERVER_MISSIONSERVER_OVERFLOW_GRANTED

DBSERVER_MISSIONSERVER_ALLARCS

DBSERVER_MISSIONSERVER_BAN_STATUS

DBSERVER_OVERRIDDEN_AUTHBITS

bits(1024) overridden_auth_bits

DBSERVER_EVENT_WAIT_TIMES

DBSERVER_QUEUE_STATUS

DBSERVER_EVENT_READY

DBSERVER_EVENT_READY_ACCEPT

DBSERVER_EVENT_FAILED_START

DBSERVER_MAP_START

DBSERVER_EVENT_START

DBSERVER_TURNSTILE_PONG

DBSERVER_MISSIONSERVER_ARCDATA_OTHERUSER

DBSERVER_DISABLED_ZONE_EVENTS

repeated string event

DBSERVER_NOTIFY_REACTIVATION

This message has no body.

If MapServer receives this message, then it enables character reactivation globally for this MapServer.

DBSERVER_EVENTHISTORY_RESULTS

DBSERVER_REJOIN_FAIL

DBSERVER_ACCOUNTSERVER_CERTIFICATION_GRANT

DBSERVER_ACCOUNTSERVER_CERTIFICATION_CLAIM

DBSERVER_ACCOUNTSERVER_CERTIFICATION_REFUND

DBSERVER_UPDATE_LOG_LEVELS

repeated LOG_LEVELS times:
  packint(1) log_level

MapServer sets its log levels as directed. It also relays them to ArenaServer directly, as an ARENACLIENT_SET_LOG_LEVELS message, and to RaidServer indirectly by relaying RAIDCLIENT_SET_LOG_LEVELS to the CONTAINER_BASERAIDS container, via dbserver.

DBSERVER_TEST_LOG_LEVELS

DBSERVER_ACCOUNTSERVER_MULTI_GAME_TRANSACTION

DBSERVER_ACCOUNTSERVER_MULTI_GAME_TRANSACTION_COMPLETED

DBSERVER_CLIENT_MESSAGE

autobits entity_id
string message

When MapServer receives this message, it sends a chat message to the connected Entity, of type INFO_SVR_COM.