# Topic: Quick-Suite
# Description: Alternative interface to DGS operations
# FAQ (robot-interface): http://www.dragongoserver.net/faq.php?read=t&cat=215#Entry219
# Forum-discussions:
# - http://www.dragongoserver.net/forum/read.php?forum=10&thread=27755
# Author: Jens-Uwe Gaspar, DGS 'juga'
## /*
## Dragon Go Server
## Copyright (C) 2001-2014 Erik Ouchterlony, Jens-Uwe Gaspar
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU Affero General Public License as
## published by the Free Software Foundation, either version 3 of the
## License, or (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU Affero General Public License for more details.
##
## You should have received a copy of the GNU Affero General Public License
## along with this program. If not, see .
## */
Abstract:
The Quick-Suite provides an alternative interface for mobile and robot clients
to allow operations on DGS objects.
Topics:
1. Introduction
- [MIGR] Migration Strategy
2. Login, Request and Response
a. Login & Logout
b. Request
c. Standard Response
d. List Request & Response
e. Filtered Response
f. Expected Fields
g. Standard Request Parameters
3. Objects
a. "game" - playing a started game
b. "user" - user info
c. "message" - message info, invitations
d. "folder" - message-folders
e. "contact" - contacts
f. "wroom" - game-offers via waiting-room
g. "bulletin" - bulletins
4. Supporting Tools
- [SGF] SGF-download "sgf.php"
- [QST] quick-status "quick_status.php"
- [RSS] RSS-Feed "rss/status.php"
- [WAP] WAP-Feed "wap/status.php"
- [QPL] quick-play "quick_play.php"
5. Errors
- Login Errors
- General Errors
- Game Errors
- Game Move Errors
6. Formats
a. Date-Formats
b. TimeLimit-Formats
7. Classes and Files
8. Possible Future Enhancements
############# TODO TODO TODO ###############
Issues to specify (see also section (8)):
- how to handle DGS-tags in text (messages/posts/etc) on client-side ?
- charsets / encoding / utf-8:
- see http://www.dragongoserver.net/forum/read.php?forum=10&thread=27755#29511
- see http://www.dragongoserver.net/forum/read.php?forum=10&thread=27755#33564
- see http://www.dragongoserver.net/forum/read.php?forum=10&thread=27755#33772
- fair-komi negotiation for game-status KOMI
#-------- (1) Introduction ----------------------------------------------------
The Quick-Suite provides an alternative interface to the DGS objects and operations.
It accepts generic-formatted input and results in a JSON-formatted output.
DGS "objects" represent different sections of the server:
- game : playing game, game-info
- user : users, player, profile
- message : private messages, invitation, disputes
- folder : folders for private messages
- contact : contacts
- wroom : waitingroom, new-game
- bulletin : bulletins
- forum : forums, threads, posts
- tourney : tournaments
- help : FAQ
Each "object" has a different set of "commands", that can be executed to get
information about the "object" or perform operations on the "object".
The new approach also supports and integrates parts of the former approach,
also see section (4) "Supporting Tools":
- [SGF] SGF-download : to download SGF of game
- [QST] quick-status : to get list of games and messages known from status-page
- [RSS] RSS-Feed : similar to quick-status as RSS-feed
- [WAP] WAP-Feed : similar to quick-status as WAP-feed
- [QPL] quick-play : to play game (with incomplete playing-interface)
#-------- (1.MIGR] Migration Strategy -----------------------------------------
Migration strategy of the former into the new approach will cover the steps:
- [SGF] extend the existing SGF-download (sgf.php)
- [QST] extend the existing quick-status (quick_status.php)
- [QPL] refactor the existing quick-play suite to serve as wrapper using
the new approach (quick_play.php) to stay compatible.
In the long term the "quick_play.php" tool will be removed.
#-------- (2) Login, Request and Response -------------------------------------
References:
* JSON - RFC 4627 - The application/json Media Type for JavaScript Object Notation (JSON)
http://tools.ietf.org/html/rfc4627
http://en.wikipedia.org/wiki/Json
#-------- (2a) Login & Logout -------------------------------------------------
A "command" is sent to the server via a GET or POST HTTP-request. The response is
normally sent back with MIME-type "application/json" and contains the respective
result for the requests command. The quick-script always expects a login-cookie
in the HTTP-headers for authentication, which can be created with:
# for possible errors (see "Login Errors" below)
login.php?quick_mode=1&userid=HANDLE&passwd=PASSWORD
# perform operations
...
# disconnect to clear cookies with session
login.php?quick_mode=1&logout=1
Authentication is one purpose for the login, the other is to allow a user-based
quota (and for that the user must be known and must be authenticated to avoid abuse).
#-------- (2b) Request --------------------------------------------------------
The standard request format looks like:
# json-mode returning 'application/json' content-type
quick_do.php?obj=&cmd=&arg=...
# test-mode returning 'text/plain' content-type
quick_do.php?obj=&cmd=&arg=...&test=1
The HTTP-Content-Type of the result is "application/json", except when the optional
"test"-argument is given, in which case the HTTP-Content-Type "plain/text" is used
instead.
#-------- (2c) Standard Response ----------------------------------------------
The standard minimal response is a JSON-formatted text with a quick-suite-version
and an error-code, there can be an optional 'error_msg' element:
{
"version": "1.0.15:13", # DGS_VERSION:QUICK_VERSION
"error": "error_code",
"error_msg": "error message",
"quota_count": 497, # remaining quota-count and quota-expire (if count is 1, the next command will get blocked)
"quota_expire": "2012-03-27 17:34:12"
}
The version-info includes the current DGS_VERSION and the QUICK_VERSION defined in
"include/globals.php". The QUICK_VERSION is increased with every release that changed
some semantics or signature of the quick-interface.
An empty 'error_code' indicates a successful operation, i.e. no errors have occured:
{
"version": "1.0.15:13",
"error": ""
"quota_count": 497, # remaining quota-count and quota-expire
"quota_expire": "2012-03-27 17:34:12"
}
The response may contain additional object- and command-specific return-values.
{
"version": "1.0.15:13",
"error": "",
"quota_count": 497, # remaining quota-count and quota-expire
"quota_expire": "2012-03-27 17:34:12"
"output1": "simple text-value", # simple scalar value
"output2": { # object
"id": 123,
"object": { # nested object
"key": "val"
}
},
"output3": [ 1, 2, 3, "ape", "bear" ] # array-value
}
IMPORTANT NOTE:
Important to note is, that you shouldn't expect a particular order of keys
in the response or its nested return objects.
#-------- (2d) List Request & Response ----------------------------------------
The quick-suite can also return a list of object entries. In this case, the result
always contains several mandatory and some optional standard fields:
{
"list_object": "game", # object-name, corresponds to obj-option
"list_totals": -1, # total list-size; or -1 if total size is unknown
"list_size": 2, # current list-size returned in response, 0=empty
"list_offset": 0, # list offset for paging a result
"list_limit": 20, # number of entries per page; 0=all entries returned
"list_has_next": 0, # 1=has next-page, 0=last page retrieved
"list_order": "key1+,key2-", # list order, can be empty (=no-order); + = ASCending, - = DESCending
"list_header": [ "key1", "key2", ... ], # (optional); field-names for TABLE-list-style
"list_result": [ item1, item2, ... ] # list-entries (array | objects)
}
* NOTE about "list_totals" and "list_size":
- it is not always possible to find out the total number of rows, because that
can be a very expensive query. In such cases, the 'list_totals' is -1.
- the 'list_size' is a redundant information giving the number of entries in
the response from the 'list_result'-array. When the total number of rows
is larger than the given LIMIT, only a subset of items is returned.
The starting offset is 'list_offset', the 'list_size' is the number of
entries in the current result, and 'list_totals' gives the total number
of found rows for the query. However if 'list_totals' is -1, at least you
can check 'list_has_next' to check if there are more "pages" to retrieve.
If 'list_has_next' is 0 the last "page" has been reached.
* NOTE about "list_order":
- the keys returned in 'list_order' refers to the field-names of the command,
e.g. for waitingroom-list: "user.rating-,user.handle+"
- if the key is a name in full upper-case, then it resembles an internal field,
that is not returned in the result, e.g. for game-list of status-view with
next-game-order 'TIMELEFT': "TIMEOUTDATE+,time_lastmove+,id-"
* NOTE about "list_header" (see also example below):
- this field is only used for TABLE-style
- and only if list contains at least one item
- keys of nested objects are written using '.', e.g. "game.message.user.name"
To paginate when using the 'list'-command you can always use the following parameters:
- 'limit' : gives maximum number of rows returned in the response,
if omitted or empty, a default of 10 is used.
can be in range 1..100
- 'off' : gives the starting offset to load the next "page" of data from.
if omitted or empty or negative, a default of 0 is used.
- NOTES:
- These two parameters can always be used, though they are not parsed for every
object-handler. For example, the quick-handler for folders is always returning
all entries regardless of the limit or offset given.
However, such exceptions are documented on the respective object-specs.
The output of objects in a full JSON-format can be quite large, because an object
is normally represented as map of keys with their respective values for EACH item
in the object-list.
Therefore, the quick-suite provides two different formats to return a list of objects,
which can be controlled with the parameter 'lstyle' (list-style):
1. TABLE-style : lstyle=table (default)
2. JSON-style : lstyle=json
JSON-style may be easier to handle than TABLE-style for JavaScript-based clients,
because it can just be used as object. TABLE-style needs some special handling
to access an object-field, though it should be easily possible to convert
a TABLE-style list into a object-based list on client-side.
One disadvantage for JSON-style is, that the output-size can be considerably
larger for big lists (factor 2-10 or more), depending on the number of fields
within a single list-object-item.
Example for TABLE-style:
{
"list_object": "game",
"list_totals": -1,
"list_size": 2,
"list_offset": 0,
"list_limit": 0,
"list_has_next": 0,
"list_order": "",
"list_header": [ "id", "user.id", "user.handle" ],
"list_result": [
[ 111, 1, "guest" ], # object #1
[ 222, 2, "ejlo" ] # object #2
]
}
Example for JSON-style:
{
"list_object": "game",
"list_totals": -1,
"list_size": 2,
"list_offset": 0,
"list_limit": 0,
"list_has_next": 0,
"list_order": "",
"list_result": [
{ # object #1
"id": 111,
"user": {
"id": 1,
"handle": 'guest',
}
},
{ # object #2
"id": 222,
"user": {
"id": 2,
"handle": 'ejlo',
}
}
]
}
#-------- (2e) Filtered Response ----------------------------------------------
The web-site provide a standard way using filters on the lists of the various
table-rows to restrict the returned data. To allow restricting the data-queries
for the quick-suite as well, though only with the defined set of filters as
specified in this spec for the different objects.
A filter can be provided by giving a URL-argument starting with a 'filter_'-prefix.
The available filters for the quick-suite objects are described for the different
commands as:
quick_do.php?... &filter_...=
- FILTER-option:
- 'filter_NAME=VAL' :
NAME stands for the name of the filter.
For example see the 'list'-command for the 'wroom'-object:
- 'filter_suitable=VAL' : suitable-filter
Such a filter normally has a correspondence on the web-site to make the quick-suite
behave similar like the web-site.
#-------- (2f) Expected Fields ------------------------------------------------
Some of the commands can return a large amount of data-fields, though the client
is not interested in all of them. To restrict the response to return only a certain
list of fields, the standard-option 'fields' can be used. For example:
# command with field-restriction
quick_do.php?obj=user&cmd=info&user=guest&fields=handle,rat*
# the result would be for example:
Result (JSON) =
{
"version": "1.0.15:13",
"error": "",
"quota_count": 497,
"quota_expire": "2012-03-27 17:34:12"
"id" : 1,
"handle" : "guest",
"rating_status" : "RATED",
"rating" : "5k (+46%)",
"rating_elo" : "1643.88952636719",
}
This works for "normal" objects and "list"-responses alike.
The syntax for the 'fields'-option is:
- if option is omitted or empty (=''), all fields as given in the specs are returned
- if the option is given, only the specified and standard fields are returned,
standard-fields (always included) are:
version,error*,quota_*,list_*,id
- only the fields on the 1st level can be restricted, fields on (nested) sub-objects
can not be excluded
- fields-option contains a comma-separated list of either a field-name or a field-regex.
field-regex can contain '*' at the end of the field-name matching all fields
starting with the given prefix
#-------- (2g) Standard Request Parameters ------------------------------------
For the 'list'-command for all objects there are a bunch of standard list-parameters,
that can always be used and are therefore not enlisted in the parameter-list for the
respective commands in the object-specs below:
- 'limit' = see section (2d), limits number of returned entries
- 'off' = see section (2d), start position for paginating entries
- 'lstyle' = see section (2d), list-output-style
Additional standard parameters that are available for other objects and commands:
- 'filter_...' = see section (2e), restrict query by certain select-criteria
- 'fields' = see section (2f), return only certain fields
- 'test' = see section (2b), header-type of response
#-------- (3) Objects ---------------------------------------------------------
The DGS "objects" currently supported are:
a) "game" - playing a started game, game-info
b) "user" - user-info
c) "message" - message-info, invitations
d) "folder" - message-folders
e) "contact" - contacts
f) "wroom" - waiting-room
g) "bulletin" - bulletins
Notes:
- "corresponding pages" = pages of web-interface to perform similar operations
- possible errors of each command are given as reference at command-description,
referring into Error-section (5).
#-------- (3a) Objects - "game" -----------------------------------------------
Purpose:
The quick-suite for the game-object allows the following operations on a game:
- retrieve information about a game (info, game-notes);
corresponding pages: "game.php", "gameinfo.php"
- save game-notes
- retrieve list of games;
corresponding pages: "status.php", "quick_status.php", "show_games.php"
- play the full-cycle of a game after it has been initiated:
corresponding pages: "game.php", "confirm.php"
- delete the game within first 10 moves
- setting free handicap stones
- playing all moves, including pass-moves
- scoring the game, resume playing on dissent
- resign the game
The quick-suite was planned to serve as replacement for the former limited
aproach of "quick_play.php" to play a game.
Request:
quick_do.php?obj=game&cmd=&gid=&move_id=&move=&msg=&with=&fmt=&toggle=&agree=
# info | get_notes
quick_do.php?obj=game&cmd=&gid=&with=
# save_notes | hide_notes | show_notes
quick_do.php?obj=game&cmd=&gid=¬es=
# list
quick_do.php?obj=game&cmd=list&view=&with=&uid=&filter_...=
Options:
= "info" | "list" | "delete" | "set_handicap" | "move" | "resign" | "status_score" | "score" |
"get_notes" | "save_notes" | "hide_notes" | "show_notes"
= for "score"-command: give agreement with current state of stones (dead/alive/neutral/dame) and score
- 1 = agree
- 0 = disagree (default)
- NOTE: agreement could be represented by an empty MOVES-argument, but to prevent "slip"
in client, it's specified explicitly by giving the AGREE-argument.
= optional filter-options (see commands)
= output-format for coordinates (default is "sgf"):
- "sgf" : SGF-format without separator, e.g. "bcefnj"
- "," : SGF-format with comma-separator, e.g. "bc,ef,nj"
- "board" : board-coordindates with comma-separator, e.g. "b17,e14,o10"
- NOTE about lengths of output for different formats:
sgf-format < ','-format < board-format, e.g. 900 < 1250 < 1450 bytes
= integer
- reference game to perform game-operation on
= message
- optional game-message on game-operation
= context for move
- move_id = current DGS-move-number as stored in db in Games.Moves,
which also counts in handicap-stones and pass/scoring-"moves".
Providing context for game-operation to avoid errorneous states like:
- (a) multi-players account with simultaneous logins or
- (b) (duplicate move commitment) if one player hit twice the validation button
during a net lag, and/or
- (c) if the opponent had already played between the two calls
= move | moves | "pass"
- move = single move-coordinate in specified mode-format
- moves = list of coordinates in specified mode-format (see below)
- there are two mode-formats:
- moves are given in SGF-coordinates (lower letters), e.g. "bc",
specified in http://www.red-bean.com/sgf/go.html
SGF-coordinates may be written with or without comma-separation,
because one coordinate-pair is always two letters.
SGF-coordinates without comma is also used as default,
if the mode-format could not be determined.
- moves are given in board-coordinates (labels), e.g. "b17"
be aware, that board-coordinates skip the 'i'-character
- Examples:
- sgf-mode (without comma), e.g. "bcpqmoeq"
- sgf-mode (comma-separated), e.g. "bc,pq,mo,eq"
- label-mode (comma-separated), e.g. "b17,q3,n5,e3"
= private game-notes
- optional game-notes for game-notes-operations
= toggle-mode for "status_score" and "score" commands
- "all" (default) = each given coordinate-point toggles the point-state and
adjacent points of the same "group" (as the GUI does it)
- "uniq" = given coordinate-points toggle groups in a unique fashion,
i.e. points are only toggled once for all togglings if they belong to the same unique group.
= integer | 'mine'
- user-id (integer)
- 'mine' = logged-in user
= view for game-list
= optional with-option to include additional data-fields (see commands)
Commands:
"info" : retrieve game-information
- required opts: GAME_ID
- optional opts: WITH
- WITH-option:
- 'user_id' : additionally return user_id-data for black + white game-users: handle, name, country, rating, rating_elo, last_access
- 'prio' : additionally return the games priority set by the user, otherwise the field is not included
- 'notes' : additionally return the starting text (ca. 30 chars) of the logged-in users private game-notes
- 'ratingdiff' : additionally return the rating-diff for finished games for black + white game-users
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- unknown_game : invalid game
- Result (JSON) =
{
"id" : 123456, # game-id
"double_id" : 0, # > 0 if double-game, < 0 if double-game deleted; abs(double_id) == ref to other game-id
"tournament_id" : 0, # tournament-id > 0 if game is part of tournament
"game_action" : 2, # game-action as defined for [4.QST]
"status" : "PLAY", # game-status: KOMI | SETUP | PLAY | PASS | SCORE | SCORE2 | FINISHED
"flags" : "HIDDENMSG", # flags (comma-separated): HIDDENMSG (game contains hidden-messages), ADMRESULT (admin ended game),
# TGDETACHED (detached tournament-game, see 'specs/db/table-Tournaments.txt'),
# ATTACHEDSGF (there are SGFs attached to game), NO_RESULT (game ended with NO-RESULT, set by game-admin)
"score" : "", # score for finished game only (same format as for game-object status_score-command); '' (=empty) if game not finished
"game_type" : "GO", # GO | TEAM_GO(N:M) | ZEN_GO (N); N,M >= 1
"rated" : 1, # 0=unrated, 1=rated
"ruleset" : "JAPANESE", # ruleset: JAPANESE | CHINESE
"size" : 19, # board-size
"komi" : 6.5, # komi
"jigo_mode" : "KEEP_KOMI", # only relevant for fair-komi: KEEP_KOMI, ALLOW_JIGO, NO_JIGO
"handicap" : 0, # handicap-stones
"handicap_mode" : "FREE", # STD=standard-handicap, FREE=free-handicap
"shape_id" : 0, # shape-id > 0 if game was started as shape-game
"time_started" : "YYYY-MM-DD hh:mm:ss", # game started time
"time_lastmove" : "YYYY-MM-DD hh:mm:ss", # last-moved (also game-end-time if finished)
"time_weekend_clock" : 1, # 1=time-running on weekend, 0=otherwise
"time_mode" : "CAN", # time-mode: FIS=Fischer-time, JAP=japanese-time, CAN=canadian-time
"time_limit" : "C: 14d + 15d / 8", # initial time-settings for game (like in waiting-room), see section (6b) "TimeLimit-Formats"
"my_id" : 111, # user-id of logged-in user (redundant in each element, but included if logged-in user-id unknown)
"move_id" : 75, # move-id, required as context for playing via game-quick-suite
"move_count" : 75, # number of moves
# the following 4 fields are omitted for finished games
"move_color" : "B", # B=black-to-move, W=white-to-move
"move_uid" : 111, # user-id to move next
"move_opp" : 222, # opponent of user-id
"move_last" : "bc", # SGF-format of last-move ("" for non-board-move, e.g. pass/scoring/setup)
# the following 2 fields are omitted for finished games
"prio" : 0, # games-priority, 0 if not set or loaded; field only loaded if WITH-option contains 'prio' used AND status-games ordered by prio
"notes" : "", # beginning of game-notes (if existing but only for logged-in user); field only present if WITH-option contains 'notes' used
"black_user" : { # black-user object-info
"id" : 111, # USER_ID
# the following fields only if WITH-option contains 'user_id'
"handle" : "black-handle",
"name" : "black-name",
"country" : "de",
"rating" : "3k (-7%)", # current DGS rating | "" (=no rating)
"rating_elo" : "1792.59326171875", # current DGS elo-rating | "" (=no rating)
"last_access" : "YYYY-MM-DD hh:mm:ss",
},
"black_gameinfo" : { # game-info of black-user
"prisoners" : 3, # prisoners
"remtime" : "C: 1d 10h (+ 15d / 8)", # remaining-time (same format as for quick-status, see [4.QST]);
# - field only filled for games where black or white user is logged-in user
# - field empty for finished games
"rating_start" : "3k (-7%)", # start-rating
"rating_start_elo" : "1792.59326171875", # start-rating ELO
# the following 3 fields are only included if the game is finished, omitted otherwise
"rating_end" : "3k (-7%)", # end-rating
"rating_end_elo" : "1792.59326171875", # start-rating ELO
"rating_diff" : "+0.23", # rating-diff, field only included if WITH-option contains 'ratingdiff'
},
"white_user" : { # white-user object-info
# same fields as described above for 'black_user'
},
"white_gameinfo" : { # game-info of white-user
# same fields as described above for 'black_gameinfo'
}
}
"list" : retrieve list of games
- required opts: VIEW
- optional opts: USER_ID, WITH, LIMIT, FILTER
- VIEW-option:
- 'status' : ask for status-games (=own running games where to move in)
- LIMIT-option may be 'all' to return all status-games in one go
- available WITH-options: user_id, prio, notes
- USER_ID-option is restricted to logged-in user (or equivalent '' | 0 | 'mine' )
- 'running' : ask for running games for user
- available WITH-options: user_id, notes
- USER_ID-option contains user-id to show running games for
- 'finished' : ask for running games for user
- available WITH-options: user_id, ratingdiff
- USER_ID-option contains user-id to show finished games for
- 'observe' : ask for all observed games (USER_ID-option 'all'), or else for observed games of logged-in user
- available WITH-options: user_id
- USER_ID-option ='all' : all observed games
- USER_ID-option ='mine' (or equivalents): like "games i'm observing" from web-site
- USER_ID-option:
- empty | 0 = default, for all views the default-USER_ID is 'mine'
- integer = use other user-id (can be logged-in user-id)
- 'mine' = use logged-in user-id
- 'all' = only allowed for 'observe'-view
- WITH-option:
- 'user_id' : additionally return user_id-data for black + white game-users: handle, name, country, rating, rating_elo, last_access
- 'prio' : additionally return the games priority set by the user, otherwise the field is not included
- 'notes' : additionally return the starting text (ca. 30 chars) of the logged-in users private game-notes
- 'ratingdiff' : additionally return the rating-diff for finished games for black + white game-users
- LIMIT-option:
- only for VIEW-option 'status', the LIMIT-option can be 'all' to return all status-games in one go
- FILTER-options:
- 'filter_mpg=VAL' :
- VAL = '1' : find all / filter on multi-player-games
- VAL = '0' : normal games-result as web-page (default)
- 'filter_tid=VAL' : filter on only given tournament-id
- IMPORTANT NOTES: "comparison between web-site and quick-suite"
* The quick-suite game-list uses the same kind of views as the web-site does.
So there is no list of ALL games, but only certain views on them, namely:
- 'status'-view = like 'status.php', running games of own (logged-in user) where to move in next
- 'running'-view = like 'show_games.php', user-specific running games
- 'finished'-view = like 'show_games.php', user-specific finished games
- 'observe'-view = like 'show_games.php', games i'm observing, OR all observed games (by all users)
* The views for ALL running or ALL finished games is not supported by the quick-suite,
because the query is very expensive and would need to be restricted as the web-site is
to make it efficient enough.
* The web-site shows the data-fields differently for "my running games" and "my finished games".
These views assume a fix "user" (logged-in user) and show only data-fields for the "opponent".
Out of consistency-reasons the quick-suite does not return "opponent" and "user"-data,
but always for all views show data-fields for the Black- and White-user-roles
with additional fields 'my_id', 'move_color', 'move_uid' and 'move_opp' to determine
the roles of "user" and "opponent".
To have the same "view" as the web-site, the client of the quick-suite must determine
the "user" and "opponent" matching it to the black- and white-user.
Example:
- result-fields: my_id=111, move_color=B, move_uid=222, move_opp=111
- then the logged-in users user-id is 111, so the "user" would be 111 and
the "opponent" would be 222. With this check the "black_user.id" and
"white_user.id"-field to get the according color the user or opponent has.
If the "black_user.id" is 222, then the respective game-info can
be found in the "black_gameinfo"-object.
* Finally for multi-player-games (MPGs) the same "restrictions" apply as for the web-site.
That means, the normal quick-suite game-lists could contain some multi-player-games,
but only as long as the requested user-id has the role of the Black or White-user.
To get a game-list with the quick-suite to all MPGs of a specific user, the client has
to use the 'mpg' FILTER-option, adding 'filter_mpg=1' to the URL-arguments.
For example, the "opponent" for the result shown for the "info"-command above is 222,
indicated by the 'move_opp'-field. Or determine the opponent by the 'move_color'-field.
If the value is 'B', then the opponent has the White color, so the opponents data
can be found in the "white_..."-structures.
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- Result (JSON) = result-list see section (2d) with list of objects dependent on view:
- only the field-names for the different views are listed here,
- the fields content and semantics are the same as for the game-object "info"-command (see above (3a))
* VIEW = 'status' | 'running' | 'finished' :
- full set of fields is returned for each list-element as for "info"-command (exceptions are described there)
* VIEW = 'observe' (all observed games OR games i'm observing) :
- full set of fields is returned for each list-element as for "info"-command
- only for "all observed games" the following additional fields are appended to the result:
{
"obs_count" : 3, # number of observers of the game
"obs_mine" : 1, # 1=observed game is one of logged-in user, 0=otherwise
}
"delete" : deletes specified game
- required opts: GAME_ID, MOVE_ID
- optional opts: MESSAGE
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- unknown_game : invalid game
- invalid_action : tried to delete game after first 10 moves
"set_handicap" : sets handicap stones at start of game
- required opts: GAME_ID, MOVE_ID, MOVES
- MOVE = moves : list of coordinates of the handicap-stone placement
- optional opts: MESSAGE
- Errors:
- all errors of: [E-LOGIN], [E-GEN], [E-GAME]
- invalid_action : tried to set handicap too early, too late,
as white-player or in game without handicap
- wrong_number_of_handicap_stone : number of set handicap stones
do not match required handicap
"move" :
- required opts: GAME_ID, MOVE_ID, MOVES
- MOVES = move : single move to submit, move="pass" for passing move
- optional opts: MESSAGE
- Errors:
- all errors of: [E-LOGIN], [E-GEN], [E-GAME], [E-GAMEMOVE]
- early_pass : pass-move forbidden as first move or before setting handicap
- invalid_action : pass-move only allowed in PLAY or PASS status,
i.e. only allowed directly after other pass-move or after normal move
- illegal_position : invalid coordinates used for move,
or coordinates given that are occupied by other stone
- suicide : move forbidden because it would be suicide
- ko : move forbidden because of ko
- move_problem : prisoner-calculation wrong -> contact admin
"resign" : resigns specified game
- required opts: GAME_ID, MOVE_ID
- optional opts: MESSAGE
- Errors:
- all errors of: [E-LOGIN], [E-GEN], [E-GAME], [E-GAMEMOVE]
"status_score" : verify game-score and state of stones (dead, alive, neutral, dame)
- required opts: GAME_ID, MOVE_ID, MOVES
- MOVE = coords : list of coordinates that 'state' should be "switched"
- optional opts: MESSAGE (will be ignored), FORMAT, TOGGLE
- Errors:
- all errors of: [E-LOGIN], [E-GEN], [E-GAME], [E-GAMEMOVE]
- invalid_action : bad game-status for scoring step (only SCORE|SCORE2)
- invalid_switch : if state of coordinate can not be switched
- illegal_position : invalid coordinates used for stones to switch state
- Result (JSON) =
{
"ruleset" : "CHINESE", # game-ruleset
"score" : 0 | "VOID" | "W+7" | "B+2.5" | "W+R" | "B+T" | "W+F",
# 0=jigo, or
# "VOID"=no-result, or
# "[col]+[res]" with col: 'B' (=Black won), or 'W' (=White won), and
# res : 'R' (=won by resignation), 'T' (=won by timeout), 'F' (=won by forfeit), or number of points
# format of coordinates depends on FMT-parameter
"dame" : "...", # coords*
"neutral" : "...", # coords* (switchable)
"white_stones" : "bc...", # coords*
"black_stones" : "aa...", # coords*
"white_dead" : "...", # coords*
"black_dead" : "...", # coords*
"white_territory" : "...", # coords*
"black_territory" : "...", # coords*
}
"score" : disagree with dead/alive/neutral-state of stones, agree on stones-state finishing game
- required opts: GAME_ID, MOVE_ID, MOVES
- MOVE = coords : list of coordinates of which the 'state' should be "switched"
- optional opts: MESSAGE, FORMAT, TOGGLE, AGREE
- Notes:
- to agree and finish game accepting the score, give AGREE argument
- to disagree with current stones-state give move-coordinates to toggle
- Errors:
- all errors of: [E-LOGIN], [E-GEN], [E-GAME], [E-GAMEMOVE]
- invalid_action :
- bad game-status for scoring step (only SCORE|SCORE2)
- on "score"-command agreement-mismatch, either agreement was expected but there are
toggled state of stones, or disagreement was expected but no state of stones is toggled
- invalid_switch : if state of coordindate can not be switched
- illegal_position : invalid coordinates used for stones to switch state
"get_notes" : retrieve game-notes
- required opts: GAME_ID
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- unknown_game : invalid game
- Result (JSON) =
{
"hidden" : "0", # hidden-state of game-notes on game-page: 1=hidden, 0=shown
"notes" : "", # users game-notes (only for logged-in user)
}
"save_notes" : save private game-notes for game
- required opts: GID, NOTES
- to remove notes use empty NOTES-argument
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- Result (JSON) =
{
"error_texts" : [ # empty array, if no "error" returned; otherwise list of error-texts
"err1", "err2", ... # free error-texts
],
}
"hide_notes" : hide private game-notes for game
- required opts: GID
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- Result (JSON) =
{
"error_texts" : [ # empty array, if no "error" returned; otherwise list of error-texts
"err1", "err2", ... # free error-texts
],
}
"show_notes" : show private game-notes for game
- required opts: GID
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- Result (JSON) =
{
"error_texts" : [ # empty array, if no "error" returned; otherwise list of error-texts
"err1", "err2", ... # free error-texts
],
}
Examples of game-playing cycle:
# login setting cookie in HTTP-header storing: handle, sessioncode
login.php?quick_mode=1&userid=user&passwd=userpassword
# retrieve list of games to play in
# (syntax given in commented line starting with '# comment')
quick_status.php?order=0
quick_status.php?user=user
quick_status.php?uid=123
do_quick.php?obj=game&cmd=list&view=status&uid=123&lstyle=table
# download game with moves
# - marked-dead-stones stored in MA-property
# - move_id stored in XM-private-property
# - other game-parameters
#
# parameters:
# quick_mode=0|1 : 1 = ignore errors
# gid=1234|game1234 : game-id
# no_cache=0|1 : 1 = disable cache (expire-header)
# owned_comments=0|1|N : 1 = if set try to return private comments (for players only) including private notes on game,
# 0 = return only public comments
# N = return NO comments or notes
# inline=0|1 : 1 = use Content-Disposition type of "inline" to directly start assigned application
# bulk=0|1 : 1 = use special filename-pattern (omit handicap if =0 and result if unfinished game):
# DGS-_YYYY-MM-DD_(H)K(=)_-.sgf
sgf.php?gid=12345&owned_comments=1&quick_mode=1
# (optional) setting handicap stones
quick_do.php?obj=game&cmd=set_handicap&gid=12345&move_id=0&move=q16,b4&msg=Onegaishimasu
# (first) regular move (move_id=0)
quick_do.php?obj=game&cmd=move&gid=12345&move_id=0&move=q3
# regular move
quick_do.php?obj=game&cmd=move&gid=12345&move_id=1&move=c17
# pass moves
quick_do.php?obj=game&cmd=move&gid=12345&move_id=2&move=pass
quick_do.php?obj=game&cmd=move&gid=12345&move_id=3&move=pass
# scoring-phase: verify score & assess dead/alive-status
quick_do.php?obj=game&cmd=status_score&gid=12345
quick_do.php?obj=game&cmd=status_score&gid=12345&toggle=uniq&move=c17,q3
quick_do.php?obj=game&cmd=score&gid=12345&move_id=4&toggle=uniq&move=c17,q3
# scoring-phase: verify score + disagree on score
quick_do.php?obj=game&cmd=status_score&gid=12345&move_id=5
quick_do.php?obj=game&cmd=score&gid=12345&move_id=5&move=q16,d4
# scoring-phase: verify score + agree on score
quick_do.php?obj=game&cmd=status_score&gid=12345&move_id=5
quick_do.php?obj=game&cmd=score&gid=12345&move_id=5&move=&agree=1
# scoring-phase: resume playing (on disagreement)
quick_do.php?obj=game&cmd=status_score&gid=12345&move_id=5
quick_do.php?obj=game&cmd=move&gid=12345&move_id=5&move=r14
# resign
quick_do.php?obj=game&cmd=resign&gid=12345&move_id=6
# delete (only on first 10 moves)
quick_do.php?obj=game&cmd=delete&gid=12345&move_id=6
# retrieve game-information (with all possible fields)
do_quick.php?obj=game&cmd=info&gid=12345&lstyle=json&with=user_id,prio,notes,ratingdiff
# retrieve list of (all) my status-games
do_quick.php?obj=game&cmd=list&view=status&limit=all&with=user_id,prio,notes
# retrieve list of my running-games in JSON-style list-format
do_quick.php?obj=game&cmd=list&view=running&uid=mine&lstyle=json&with=user_id
do_quick.php?obj=game&cmd=list&view=running&uid=0
do_quick.php?obj=game&cmd=list&view=running
do_quick.php?obj=game&cmd=list&view=running&with=user_id,notes
# retrieve list of other users running-games
do_quick.php?obj=game&cmd=list&view=running&uid=2
# retrieve list of my finished-games
do_quick.php?obj=game&cmd=list&view=finished&with=user_id,notes,ratingdiff
# retrieve list of other users finished-games
do_quick.php?obj=game&cmd=list&view=finished&uid=2
# retrieve list of games i'm observing
do_quick.php?obj=game&cmd=list&view=observe
# retrieve list of all observed games
do_quick.php?obj=game&cmd=list&view=observe&uid=all
# get game-notes
do_quick.php?obj=game&cmd=get_notes&gid=12345
# save game-notes, hide + unhide
do_quick.php?obj=game&cmd=save_notes&gid=12345¬es=NotesText
do_quick.php?obj=game&cmd=hide_notes&gid=12345
do_quick.php?obj=game&cmd=show_notes&gid=12345
#-------- (3b) Objects - "user" -----------------------------------------------
Purpose:
The quick-suite for the user-object allows to
- retrieve public information about a user;
corresponding pages: "userinfo.php"
Request:
quick_do.php?obj=user&cmd=&uid=&user=
Options:
= "info"
= integer
= string
- reference user to perform user-operation on
- USER_ID is the unique user-id (uid),
e.g. http://www.dragongoserver.net/userinfo.php?uid=1
- USER_HANDLE is the unique user-id (handle),
e.g. http://www.dragongoserver.net/userinfo.php?user=guest
- only one argument for or can be used
Commands:
"info" : returns public user-info
- optional opts: USER_ID|USER_HANDLE
- if USER_ID and HANDLE is omitted, the ID of the logged-in user is used per default.
This can be used to check if and which user is logged-in.
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- not_logged_in : returned if not logged-in;
omit USER_ID|HANDLE to check it still logged-in (and which user)
- invalid_args : bad parameters (missing user-id)
- unknown_user : unknown user-id specified
- Result (JSON) =
{
"id" : 1, # USER_ID
"handle" : "guest", # USER_HANDLE
"type" : "", # user types (comma-separated): pro teacher bot
"name" : "name", # user name
"country" : "se", # DGS country-code, e.g. http://www.dragongoserver.net/images/flags/se.gif
"picture" : "", # picture-filename, e.g. http://localhost/dev/userpic/5318.png?t=YYYYMMDDhhmmss
"vacation_left" : 25, # vacation days left
"vacation_on" : "2d 7h", # on-vacation ("" = not-on vac.)
"register_date" : "YYYY-MM-DD", # register-date
"last_access" : "YYYY-MM-DD hh:mm:ss", # date of last access (website; in users time-zone; can be empty)
"last_quick_access" : "YYYY-MM-DD hh:mm:ss", # date of last access (quick-suite; in users time-zone; can be empty)
"last_move" : "YYYY-MM-DD hh:mm:ss", # date of last move (in users time-zone; can be empty)
"rating_status" : "RATED", # NONE | INIT | RATED
"rating" : "5k (+46%)", # DGS rating | "" (=no rating)
"rating_elo" : "1643.88952636719", # DGS elo-rating | "" (=no rating)
"rank" : "5k EGF", # user rank-info (contains HTML)
"open_match" : "ask later", # user open-for-match-info (contains HTML)
"games_running" : 5, # number of running games
"games_finished" : 50, # number of finished games
"games_rated" : 10, # number of (finished) rated games
"games_won" : 8, # number of (finished rated) won games
"games_lost" : 2, # number of (finished rated) lost games
"games_mpg" : 0, # number of started multi-player-games
}
- Result Values:
- rating_status:
- NONE = has no rating
- INIT = has rating but no rated game yet
- RATED = started/played rated game (has a rating)
Examples for user-commands:
# login setting cookie in HTTP-header storing: handle, sessioncode
login.php?quick_mode=1&userid=user&passwd=userpassword
# retrieve user-info
quick_do.php?obj=user&cmd=info&user=guest
#-------- (3c) Objects - "message" --------------------------------------------
Purpose:
The quick-suite for the message-object allows to
- retrieve private message, send new message, reply to message;
corresponding pages: "message.php"
- move message to other folder, delete message, list messages;
corresponding pages: "message.php", "list_messages.php",
- send new invitation, accept game-invitation message, decline game-invitation message;
corresponding pages: "message.php"
Request:
quick_do.php?obj=message&cmd=&mid=&ouid=&ouser=&subj=&msg=&folder=&with=
# list
quick_do.php?obj=message&cmd=list&with=&filter_...=
# send new invitation
quick_do.php?obj=message&cmd=send_inv&to_uid=&to_user=&msg=&folder=&gs_...=
# dispute invitation
quick_do.php?obj=message&cmd=dispute_inv&mid=&msg=&folder=&gs_...=
Options:
= "info" | "list" | "send_msg" | "move_msg" | "delete_msg" | "accept_inv" | "decline_inv" | "send_inv" | "dispute_inv"
= optional filter-options (see commands)
= integer
- target folder
- standard folders: 1=MAIN, 2=NEW, 3=REPLY, 4=TRASH, 5=SENT
- user-specific folders (only folder-id): >= 6
= game-settings for invitation or dispute
- see "send_inv"-command for list of game-settings
= text-body of message
- message-text for message-operation
= integer
- message-id referencing private DGS-message to perform message-operation on
- message-id to reply to for "send_msg/accept_inv/decline_inv"-command
= integer
= string
- OTHER_UID : specific user-id for bulk-message to identify unique entry
- OTHER_UID|OTHER_HANDLE : recipient of message:
- OTHER_UID is the unique user-id (uid),
e.g. http://www.dragongoserver.net/userinfo.php?uid=1
- OTHER_HANDLE is the unique user-id (handle),
e.g. http://www.dragongoserver.net/userinfo.php?user=guest
- only one argument for or can be used for sending message
= title of message
= integer
= string
- mutual exclusive options, one of them must be used though
- TO_UID : recipient user-id for sending invitation or dispute
- TO_HANDLE : recipient user-handle for sending invitation or dispute
= optional with-option to include additional data-fields (see commands)
Commands:
"info" : returns private message
- required opts: MESSAGE_ID
- optional opts: OTHER_UID (for bulk-message), FOLDER, WITH
- WITH-option:
- 'user_id' : additionally return user_id-data (handle + name + rating) for message correspondent
- 'folder' : additionally return folder-data (name + color_bg + color_fg) for message
- Important Notes:
* using "info"-command will NOT mark message as read (like GUI on message-read),
but with the FOLDER-option a target folder to move the message into can be given.
If a target folder is given, but the message needs a reply (e.g. for invitations),
the REPLY-folder will be used instead as target-folder (if another folder was given).
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- invalid_args : bad parameters (missing message-id)
- unknown_message : unknown message-id specified
- Result (JSON) = // also see specs/db/table-Messages.txt
{
"id" : 1, # message-id
"user_from" : {
"id" : 111, # user-id of sender, 0=server-message
# the following fields only if WITH-option contains 'user_id' and id > 0
"handle" : "user1", # USER_HANDLE
"name" : "name1", # user name
"rating" : "5k (+46%)", # DGS rating | "" (=no rating)
"rating_elo" : "1643.88952636719", # DGS elo-rating | "" (=no rating)
},
"user_to" : {
"id" : 222, # user-id of receiver
# the following fields only if WITH-option contains 'user_id' and id > 0
"handle" : "user2", # USER_HANDLE
"name" : "name2", # user name
"rating" : "5k (+46%)", # DGS rating | "" (=no rating)
"rating_elo" : "1643.88952636719", # DGS elo-rating | "" (=no rating)
},
"type" : "NORMAL", # message-type (see specs/db/): NORMAL | INVITATION | DISPUTED | RESULT
"flags" : "", # flags (comma-separated): BULK (multi-receiver bulk-message)
"folder" : {
"id" : 2, # folder-nr (<0 destroyed, 0-5 system-folder, >= 6 user-folder)
# the following fields only if WITH-option contains 'folder'
"name" : "New", # folder-name (lang-dependent)
"system" : 1, # 1=system-folder, 0=user-folder
"color_bg" : "F7F5E399", # folder background-color (incl. alpha-channel) in hex-format
"color_fg" : "000000", # folder foreground-color (=font-color) in hex-format
},
"created_at" : "YYYY-MM-DD hh:mm:ss", # creation-date of message
"thread" : 0, # message-id of first message in a message-thread, 0=system-message
"level" : 0, # thread-level of message-thread (starting at 0)
"message_prev" : 0, # message-id of message that has been replied to
"message_hasnext" : 1, # 0=no-answer for current message, 1=there are answer(s) to this message
# find answers with "list"-command and 'answers'-filter
"can_reply" : 1, # 1=reply allowed, 0=reply forbidden
"need_reply" : 2, # 2=message needs reply, 1=message has been replied, 0=no reply needed
"game_id" : 0, # game-id for game-related message (e.g. invitation); game may be deleted
"subject" : "boo", # subject of message
"text" : "haha", # content of message
# additional fields set, if message is of type INVITATION
"game_status" : "INVITED", # game-status:
# - "INVITED" = active invitation
# - "" (empty) = invitation declined, game-info deleted
# - other-status = invitation accepted, normal game-status -> see (3a) 'status'-field for "info"-command
"game_settings" : { # 'game_settings' only present, if game_status == INVITED
"game_type" : "GO", # always 'GO' for invitations (e.g. no multi-player-games for invites)
"game_players" : "1:1", # always '1:1' for invitations (e.g. no multi-player-games for invites)
"handicap_type" : "conv", # see HTYPE_... in 'include/game_functions.php':
# conv, proper, nigiri, double, black, white, auko_sec, auko_opn, div_ykic, div_ikyc
# see also section (3f) wroom-object "info"-command "handicap_type"-field
"shape_id" : 0, # shape-id > 0 if game was started as shape-game
"rated" : 1, # 0=unrated, 1=rated
"ruleset" : "JAPANESE", # ruleset: JAPANESE | CHINESE
"size" : 19, # board-size
"komi" : 6.5, # komi
"handicap" : 0, # handicap-stones
"handicap_mode" : "FREE", # STD=standard-handicap, FREE=free-handicap
"adjust_handicap" : -2, # handicap-adjustment
"min_handicap" : 0, # min. number of handicap-stones
"max_handicap" : -1, # max. number of handicap-stones, -1 = default-max-handicap
"adjust_komi" : 0.0, # komi-adjustment
"jigo_mode" : "KEEP_KOMI", # jigo-mode for adjusting-komi or fair-komi: KEEP_KOMI (=no jigo restriction), ALLOW_JIGO, NO_JIGO
"time_weekend_clock" : 1, # 1=time-running on weekend, 0=otherwise
"time_mode" : "CAN", # time-mode: FIS=Fischer-time, JAP=japanese-time, CAN=canadian-time
"time_limit" : "C: 14d + 15d / 8", # initial time-settings for game (like in waiting-room),
# see section (6b) "TimeLimit-Formats"
"time_main" : 210, # time-limit main-time [1 unit = 1 hour, 15 hour = 1 DGS-day]
"time_byo" : 225, # time-limit byo-time [1 unit = 1 hour, 15 hour = 1 DGS-day]; extra-time for Fischer-time
"time_periods" : 8, # time-limit byo-periods: periods (for JAP), stones (for CAN), unused (=0, for FIS)
"opp_started_games" : 0, # number of games already started with opponent
"calc_type" : 1, # quality of setings: 1=probable-setting (conv/proper depends on rating), 2=fix-calculated
"calc_color" : "black", # probable/fix color of logged-in user: double | fairkomi | nigiri | black | white
"calc_handicap" : 3, # probable/fix handicap
"calc_komi" : 6.5, # probably/fix komi, empty "" for fairkomi
},
}
"list" : retrieve list of messages ordered by creation-date (newest first)
- required opts: FILTER-folders
- optional opts: WITH, FILTER, LIMIT
- WITH-option:
- 'user_id' : additionally return user_id-data (handle + name + rating) for message correspondent
- 'folder' : additionally return folder-data (name + color_bg + color_fg) for message
- FILTER-options:
- 'filter_answers=VAL' : message-id of parent-message
- return message(s), that are replies to given message-id; can be used to traverse message-thread
- there can be more than one reply to a message
- no default
- overwrites 'filter_folders' with value 0 (=ALL)
- unlimited, implicit 'limit=all' in effect
- 'filter_folders=VAL' : 1,2,3
- return only messages from given folders
- comma-separated list of folder-ids or standard-folder-names
- default 0
- standard-folders have aliases: 1=MAIN, 2=NEW, 3=REPLY, 4=TRASH, 5=SENT
- special folder-values: 0=ALL (=all-received like website)
- user-specific folders can only given by folder-id: >= 6
see also (3d) folder-object
- Important Notes:
* messages from REPLY-folder can still need no-reply, for example if user moved
a no-reply-needed message into the Reply-folder.
So in order to know, if a reply is needed for a message, you have to inspect
the "can_reply" and the "need_reply"-field in the response.
- LIMIT-option:
- only when using messages for folders NEW and/or REPLY,
the LIMIT-option can be 'all' to return all those messages in one go
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- invalid_args : bad parameters (bad filters)
- folder_not_found : unknown folder specified in filters
- Result (JSON) = result-list see section (2d) with list of objects:
- the fields content and semantics are the same as for the message-object "info"-command (see above (3c))
"send_msg" : send new message, reply to message
- required opts: OTHER_UID|OTHER_HANDLE (not for reply), SUBJECT
- for replying received message OTHER_UID|OTHER_HANDLE must NOT be used
- optional opts: MESSAGE_ID (for replies), FOLDER (target-folder), MESSAGE
- MESSAGE_ID : message-id to reply to with sending-message,
parameters OTHER_UID|OTHER_HANDLE must not be used for replying
- FOLDER : target-folder of replied-to message for sending-user
- Notes:
- NOT SUPPORTED: sending invites for multi-player-games, sending bulk-message
- if FOLDER is omitted, behave like GUI moving replied-message into MAIN-folder
- message to send will be moved into SENT-folder for sending-user
- Errors:
- all errors of: [E-LOGIN], [E-GEN], [E-MSG], [E-MSGSEND]
- Result (JSON) =
{
"error_texts" : [ # empty array, if no "error" returned; otherwise list of error-texts
"err1", "err2", ... # free error-texts
],
}
"move_msg" : moves message(s) into target folder
- required opts: MESSAGE_ID, FOLDER
- multiple message-ids allowed separated by comma
- Notes:
- messages that need reply can not be moved
- some target-folder may not be used to move certain type of messages to (like in REPLY/SENT-folder)
- Errors:
- all errors of: [E-LOGIN], [E-GEN], [E-MSG]
- Result (JSON) =
{
"success_count" : 1, # number of messages, that were moved successfully
"failure_count" : 0, # number of messages, that were not deleted (maybe need reply)
}
"delete_msg" : deletes message(s)
- required opts: MESSAGE_ID
- multiple message-ids allowed separated by comma
- Notes:
- messages can not be deleted, if they need a reply
- messages are not really destroyed but moved into the internally used DESTROY-folder
- Errors:
- all errors of: [E-LOGIN], [E-GEN], [E-MSG]
- Result (JSON) =
{
"success_count" : 1, # number of messages, that were deleted successfully
"failure_count" : 0, # number of messages, that were not deleted (maybe need reply)
}
"accept_inv" : accepts game-invitation
- required opts: MESSAGE_ID
- optional opts: MESSAGE, FOLDER
- FOLDER : target-folder of replied-to message for sending-user
- Notes:
- if FOLDER is omitted, behave like GUI moving replied-message into MAIN-folder
- message to send will be moved into SENT-folder for sending-user
- Errors:
- all errors of: [E-LOGIN], [E-GEN], [E-GAMECREATE], [E-MSG], [E-MSGSEND]
"decline_inv" : declines game-invitation
- required opts: MESSAGE_ID
- optional opts: MESSAGE, FOLDER
- FOLDER : target-folder of replied-to message for sending-user
- Notes:
- if FOLDER is omitted, behave like GUI moving replied-message into MAIN-folder
- message to send will be moved into SENT-folder for sending-user
- Errors:
- all errors of: [E-LOGIN], [E-GEN], [E-GAMECREATE], [E-MSG], [E-MSGSEND]
# NOT IMPLEMENTED: TODO
"send_inv" : send new invitation
# NOT IMPLEMENTED: TODO
"dispute_inv" : dispute invitation
Examples for message-commands:
# login setting cookie in HTTP-header storing: handle, sessioncode
login.php?quick_mode=1&userid=user&passwd=userpassword
# retrieve message
quick_do.php?obj=message&cmd=info&mid=1234567
# retrieve message and mark as read moving into MAIN-folder (=1)
quick_do.php?obj=message&cmd=info&mid=1234567&folder=1
# retrieve bulk-message for certain recipient
quick_do.php?obj=message&cmd=info&mid=1234567&ouid=2
# retrieve list of messages: for NEW & REPLY folders, for all received messages, for user-folders
do_quick.php?obj=message&cmd=list&filter_folders=NEW,REPLY&limit=all
do_quick.php?obj=message&cmd=list&with=user_id
do_quick.php?obj=message&cmd=list&with=folder&filter_folders=6,7,8
# retrieve list of answers for message
do_quick.php?obj=message&cmd=list&filter_answers=12345
#-------- (3d) Objects - "folder" ---------------------------------------------
Purpose:
The quick-suite for the folder-object allows to
- retrieve information about folders to store private messages in;
corresponding pages: "list_messages.php", "edit_folders.php"
Request:
quick_do.php?obj=folder&cmd=
# list
quick_do.php?obj=folder&cmd=list
Options:
= "list"
Commands:
"list" : returns list of message-folders in natural order
- required opts: -
- optional opts: -
- NOTES:
- all folders of user are returned; std-options and have no effect
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- Result (JSON) = // also see specs/db/table-Messages.txt
{
"list_object" : "folder",
"list_totals": -1,
"list_size" : 5,
"list_offset" : 0,
"list_limit" : 0,
"list_order" : "id+",
"list_result" : [
{
"id" : 2, # folder-nr (<0, 0-5 system-folder, >= 6 user-folder)
"name" : "New", # folder-name (lang-dependent)
"system" : 1, # 1=system-folder, 0=user-folder
"color_bg" : "F7F5E399", # folder background-color (incl. alpha-channel) in hex-format
"color_fg" : "000000", # folder foreground-color (=font-color) in hex-format
"on_status" : 1, # 1=shown on status-page, 0=folder-content only shown in message-list
},
...
]
}
Examples for folder-commands:
# login setting cookie in HTTP-header storing: handle, sessioncode
login.php?quick_mode=1&userid=user&passwd=userpassword
# retrieve folders
quick_do.php?obj=folder&cmd=list
#-------- (3e) Objects - "contact" --------------------------------------------
Purpose:
The quick-suite for the contact-object allows to
- retrieve information about a users contacts
corresponding pages: "list_contacts.php"
Request:
quick_do.php?obj=contact&cmd=
# list
quick_do.php?obj=contact&cmd=list&with=
Options:
= "list"
= optional with-option to include additional data-fields (see commands)
Commands:
"list" : returns list of contacts
- required opts: -
- optional opts: WITH
- WITH-option:
- 'user_id' : returns additional user_id-data (see example below) for contact-user
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- Result (JSON) =
{
"list_object" : "contact",
"list_totals": -1,
"list_size" : 3,
"list_offset" : 0,
"list_limit" : 0,
"list_order" : "contact_user.name+",
"list_result" : [
{
"contact_user" : {
"id" : 1, # user-id of contact
"handle" : "guest", # USER_HANDLE
"name" : "Guest", # user name
# for the following fields -> see "info"-command for user-object (3b)
# the following fields are only included if WITH-option contains 'user_id'
"country" : "se",
"rating" : "5k (+46%)",
"rating_elo" : "1643.88952636719",
"last_access" : "YYYY-MM-DD hh:mm:ss",
"last_move" : "YYYY-MM-DD hh:mm:ss",
"type" : "",
},
"system_flags" : "", # system flags (comma-separated): WR_PROTECT_GAMES REJECT_MESSAGE REJECT_INVITE WR_HIDE_GAMES
"user_flags" : "", # user flags (comma-separated): BUDDY FRIEND STUDENT TEACHER FAN ADMIN TROLL MISC
"created_at" : "YYYY-MM-DD hh:mm:ss", # contact created date
"updated_at" : "YYYY-MM-DD hh:mm:ss", # contact last-updated date
"notes" : "my-note" # optional contact-notes
},
...
]
}
Examples for contact-commands:
# login setting cookie in HTTP-header storing: handle, sessioncode
login.php?quick_mode=1&userid=user&passwd=userpassword
# retrieve all contacts
quick_do.php?obj=contact&cmd=list
#-------- (3f) Objects - "wroom" ----------------------------------------------
Purpose:
The quick-suite for the wroom-object allows to
- retrieve game-offers from waiting-room;
corresponding pages: "waiting_room.php"
- join & delete game-offers from waiting-room;
corresponding pages: "join_waitingroom_game.php"
- create new game-offers in waiting-room;
corresponding pages: "new_game.php"
Request:
quick_do.php?obj=wroom&cmd=&wrid=
# list
quick_do.php?obj=wroom&cmd=list&with=&filter_...=
Options:
= "info" | "list" | "delete" | "join" | "new_game"
= id of waiting-room-entry
= optional filter-options (see commands)
= optional with-option to include additional data-fields (see commands)
Commands:
"info" : returns information on single game-offer from waiting-room
- required opts: WROOM_ID
- optional opts: WITH
- WITH-option:
- 'user_id' : return additional user_id-data of game-offerer
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- Result (JSON) = // also see specs/db/table-Waitingroom.txt
{
"id" : 1, # waitingroom-id
"user" : {
"id" : 111, # user-id of sender, 0=server-message
# the following fields only if WITH-option contains 'user_id'
"handle" : "user1", # USER_HANDLE
"name" : "name1", # user name
"country" : "xe", # country-code
"rating" : "5k (+46%)", # DGS rating | "" (=no rating)
"rating_elo" : "1643.88952636719", # DGS elo-rating | "" (=no rating)
},
"created_at" : "YYYY-MM-DD hh:mm:ss", # creation-date of waitingroom-entry
"count_offers" : 3, # remaining number of offers with same characteristics
"comment" : "fast game", # comment for game-offer
# game_settings
"game_type" : "GO", # game-type: GO,TEAM_GO,ZEN_GO
"game_players" : "1:1", # multi-player-game setup: "N:M", or empty for game-type=GO
"handicap_type" : "conv", # see HTYPE_... in 'include/game_functions.php':
# conv, proper, nigiri, double, black, white, auko_sec, auko_opn, div_ykic, div_ikyc
#
# conv = conventional handicap (like in GUI)
# proper = proper handicap (like in GUI)
# nigiri = nigiri
# double = double-game (one as black, one as white)
# black = game-inviter takes black
# white = game-inviter takes white
#
# Fair-komi handicap-types:
# - auko_sec = fair-komi: secret auction komi
# - auko_opn = fair-komi: open auction komi
# - div_ykic = fair-komi: divide&choose: you choose komi, i choose color
# - div_ikyc = fair-komi: divide&choose: i choose komi, you choose color
"shape_id" : 0, # shape-id > 0 if game was started as shape-game
"shape_snapshot" : "", # shape-snapshot
"rated" : 1, # 0=unrated, 1=rated
"ruleset" : "JAPANESE", # ruleset: JAPANESE | CHINESE
"size" : 19, # board-size
"komi" : 6.5, # komi
"handicap" : 0, # handicap-stones
"handicap_mode" : "FREE", # STD=standard-handicap, FREE=free-handicap
"adjust_handicap" : -2, # handicap-adjustment
"min_handicap" : 0, # min. number of handicap-stones
"max_handicap" : -1, # max. number of handicap-stones, -1 = default-max-handicap
"adjust_komi" : 0.0, # komi-adjustment
"jigo_mode" : "KEEP_KOMI", # jigo-mode for adjusting-komi or fair-komi: KEEP_KOMI (=no jigo restriction), ALLOW_JIGO, NO_JIGO
"time_weekend_clock" : 1, # 1=time-running on weekend, 0=otherwise
"time_mode" : "CAN", # time-mode: FIS=Fischer-time, JAP=japanese-time, CAN=canadian-time
"time_limit" : "C: 14d + 15d / 8", # initial time-settings for game (like in waiting-room),
# see section (6b) "TimeLimit-Formats"
"time_main" : 210, # time-limit main-time [1 unit = 1 hour, 15 hour = 1 DGS-day]
"time_byo" : 225, # time-limit byo-time [1 unit = 1 hour, 15 hour = 1 DGS-day]; extra-time for Fischer-time
"time_periods" : 8, # time-limit byo-periods: periods (for JAP), stones (for CAN), unused (=0, for FIS)
"restrictions" : "", # empty = no restrictions defined for game-offer; non-empty = info-string with restrictions.
# despite having restrictions, a game-offer may be joinable (e.g. for hidden entries)
"join" : 1, # 1=game-offer can be joined, 0=can not be joined (because your own or unsuitable)
"join_warn" : "", # if not-empty, contains warning about joining (about max-games reached soon)
"join_err" : "", # if not-empty, contains error-reasons why joining not possible (e.g. max-games reached,
# MPG already joined, opponents max-games reached)
"opp_started_games" : 0, # number of games already started with opponent
"calc_type" : 1, # quality of setings: 0=own-game-offer, 1=probable-setting (conv/proper depends on rating),
# 2=fix-calculated, 3=MPG (color/handicap/komi set by game-master)
"calc_color" : "black", # probable/fix color of logged-in user: '' | mpg | double | fairkomi | nigiri | black | white
# '' (=empty) if color cannot be determined (e.g. if users are not rated for conventional-handicap)
# the next two fields are '' (empty = non-int/float), if calc_type is 0 or 3 or 'calc_color' is empty:
"calc_handicap" : 3, # probable/fix handicap
"calc_komi" : 6.5, # probably/fix komi, field omitted for fair-komi
}
"list" : returns list of all game-offers from waiting-room
- optional opts: FILTER, WITH
- FILTER-options:
- 'filter_suitable=VAL' :
- VAL = '1' : only finding suitable game-offers (default)
- VAL = '0' : find all game-offers
- VAL = '2' : find own game-offers
- WITH-option:
- 'user_id' : return additional user_id-data of game-offerer
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- Result (JSON) = // also see specs/db/table-Waitingroom.txt
{
"list_object" : "wroom",
"list_totals": -1,
"list_size" : 3,
"list_offset" : 0,
"list_limit" : 0,
"list_order" : "user.rating-,user.handle+",
"list_result" : [
# each list-element looks like the output for the "info"-command (without the std-fields),
# except for the fields mentioned below in "Exception Notes"
{
"id" : 123, # waiting-room-id
...
},
...
]
}
- Exception Notes:
- Field 'join' : this field is included, but shows only the result of general checks.
The more precise checks are only done for the 'info'-command as they would be
too expensive for a list of elements. So if the value is "0" the offer can for
sure NOT be joined, but if the value is "1" it can still be that the offer
is not joinable. But this can only happen if the users max-games have been reached.
- Field 'join_warn' and 'join_err' : these fields are only included for the 'info'-command.
They contain reasons and warnings based on the detail-checks for the 'join'-field,
and are therefore not included for the 'list'-command as well.
- Field 'opp_started_games' : this field is not included for the 'list'-command,
because it is too expensive to be caclculated for a list.
"delete" : deletes own game-offer from waiting-room
- required opts: WROOM_ID
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- waitingroom_game_not_found : unknown waiting-room entry
- waitingroom_delete_not_own : unauthorised delete, you can only delete your own waiting-room entries
"join" : joins game-offer from waiting-room
- required opts: WROOM_ID
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- not_allowed_for_guest : guests are not allowed to join
- waitingroom_game_not_found : unknown waiting-room entry
- max_games : joining user has already too many started games running
- max_games_opp : the user from the game-offer has already too many started games running
- waitingroom_own_game : you can not join your own waiting-room game-offer
- waitingroom_not_in_rating_range : your rating is not within the requested range of the game-offer
- waitingroom_not_enough_rated_fin_games : you have not finished enough rated games
- waitingroom_not_same_opponent : waiting-room restriction on joining by same-opponent is violated
- no_initial_rating : handicap-type of game-offer requires a rating
- internal_error : inconsistency found in game-offer -> contact admin
# NOT IMPLEMENTED: to-specify (TODO)
"new_game" : create new game-offer in waiting-room
- Notes:
- only one "view" (combining standard/fair-komi/mpg in one)
Examples for wroom-commands:
# login setting cookie in HTTP-header storing: handle, sessioncode
login.php?quick_mode=1&userid=user&passwd=userpassword
# retrieve all waiting-room-entries
quick_do.php?obj=wroom&cmd=list
# retrieve info about single waiting-room-entry
quick_do.php?obj=wroom&cmd=info&wrid=123&with=user_id
# deletes waiting-room game
quick_do.php?obj=wroom&cmd=delete&wrid=123
# joins waiting-room game
quick_do.php?obj=wroom&cmd=join&wrid=123
#-------- (3g) Objects - "bulletin" -------------------------------------------
Purpose:
The quick-suite for the bulletin-object allows to
- retrieve unread bulletins, retrieve single bulletin, mark bulletin as read;
corresponding pages: "list_bulletins.php", "view_bulletin.php"
Request:
quick_do.php?obj=bulletin&cmd=&bid=
# list
quick_do.php?obj=bulletin&cmd=list&with=
Options:
= "info" | "list" | "mark_read"
= single or list of comma-separated bulletin-ids
= optional with-option to include additional data-fields (see commands)
Commands:
"info" : returns single bulletin
- required opts: BULLETIN_ID
- optional opts: WITH
- WITH-option:
- 'user_id' : additionally return user_id-data (handle + name) for author of bulletin
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- invalid_args : bad parameters (missing or invalid bulletin-id)
- Result (JSON) = // also see specs/db/table-Bulletin.txt
{
"id" : 123, # bulletin-id
"target_type" : "ALL", # target-type: ALL,TD,TP,UL,MPG
"status" : "SHOW", # status: NEW,PENDING,REJECTED,SHOW,ARCHIVE,DELETE
"category" : "ADM_MSG", # category: MAINT,ADM_MSG,TOURNEY,TNEWS,FEATURE,PRIV_MSG,AD
"flags" : "", # flags (comma-separated): ADM_CREATED, USER_EDIT
"time_published" : "YYYY-MM-DD hh:mm:ss", # publish-time
"time_expires" : "YYYY-MM-DD hh:mm:ss", # expire-time
"time_updated" : "YYYY-MM-DD hh:mm:ss", # last-changed-time
"author" : {
"id" : 111, # user-id of author
# the following fields only if WITH-option contains 'user_id'
"handle" : "user1", # USER_HANDLE
"name" : "Name1", # user name
},
"tournament_id" : 0, # tournament-id
"game_id" : 0, # game-id
"hits" : 33, # view-count
"subject" : "title",
"text" : "text",
"read" : 0, # 0=unread, 1=read
}
"list" : returns list of unread bulletins
- optional opts: WITH
- WITH-option:
- 'user_id' : additionally return user_id-data (handle + name) for author
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
- Result (JSON) = // also see specs/db/table-Bulletin.txt
{
"list_object" : "bulletin",
"list_totals": -1,
"list_size" : 2,
"list_offset" : 0,
"list_limit" : 0,
"list_order" : "time_published-",
"list_result" : [
# the fields content and semantics are the same as for the bulletin-object "info"-command (see above)
{
},
...
]
}
"mark_read" : mark bulletin(s) as read
- required opts: BULLETIN_ID
- Errors:
- all errors of: [E-LOGIN], [E-GEN]
Examples for bulletin-commands:
# login setting cookie in HTTP-header storing: handle, sessioncode
login.php?quick_mode=1&userid=user&passwd=userpassword
# retrieve unread bulletins
quick_do.php?obj=bulletin&cmd=list&with=user_id
# retrieve single bulletin (read or unread)
quick_do.php?obj=bulletin&cmd=info&bid=7&with=user_id
# mark unread bulletin(s)
quick_do.php?obj=bulletin&cmd=mark_read&bid=7,11
#-------- (4) Supporting Tools ------------------------------------------------
#-------- (4.SGF) SGF-download "sgf.php" --------------------------------------
Purpose:
The page "sgf.php" is used to download a DGS-game in SGF-format.
Internally DGS uses a different format and because of the turn-based nature
of the server not all DGS-game parameters fit into a SGF-file.
Request:
sgf.php?gid=&owned_comments=&mpg=&quick_mode=&inline=&no_cache=&bulk=&filefmt=
Important Notes:
* If you are not logged-in (to set session-cookie authenticating a user),
ALL dates are given in UTC-timezone!
* If you are not logged in (no session cookies set),
then you only have access to public comments.
No private comments are available (option = 1 has no effect).
* Not all information from DGS is exported into the SGF.
For example, the time-information can not be exported in the SGF,
because it could exceed the value-range (in seconds) interpreted
by some SGF-clients.
Options:
= integer ; REQUIRED option
- game-id referencing game on DGS to download SGF from
= 0 | 1 | N ; default = 0
- 0 = return only public comments
- 1 = try to return private comments (for players only),
including private notes on game
- N = return NO comments or notes at all
= int ; default = 0, flags for multi-player-game only
- 1 (bit 0) = don't include user-info on each move-node
= 0 | 1 ; default = 0
- 0 = exit on error (default)
- 1 = ignore errors
= 0 | 1 ; default = 0
- 0 = use Content-Disposition type of "attachment", so that browser asks
what to do after download complete. This was required for several mobile
devices, that had no support for "inline"-disposition.
- 1 = use Content-Disposition type of "inline" to directly start assigned
application, which means that after the browser downloads it could directly
start a SGF-viewer.
= 0 | 1 ; default = 0
- 0 = caching enabled: +5 min expiration
- 1 = disable caching (expire-header adjusted accordingly)
= 0 | 1 ; default = 0
- 0 = use standard filename-pattern for download:
"---YYYYMMDD.sgf"
Example:
"jug-stex-415456-20090327.sgf"
- 1 = use special filename-pattern;
omit handicap (if =0) and omit result if unfinished game:
"DGS-_YYYY-MM-DD_(H)K(=)_-.sgf"
Example:
"DGS-537452_2010-04-11_R9H3K0,5=B0,5_pjo-Testter.sgf"
"DGS-557175_2010-04-13_F9K1,5=W29,5_Stanberry-Tim1tim2tim3.sgf"
= normal text mixed with special placeholders defining file-format
- extension '.sgf' is always appended automatically
- defaults:
- with bulk=0: $w-$b-$g-$d1 (example: "userW-userB-123-20130819.sgf")
- with bulk=1: DGS-$g_$d2_$R$S$H$K$r_$w-$b (for example see -option)
- special placeholders:
- $$ = escape special-symbol: '$'
- $b = black-user handle
- $w = white-user handle
- $g = game-id
- $S = board-size: '19'
- $R = rated: 'F' = free, 'R' = rated
- $H = handicap: '' = no handicap, 'H7'
- $K = komi: 'K6,5'
- $r = result: '=B3,5' = B won by 3.5, '=W0' = jigo, '=VOID' = no-result, '=W3' = white won by 3
- $d1 = last-changed date in format YYYYMMDD: 20130819
- $d2 = last-changed date in format YYYY-MM-DD: 2013-08-19
Response (SGF-properties):
This paragraph lists all exported SGF-properties by the DGS-server
in alphabetical order:
# SGF-standard properties:
AB, AP, B, BR, BT, BW, C, DT, FF, GC, GM, GN, HA, KM, MA, MN, N, OT, PB, PC,
PL, PW, RE, RU, SO, SZ, TB, TW, W, WT
# DGS-non-standard properties:
XM
# exported DGS-properties: XM
ID Description type property value
---- ------------------- ----------- --------------------------------------
XM move_id game-info see specs/quick_suite.txt (3a)
Example of DGS-exported SGF with some format descriptions:
# standard-SGF-properties are not documented here,
# see SGF[4]-properties: http://www.red-bean.com/sgf/proplist_ff.html
#
# Note: this example only lists the properties in the order used,
# but the listing does not show a valid SGF-format
FF[4]
GM[1]
CA[utf-8] # charset (optional)
AP[DGS:1.0.15] # DGS-version
PC[Dragon Go Server: http://www.dragongoserver.net/]
DT[2007-04-21,2007-05-19] # start-date,end-date of game
GN[Ba_alza-jug-310100-20070519] # filename of SGF (see -option above)
SO[http://www.dragongoserver.net/game.php?gid=310100] # source with URL
# EV and RO properties only present for tournaments
EV[(Dragon Ladder) Tournament #X: title] # info if game of tournament
RO[Round X of Y] # round-info of tournament
PB[JUG (jug)]
PW[Ba_alza (Ba_alza)]
BR[6k]
WR[6k]
# Team-Players: only for multi-player-game, space-separated
BT[jug]
WT[Ba_alza]
# non-standard property with "move_id" required for quick-suite (3a)
# providing a "context" for playing the next move
XM[245]
# free-text game-comment (normally not indented)
# - "White|Black End Rating:" only included for finished game
GC[Game ID: 310100
Game Type: Go (1:1) # values: GO (1:1) | TEAM_GO (N:M) | ZEN_GO (N)
(Dragon Ladder) Tournament #X: title; with Y participants # only for tournament-game: tournament-info
Rated: Y # values: Y | N
Note: game-result set by admin # Note-lines 0..n
White Start Rating: 7k (-29%) - ELO 1371
Black Start Rating: 8k (-18%) - ELO 1282
White End Rating: 6k (-4%) - ELO 1496
Black End Rating: 6k (-2%) - ELO 1497
# only for shape-game:
Shape #3 (W-First): Sunjang Baduk
# only for multi-player-game (Team-/Zen-Go)
Game Players (Order. Color: Name (Handle), Current Rating):
1. B JUG (jug), 6k (-2%) - ELO 1497 # group: B | W | BW
1. W Ba_alza (Ba_alza), 6k (-4%) - ELO 1496 # player: Name (Handle), current rating
]
OT[90 days + 1 day per move and 10 extra periods]
RU[Japanese] # ruleset: Japanese | Chinese
SZ[19]
KM[6.5]
HA[3] # handicap (omitted prop if no handicap)
RE[B+7.5] # result only for finished game; format: 0=jigo, "B/W+Resign/Time/Forfeit/999[.5]", "Void"
# see also SGF-specs: http://www.red-bean.com/sgf/properties.html#RE
# shape-game-setup (with shape-info-comment)
AB[aa][bb][cc] # Black setup stones for shape-game
AW[dd][ee][ff] # White setup stones for shape-game
GC[Shape #3 (W-First): Sunjang Baduk # shape-info of shape-game with URL to view-shape
http://www.dragongoserver.net/view_shape.php?shape=3]
# (implicitly) enforcing new SGF-node on next-property with ';'-prefix
# game-moves (with comments)
# - prefix '[Handle]' for multi-player-game added on each move (if not deactivated by MPG-option)
AB[cc][ee][gg] # handicap stones (optional prop)
MN[1] # correct move-number
B[qd]
C[onegaishimasu]
W[dc] ...
# pass-sequence
;W[]
;B[]
;W[]
N[W SCORE] # optional prop
# switch color (optional prop)
# - may happen after passes->score->resume play
# - values: B | W
PL[B]
# change move-number (optional prop), may occur after passes->score->resume
MN[217]
# only in scoring-step: marked stones
MA[er][ep] ...
# remaining properties only for finished game containting result-props
N[RESULT] # optional prop
TB[mp][mo] ...
TW[qk][il] ...
# free-text with game-result (normally not indented)
C[Thanks for the game
White: 47 territories + 9 prisoners + 6.5 komi = 62.5
Black: 70 territories + 0 prisoner = 70
Result: B+7.5
Notes - JUG: # only for logged-in user (optional)
my private game notes]
Errors:
* SGF Errors:
- all errors of: [E-LOGIN], [E-GEN]
- unknown_game : invalid game
Examples:
# login setting cookie in HTTP-header storing: handle, sessioncode
login.php?quick_mode=1&userid=user&passwd=userpassword
# download SGF (open browser-attached SGF-viewer)
sgf.php?gid=557175&owned_comments=1&inline=1
# download SGF (e.g. for robot, no comments)
sgf.php?gid=557175&owned_comments=N&quick_mode=1&no_cache=1
References:
- see also "sgf.php" and "include/sgf_builder.php"
- SGF[4]-specs: http://www.red-bean.com/sgf/index.html
- SGF[4]-properties: http://www.red-bean.com/sgf/proplist_ff.html
#-------- (4.QST) Quick-Status "quick_status.php" -----------------------------
Purpose:
The page "quick_status.php" is used to return some of the information
from the corresponding status-page "status.php":
- retrieve a list of unread bulletins
- retrieve a list of private messages (marked to be shown on status-page),
showing messages from NEW- & REPLY-folder
- retrieve a list of games the specified user is next to move in
(normal games or multi-player-games alike)
- retrieve a list of multi-player-games in SETUP-mode to manage
Request:
quick_status.php?version=&userid=&passwd=&no_cache=&order=
Important Notes:
* For DGS version >= 1.0.15:
- You must be logged-in (to set session-cookie authenticating a user)
- Login is possible per cookie-login using 'login.php' or by the less safe method
providing user and password as URL-arguments 'userid' and 'passwd'
- If you are not logged-in you will receive an error 'invalid_user'
* For DGS version >= 1.0.15:
With version 1.0.15 the quick-status page has an additional progressive block-specific caching.
This is done to reduce the server-load and to enforce some form of quota
without the need of changing each client to react on quota-exceedings.
There also is the normal browser-caching, see also option below.
The caching describe in this note is something different from that and will only kick-in
when the browser does not take the data from its own cache (and the server is asked).
For testing purpose on test-servers, the progressive block-specific caching can be deactivated.
For the live-server disabling is not possible. See also option below.
The following "writing-operations" will invalidate the QST-cache for the respective users:
* Operations are covered by all interfaces: web-site, quick-play and quick-do-suite
* status-games block is invalidated on (for web-site, quick-play and quick-do-suite):
- start a game by joining waiting-room-game or accepting invitation or started MP-game
- finish a running game by user or timeout
- delete a running game by user or admin
- move in a running game (play, resign, delete, pass, score)
- save change during fair-komi negotation
- changing the game-priority for ordering status-games
* private-messages block is invalidated on:
- new message of single and bulk type for sender and receivers
- read message (moving it away from NEW-folder)
- move message into different folder
* bulletins block is invalidated on:
- mark bulletin as read
* multi-player-games block is invalidated on:
- accept or reject invitation
- start MP-game
[INTERNAL NOTE:
The invalidation is done by appending a "CLEAR " to an existing cache-file.
The values for "" are B=bulletin, G=games, M=messages, MPG=MP-games.
See also QST_CACHE_.. consts.
]
It is recommended, that the quick-status page should not be called more than once per minute.
If a client does that regardless AND no specific block in the cache was invalidated,
the following warning (with 'userid' replaced) is prepending the data, indicating that the
data is taken from the cache:
[#Warning: excessive_usage; quick_status.returning_cached_data(userid).see_faq[http://www.dragongoserver.net/faq.php?read=t&cat=15#Entry302]]
Each block of data (bulletins, messages, status-games, multi-player-games)
has its own cache for a specific user and data-block, and has its own minimum
request-interval:
- bulletins : 15 min
- messages : 15 min
- status-games : 1 min, progressive if data unchanged, max. 15 min
- multi-player-games : 15 min
If a client requests quick-status before the min-request interval has passed,
the according block-specific data is returned from a cache if it has not yet
expired.
For the status-games data-block a progressive expiring is in place.
It starts with a waiting-time of one minute. If the client asks after one minute elapsed,
the status-games are loaded again (before one minute the data from the cache is taken).
If the newly loaded status-games show no difference to the previous data-block,
the waiting-time for the next interval is doubled.
In summary, the client always receives a result, but the server decides if it's taken
from the cache or database reflecting reality. The client is obliged to resonsibly
choose a suitable request-interval. And even though the minimum is one minute, do not
just use it because you can. Please read the following FAQ-entry before you choose:
"How should the resources provided by DGS be used responsibly?"
see http://www.dragongoserver.net/faq.php?read=t&cat=15#Entry302
Example of caching:
- B=bulletins, M=messages, G=status-games, MPG=multi-player-games
- B1 = data-set, B2 = data-set different from B1
- the request-time and data-changes are arbitrary to show the
progressive caching-effect for status-games and normal expire-times and quota-warnings
- 09:00:00 ask QST for 1st time -> result: B1 + M1 + G1 + MPG1
from database ( B1,M1,G1,MPG1 )
expire-time for B/M/MPG = 09:15:00, for G = 09:01:00
- 09:00:30 ask QST (request-interval too small, below 1 min)
-> result: [#Warning: excessive_usage...] + B1 + M1 + G1 + MPG1
from cache ( B1,M1,G1,MPG1 )
expire-time for B/M/MPG = 09:15:00, for G = 09:01:00
- 09:02:00 ask QST -> result: B1 + M1 + G2 + MPG1
from cache ( B1,M1,MPG1 ); from database ( G2 )
expire-time for B/M/MPG = 09:15:00, for G = 09:03:00 (1 min)
- 09:03:00 ask QST -> result: B1 + M1 + G2 + MPG1
from cache ( B1,M1,G2,MPG1 )
expire-time for B/M/MPG = 09:15:00, for G = 09:05:00 (doubled to 2 min because no change)
- 09:05:00 ask QST -> result: B1 + M1 + G2 + MPG1
from cache ( B1,M1,G2,MPG1 )
expire-time for B/M/MPG = 09:15:00, for G = 09:09:00 (doubled to 4 min because no change)
- 09:09:00 ask QST -> result: B1 + M1 + G2 + MPG1
from cache ( B1,M1,G2,MPG1 )
expire-time for B/M/MPG = 09:15:00, for G = 09:17:00 (doubled to 8 min because no change)
- 09:15:00 ask QST -> result: B1 + M2 + G2 + MPG1
from cache ( G2 ); from database ( B1,M2,MPG1 )
expire-time for B/M/MPG = 09:30:00, for G = 09:17:00
- 09:20:00 ask QST -> result: B1 + M2 + G3 + MPG1
from cache ( B1,M2,MPG1 ); from database ( G3 )
expire-time for B/M/MPG = 09:30:00, for G = 09:21:00 (reset to 1 min because it changed)
* For DGS version 1.0.15:
quick-status version=0+1 will be deprecated and (probably) removed on next major version DGS 1.0.16.
When a version is deprecated, the following warning is prepending the data:
[#Warning: deprecated_version; ]
* For DGS version <= 1.0.14:
If you are not logged-in (to set session-cookie authenticating a user),
ALL dates are given in UTC-timezone in format "YYYY-MM-DD hh:mm:ss GMT" !
* For DGS version <= 1.0.14:
If you are not logged in (no session cookies set),
then you only have access to your status-game.
Data that requires authentication:
- Bulletins are not included
- Private messages are not included
- Multi-player game data is not included
Options:
= (optional) version defining format
- 0 = 1 = quick-status format for DGS-release-version < 1.0.15
- MPG-entries (multi-player-games): not shown
- B-entries (unread bulletins): not shown
- G-entries (status-games): reduced field-set, different format
- M-entries (new messages): different format
- 2 = quick-status format for DGS-release-version = 1.0.15
- current specs describe this format
+ = string
- A user login is mandatory to retrieve data via quick-status.
- There are two ways to login:
- 1. login with URL-arguments userid + passwd
- 2. use 'login.php' to set cookies (preferred way)
- If no user-id is given (per argument or cookies), an error 'invalid_user' is returned.
- reference user to get status-info for
- USER_HANDLE is the unique user-id (handle),
e.g. http://www.dragongoserver.net/userinfo.php?user=guest
= 0 | 1 | 2 ; default = 0
- 0 = caching enabled: +5 min expiration
- 1 = disable caching (expire-header adjusted accordingly)
- 2 = disable browser-caching AND progressive block-specific caching (described above in "Important Notes")
NOTE: deactivation is not possible on the live-server, error 'invalid_args' is returned in this case
= (optional) sort-order for status-games
- '' = use default order as configured on status-page
- 0 = no-order (that's more gentle to the server, because less sorting)
- 1 or LASTMOVED = order by opponent-last-moved-date
- 2 or MOVES = order by number of moves in game
- 3 or PRIO = order by players priority set for game (on game-info page)
- 4 or TIMELEFT = order by players remaining-time
Response:
The output of the "quick_status.php" tool is a document of HTTP-Content-Type
"text/plain", that contains a list of lines consisting of comments, message-info
and game-info. The output-format follows the following syntax:
- line starting with '#' are comments in general
- line starting with '##' contains the format of a specific line-type,
different line-types with different amount of fields are possible
- line starting with '[#' are warnings, e.g. "[#Warning: messages_list_not_shown; ]"
- empty lines should be skipped
- other lines contain data
- if there are no data-lines, then the result-set is empty
- a data-line consists of comma-separated fields
- leading and trailing whitespaces of the fields should be ignored
- a field is put into single-quotes "'" when
a) the field-value contains either a single-quote, a space or a backslash '\', or
b) the corresponding field-header is surrounded by single-quotes
- escape-characters (single-quote, backslash) are escaped
with a preceeding backslash, e.g. '\\' or "\'"
The current format of data-lines in the output is (different versions are referenced in braces):
# header-line with format of unread-bulletins (only for version >= 2)
"## B,bulletin_id,target_type,category,'publish_time','expire_time','subject'"
bulletin_id : bulletin-id to get info or view bulletin, e.g. "view_bulletin.php?bid=$bulletin_id"
target_type : see field 'Bulletin.TargetType' in 'specs/db/table-Bulletin.txt'
category : see field 'Bulletin.Category' in 'specs/db/table-Bulletin.txt'
publish_time : publish-time of bulletin, defines order of bulletins
expire_time : bulletin expires on expire-time (auto-read-mark)
subject : bulletin title
# header-line with format of message-data-line (version = 2)
"## M,message_id,folder_id,type,'sender','subject','date'"
message_id : message-id, e.g. http://www.dragongoserver.net/message.php?mode=ShowMessage&mid=1595525
folder_id : current folder-id of message
- 2 = NEW-folder
- 3 = REPLY-folder
type : message-type
- NORMAL = normal private message
- INVITATION = invitation
- DISPUTED = disputed invitation
- RESULT = normal result message
sender : sender-name, '[Server message]' for server-messages
subject : message-subject
date : date when message has been sent
# header-line with format of message-data-line (version < 2), though header-line not included in output
"## M,message_id,'sender','subject','date'"
# header-line with format of game-data-line (version = 2)
"## G,game_id,'opponent_handle',player_color,'lastmove_date','time_remaining',game_action,game_status,move_id,tournament_id,shape_id,game_type,game_prio,'opponent_lastaccess_date',handicap"
game_id : game-id, e.g. http://www.dragongoserver.net/game.php?gid=317416
opponent_handle : user-id (handle) of users opponent
player_color : B | W = current color of player to move
lastmove_date : date of last-move in format "YYYY-MM-DD hh:mm:ss[ GMT]" (timezone only if not logged-in)
time_remaining : time-remaining of player-to-move,
- version = 2: format described in section (6b) "TimeLimit-formats" in section "Format of [TR] Time-remaining"
- version < 2: format described in section (6b) "TimeLimit-formats" in section "Format of [TL] Time-limit"
game_action : next action of player in game
- 1 = set handicap-stones
- 2 = play next move (or pass or resign)
- 3 = do scoring
- 10 = fair-komi-negotiation: enter komi-bid
- 11 = fair-komi-negotiation: enter komi-bid or accept last komi-bid
- 12 = fair-komi-negotiation: choose color
- 13 = fair-komi-negotiation: wait (shouldn't happen for player-to-move)
- 0 = unknown / unsupported state
game_status : KOMI | PLAY | PASS | SCORE | SCORE2 = current game-status
- KOMI = fair-komi negotiation
- PLAY = normal play-mode
- PASS = one player has passed
- SCORE = first player enters scoring step
- SCORE2 = other player enters scoring step (agree/disagree with score, or resume playing)
move_id : required for move-context, see section (3a)
tournament_id : tournament-id, e.g. http://www.dragongoserver.net/tournaments/view_tournament.php?tid=19,
0 if game is not part of a tournament
shape_id : shape-id, e.g. http://www.dragongoserver.net/view_shape.php?shape=3,
0 if game is not a shape-game
game_type : game-type and game-players info, format:
- GO
- TEAM_GO(N:M)
- ZEN_GO(N)
game_prio : priority set by user for game
- value-range: -32768..32767
- 0 = not-loaded or no prio
- NOTE: prio is only loaded if next-game-order for status-games is priority or order was given as URL-argument.
Please note, that requests with different 'order'-argument use the same cache-key and therefore you need to
wait for cache-expiry to get the correct result.
opponent_lastaccess_date : date of opponents last-access-date in format "YYYY-MM-DD hh:mm:ss[ GMT]" (timezone only if not logged-in)
handicap : number of handicap-stones
# game-data-lines without header-line for status-games (version < 2), though header-line not included in output
"'G', game_id, 'opponent_handle', player_color, 'lastmove_date', 'time_remaining'"
time_remaining : time-remaining of player-to-move (different format to version=2),
- version = 2: see above
- version < 2: format described in section (6b) "TimeLimit-formats" in section "Format of [TL] Time-limit"
# header-line with format of multi-player-game data-line (only for version >= 2)
"## MPG,game_id,game_type,ruleset,size,lastchanged_date,ready_to_start"
game_id : see game-data
game_type : see game-data
ruleset : JAPANESE | CHINESE
size : board-size [int]
lastchanged_date : date of last-change in format "YYYY-MM-DD hh:mm:ss"
ready_to_start : 1 = indicates if all players joined, so the game can be started,
0 otherwise
Example output:
## B,count,bulletin_id,target_type,category,'publish_time','expire_time','subject'
B,1,17,ALL,MAINT,'2011-04-30 13:58:00','2011-05-30 13:58:00','very important subject'
## M,message_id,folder_id,type,'sender','subject','date'
M,1595525,2,NORMAL,'[Server message]','Removal from tournament #123','2010-09-19 20:53:31'
## G,game_id,'opponent_handle',player_color,'lastmove_date','time_remaining',game_action,game_status,move_id,tournament_id,shape_id,game_type,game_prio,opponent_lastaccess_date
G,317416,'fractic',B,'2007-05-27 12:21:51','J: 83d 14h (+ 1d * 10)',2,PLAY,62,0,0,'GO',0,'2007-05-27 15:00:00'
G,320121,'ejlo',B,'2009-02-01 20:41:49','C: 1d 10h (+ 3d / 5)',2,PLAY,8,0,3,'GO',5,'2009-03-01 10:00:00'
G,527776,'physimatic',W,'2010-10-03 18:28:52','F: 8d (+ 12h)',3,SCORE2,285,19,0,'TEAM_GO (2:2)',-2,'2011-04-30 17:38:22'
## MPG,game_id,game_type,ruleset,size,'lastchanged_date'
MPG,527777,TEAM_GO(3:1),CHINESE,9,'2010-10-03 16:00:00',1
Errors:
* Quick-Status Errors:
- all errors of: [E-LOGIN], [E-GEN]
- no_uid : no user-id found (maybe cookies expired)
- unknown_game : invalid game
- unknown_user : unknown user-id specified
Examples:
# get own quick-status: login, get new private-messages and status-games
login.php?quick_mode=1&userid=user&passwd=userpassword
quick_status.php
# get quick-status for other user
quick_status.php?uid=2
quick_status.php?user=ejlo
#-------- (4.RSS) RSS-Feed "rss/status.php" -----------------------------------
Purpose:
The information about private messages and games from the status-page
can also be retrieved using a RSS feed.
The main URL for the RSS-feed is:
http://www.dragongoserver.net/rss/status.php
Information returned in RSS-feed about status-games:
- opponent-name
- link to game on DGS-website
- game-id
- color
- last move
- last-changed-date
- link to move in game on DGS-website
Errors:
- all errors of: [E-LOGIN], [E-GEN]
Example of usage:
# 1. let the server identify you by your cookies:
http://www.dragongoserver.net/rss/status.php
# 2. Ask for an authentification:
http://www.dragongoserver.net/rss/status.php?authid=guest
# 3. Force your complete identification:
http://www.dragongoserver.net/rss/status.php?userid=guest&passwd=guest
#-------- (4.WAP) WAP-Feed "wap/status.php" -----------------------------------
Purpose:
The information about private messages and games from the status-page
can also be retrieved using a WAP feed.
The main URL for the WAP-feed is:
http://www.dragongoserver.net/wap/status.php
Information returned in RSS-feed about status-games: see RSS-feed
Errors:
- all errors of: [E-LOGIN], [E-GEN]
Example of usage:
# 1. let the server identify you by your cookies:
http://www.dragongoserver.net/wap/status.php
# 2. Ask for an authentification:
http://www.dragongoserver.net/wap/status.php?authid=guest
# 3. Force your complete identification:
http://www.dragongoserver.net/wap/status.php?userid=guest&passwd=guest
#-------- (4.QPL) Quick-Play "quick_play.php" ---------------------------------
Purpose:
The former quick-play page "quick_play.php" allows to play a game cycle
from 2nd move on till before the first pass, and no scoring-steps included.
Clocks, prisoners and ko are handled in the same way the web-site would do.
You can only use "quick_play.php" to answer a move WITH coordinates
by a move WITH coordinates. This excludes all particular steps of the game
like placing handicap stones, passing, resigning and scoring.
Use the conventionnal manual Dragon interface (web-site) to resolve
these steps, or use the new approach.
This page will be replaced by: (3a) game-object using "quick_do.php" page.
Request:
quick_play.php?gid=&handle=&sgf|board_prev=&sgf|board_move=&color=&message=
Options:
= integer
- game-id
= string
- user-id
= string
- arg 'sgf_prev' : the previous move coords (=the stone marked with a circle on the web-site) in SGF-format
- arg 'sgf_move' : the move coords you want to play in SGF-format, e.g. 'aa'
- arg 'board_prev' : the previous move coords (=the stone marked with a circle on the web-site) in label-format
- arg 'board_move' : the move coords you want to play in label-format, e.g. 'a19'
- Notes:
- The arguments '.._prev' and '.._move' could be either 'sgf' or 'board' (=label) coordinates independently.
- if both are given 'sgf_..' and 'board_..' coordinate arguments,
then the 'sgf'-version takes precedence
- Example:
- With a 19x19 board, the upper left intersection is 'aa' in sgf coordinates and the lower right is 'ss'.
In board coordinates, these 2 points are 'a19' and 't1' (take care about the skipped 'i'). Lowercase is needed.
= B | W
- color to play (W or B). This is your color.
The same as returned by the quick-status page.
= string
- optional field containing a move message. Take note, that for long texts
you should consider using a HTTP-POST instead of a HTTP-GET to transfer your data.
Response:
"Ok" on success
- Errors:
- all errors of: [E-LOGIN], [E-GEN], [E-GAME], [E-GAMEMOVE]
Example:
# login setting cookie in HTTP-header storing: handle, sessioncode
login.php?quick_mode=1&userid=user&passwd=userpassword
# retrieve list of games to play in
quick_status.php
# download game with moves in SGF-format (also see Example in section (3a))
sgf.php?gid=12345&owned_comments=1&quick_mode=1
# use quick-play to do your moves
quick_play.php?gid=12345&handle=user&board_prev=a19&board_move=t1&color=W&message=eat_this
or
quick_play.php?gid=12345&handle=user&sgf_prev=aa&board_move=tt&color=W&message=eat_this
#-------- (5) Errors ----------------------------------------------------------
All errors are given in order of appearance following flow in source-code
for specific actions.
Errors:
* [E-LOGIN] Login Errors:
- not_logged_in : user is not logged in
- wrong_userid : unknown user-id provided for login
- wrong_password : wrong password to login given user
- need_activation : newly registered accounts must first be activated by email verification
- cookies_disabled : no cookies set with user-id and login-session
- fever_vault : login quota exceeded
- login_denied : login of user denied by admin
- ip_blocked_guest_login : IP-range is blocked for login as guest-user
* [E-GEN] General Errors:
- server_down : server in maintenance-mode
- invalid_command : invalid command for quick-suite
- invalid_args : missing or invalid arguments given
- unknown_entry : entry identified by id could not be found
- mysql_connect_failed : connection to database failed
- mysql_select_db_failed : database could not be selected
- mysql_query_failed : database query failed
- mail_failure : sending mail for notification failed (e.g. for quota-exceeded)
- not_allowed_for_guest : guests are not allowed to use some of quick-suite pages
* [E-GAMECREATE] Game Creation Errors:
- unknown_ruleset : unknown ruleset (known: JAPANESE, CHINESE)
- handicap_range : invalid handicap specified
- komi_range : invalid komi specified
- invalid_snapshot : snapshot for shape-game is invalid
- invalid_snapshot_char : invalid character to represent shape-snapshot used
- mismatch_snapshot : shape-game inconsistency with snapshot detected
- no_initial_rating : player needs rating for required handicap-type
- time_limit_too_small : given time is too small
- illegal_position : illegal position detected on loading game-board
- unknown_game : game-data can not be found
- invited_to_unknown_game : game invited to is unknown to system
- game_already_accepted : game has already been accepted, probable race-condition
- wrong_dispute_game : players do not match with dispute-game
- wrong_players : players do not match with game-request
- mysql_start_game : database-error on starting game
- mysql_data_corruption : data is corrupted -> contact admin
- feature_disabled : feature (probably tournament) is disabled
- internal_error : data is inconsistent -> contact admin
* [E-GAME] Game Errors:
- unknown_game : invalid game
- game_not_started : game has not started yet (still in invitation-mode)
- game_finished : game is already finished (move/operation not possible)
- invalid_game_status : game is in wrong status to perform requested operation
- database_corrupted : player-to-move can not be determined -> contact admin
- already_played : 'move_id' context for current move in game is no longer valid,
or was wrong in the 1st place
- not_game_player : you are not a player of the game
* [E-GAMEMOVE] Game Move Errors:
- invalid_coord : invalid coordinates given
- move_problem : 'pass'-move only allowed for "move"-command
- not_your_turn : it is not your turn to move in the game;
(error not occuring for commands "delete", "resign")
- internal_error : board-data could not be loaded -> contact admin
- invalid_action : unknown action
- mysql_update_game : database query to update game failed
- mysql_insert_move : database query to insert move failed
- opponent_not_found : database corrupt regarding game-opponent -> contact admin
- receiver_not_found : message-receiver for notify could not be found -> contact admin
- mysql_insert_message : database query to insert message for notify failed
* [E-MSG] Message Errors:
- unknown_message : unknown message-id specified
- receiver_not_found : given recipient(s) can not be found
- folder_not_found : specified folder is unknown for current user
- bulkmessage_self : bulk-messages can not be sent to oneself
- invite_bad_gamesetup : internal consistency-error, missing invitation game-setup
* [E-MSGSEND] Message Send Errors:
- invalid_action : failure on checking to send a message, detailed error-texts found in "error_texts"-field
- reply_invalid : invalid reply, because ...
- message can't be replied to, or no reply possible for message
- reply to myself is not allowed (as that doesn't show up in message-thread-view)
- for normal messages (can be ok for accepting/declining invitation):
reply only possible to NORMAL-messages, not to invitations/disputes or system-messages
- for accepting/declining invitation:
reply only possible to invitation message, not to normal messages or already disputed invitation
- used OTHER_UID|OTHER_HANDLE arguments to specify message-recipient,
recipient must be omitted as it's determined from message-sender
- folder_forbidden : invalid target folder used to move replied message to
- folder-id must be >0
- NEW-folder (folder-id=2) and SENT-folder (folder-id=5) are not allowed for old message to store into
- game_delete_invitation : error on game-deletion/decline-invitation detected,
nothing found to be deleted, which could mean that the invitation was already declined
#-------- (6) Formats ---------------------------------------------------------
#-------- (6a) Date-Formats ---------------------------------------------------
There are two date-formats used for the quick-suite:
- "YYYY-MM-DD"
used when there is no time-info available, e.g. for registration-date
- "YYYY-MM-DD hh:mm:ss"
standard format for quick-suite for date-times
#-------- (6b) TimeLimit-Formats ----------------------------------------------
There are two major time-limit-formats used on DGS, which can appear
in the output of the quick-suite for the three different time-systems
in use (JAP=Japanese, CAN=Canadian, FIS=Fischer-time):
- [TL] Time-limit : static time-settings for game
- [TR] Time-Remaining : dynamic time of game for each player
The main specification for time-limits and time-remaining you can find in:
- time-specifications defined in 'specs/time.txt'
* General format:
- Format of TIME is:
- "Xd Yh" = X days and Y hours
- "0h" = zero time
- one of DAYS or HOURS is optional
- Format of EXTRATIME for types:
- type=JAP: "TIME * Z" = TIME byo-yomi-time per move and Z extra periods
- type=CAN: "TIME / Z" = TIME byo-yomi-time per Z stones
- type=FIS: "TIME" = TIME extra-time per move
* Format of [TL] Time-limit:
- Examples:
- see "include/time_functions.php", method "echo_time_limit()"
- see "scripts/tests/TimeFormatTest.php", test-method "test_echo_time_limit()"
* Format of [TR] Time-remaining:
- Examples:
- see "include/time_functions.php", method "echo_time_remaining()"
- see "scripts/tests/TimeFormatTest.php", test-methods:
- for TYPE=JAP: "test_echo_time_remaining_jap()"
- for TYPE=CAN: "test_echo_time_remaining_can()"
- for TYPE=FIS: "test_echo_time_remaining_fischer()"
#-------- (7) Classes and Files -----------------------------------------------
This section shortly describes the framework-classes and files in use.
For more details you may also check the source-code documentation of the classes,
their variables and functions.
- quick_do.php:
Facade to quick-suite to delegate commands on objects to quick-handlers.
- include/quick/...
Containing all quick-handlers.
#-------- (8) Possible Future Enhancements ------------------------------------
# Priority (1=high, 5=low, ?=unknown) is added, e.g. Prio(1)
This section outlines some ideas that came to mind regarding the quick-suite,
but are not necessarily going to be implemented (soon or at all).
* Prio(?): add more handlers for remaining DGS objects and operations
* encoding via JSON:
- [quick] [site] eval-step #1 (occur for WHAT?): needs UTF8-encoded data from database :( :( :( => need proper handling of UTF8 !!!!
- [quick] encoding JSON: http://www.dragongoserver.net/forum/read.php?forum=10&thread=27755#29511
* game-obj:
- handle fair-komi
- handle MPG with game-players >2, handle setup for multi-player-game
- replace_notes, add_time, set_prio
* message-obj:
- handle send-invitation / send-dispute
* wroom-obj:
- new-game
* user-obj:
- user-vacation, picture, list-cmd
- [quick] user-obj: get_bio-cmd: -> { bio: [ key:val, ...], ...] }
* contact-obj:
- replace-cmd = insert_or_update
- delete