This is how you steal stuff from dashingdon.com.
Lets people grab stats and attributes like an author's games list or a list of their game scenes (only on games set to public, of course).
It also allows for managing games remotely – this would allow a third-party editor to update your game once you give the system your Game API Key or create new games on your account with your Creation API Key.
There's absolutely no reason to share your Developer API Key or ask a member for their Developer API Key.
All EasyAPI transactions are logged for security. Abuse of the EasyAPI will lead to the banning of the offending user account and/or blocking of the offending IP address from access.
This is how you steal stuff from dashingdon.com.
The default return format is a JSON object. Note that slashes are not escaped.
Comma-separated values with a header row can be returned by appending ?csv
to the request URL.
Nope.
GET /easy/meta
Get yourself some metadata. You'll need to pass your Developer API Key as the Username using Basic Authorization.
[DEVKEY]
– Developer API Keymembers
– # of total membersgames
– # of total gamespublic
– # of public gamesdownloadable
– # of downloadable gamesGET /easy/meta HTTP/1.1
Host: dashingdon.com
Authorization: Basic [DEVKEY]
Cache-Control: no-cache
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dashingdon.com/easy/meta",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"authorization: Basic [DEVKEY]", //[DEVKEY] Must Be Base64 Encoded
"cache-control: no-cache"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
var http = require("https");
var options = {
"method": "GET",
"hostname": "dashingdon.com",
"port": null,
"path": "/easy/meta",
"headers": {
"authorization": "Basic [DEVKEY]", //[DEVKEY] Must Be Base64 Encoded
"cache-control": "no-cache"
}
};
var req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.end();
{"authors":941,"games":780,"public":203,"downloadable":7}
Appending ?csv
will format this output as CSV.
GET /easy/authors
Get a list of authors with at least one published public game. You'll need to pass your Developer API Key as the Username using Basic Authorization.
[DEVKEY]
– Developer API Keyid
– ID of the Authorname
– Author nickname{
"0": {
"id": "EdRbko",
"name": "dashingdon"
},
"1": {
"id": "gg95eE",
"name": "anotherauthor"
},
"2": {
"id": "bb81Aa",
"name": "yetanotherauthor"
}
}
You may also append the author nickname to the GET URL to request that particular author's ID:
GET /easy/authors/dashingdon
{"id":"EdRbko","name":"dashingdon"}
?csv
will format this output as CSV.
GET /easy/authors/[AUTHORID]/games
Retrieve the list of public games by an author. Last Update may be 'null' for JSON and 'NULL' for CSV if the author has never used the update feature. The URL Slug is a sanitized, hypenated version of the Title and it is the name of the directory holding the game files.
[DEVKEY]
– Developer API Key[AUTHORID]
– Author's IDid
Game IDtitle
Titleslug
URL Slugdesc
Descriptionupdate
Last Update (YYYY-MM-DD){
"0": {
"id": 2,
"title": "The Burden",
"slug": "the-burden",
"desc": "Unarmed and unarmored...",
"update": null
},
"1": {
"id": 738,
"title": "Phobia",
"slug": "phobia",
"desc": "Inspired by Obsidian With great fear comes great power.",
"update": null
}
}
"id","title","slug","desc","update"
"2","The Burden","the-burden","Unarmed and unarmored...","NULL"
"738","Phobia","phobia","Inspired by Obsidian With great fear comes great power.","NULL"
All public games can be accessed via the 'short URL' method. Therefore, you can create URLs for each of the returned games by using https://dashingdon.com/go/[GAMEID]
where [GAMEID]
is the first returned value for each entry. For example, above we can see 2 is the Game ID for 'The Burden' so we can access it thusly:
https://dashingdon.com/go/2
By design, private games cannot be accessed via the short URL method.
If you prefer to use the long URL instead (weirdo), you can do so by using https://dashingdon.com/play/[AUTHOR]/[URLSLUG]
where [AUTHOR]
is the author's name and [URLSLUG]
is the 'safe' version of the Title used for the name of the game's directory. Therefore, in this instance:
https://dashingdon.com/play/dashingdon/the-burden
The long URL above may be 'broken' on older games – a temporary remedy (until the game is updated) is to append /mygame/ to the end of the long URL.
GET /easy/games/[GAMEID]
The meat and potatoes. The whole kit and caboodle. The cat's pajamas. Actually, no, not that last one. That's something different.
[DEVKEY]
– Developer API Key Base64 Encoded[GAMEKEY]
– Game API Keytitle
– Game Titleauthor
– Authorslug
– URL Slugdesc
– Descriptionfeedback
– Feedback URLupdate
– Last Update (possible null)stylesheet
– Stylesheet (0 to 9)saveplugin
– Save Plugin (0 for no or 1 for yes)usecompiled
– Use Compiled (0 for no or 1 for yes)scenes
– Scenesfilename
– Text File Name (no .txt extention)size
– File Size (in Bytes, Kilobytes, Megabytes, or Gigabytes)update
– Last Modified (server time) (Y-m-d H:i:s){
"title": "The Burden",
"author": "dashingdon",
"slug": "the-burden",
"desc": "Unarmed and unarmored...",
"feedback": "https://forum.choiceofgames.com/t/the-burden-yet-another-typical-fantasy-adventure/",
"update": null,
"stylesheet": "2",
"saveplugin": "0",
"usecompiled": "0",
"scenes": {
"0": {
"filename": "00_introduction",
"size": "4K",
"update": "2016-09-12 00:38:05"
},
"16": {
"filename": "variables",
"size": "1K",
"update": "2016-09-12 00:38:05"
}
}
}
Again, appending ?csv
will format this output as CSV.
GET /easy/games/[GAMEID]/scenes
Retrieve the list of scenes for a public game. This is a lesser payload that I would ask you to use if you don't need the full game info but are working with a game's scenes.
The filename will not have the '.txt.' extension as that is absolute for scene files. Size will be rounded up to a full number in Bytes, Kilobytes, Megabytes, or Gigabytes as designed by B, K, M, and G respectively. Last Update is the file modified server datetime presented as YEAR[4]-MONTH[2]-DAY[2] HOUR[2]:MINUTE[2]:SECONDS[2]
/ (Y-m-d H:i:s)
in 24-hour notation.
[DEVKEY]
– Developer API Key[GAMEKEY]
– Game API Keyfilename
– Name of the Filesize
– File Sizeupdate
– Last Update{
"0": {
"filename": "00_introduction",
"size": "4K",
"update": "2016-09-12 00:38:05"
},
"1": {
"filename": "01_flashback",
"size": "9K",
"update": "2016-09-12 00:38:05"
},
"15": {
"filename": "sub_moniker",
"size": "710B",
"update": "2016-09-12 00:38:05"
},
"16": {
"filename": "variables",
"size": "1K",
"update": "2016-09-12 00:38:05"
}
}
Again, appending ?csv
will format this output as CSV.
GET /easy/games/[GAMEID]/scenes/[FILENAME]
Retrieve the full text contents of a scene file of a public game. The return format will be UTF-8 encoded plain text with preservation of tabs and spaces.
[DEVKEY]
– Developer API Key[GAMEKEY]
– Game API Key[FILENAME]
– Name of the Scene File without .txt extension*TITLE The Burden
*AUTHOR Dashing Don
*SCENE_LIST
startup
00_introduction
01_flashback
02_flashforward
03_outbound
The crabby old wizard bursts into your barren room with a scowl on his face.
He is every bit as decrepit and unwelcoming as the tower where you've lived for the past six years.
"We're going to help the duchess!" he shouts. "Get your lantern. Be quick, now!"
You walk behind the ambling wizard, your lantern squeaking as it sways from the handle in your fist
and your sandals trampling the tall, wet grass under your feet. You can't recall having any other possessions.
This heaviness in your stomach, this lightness in your head: the feeling grows stronger as you
approach the town of your birth. The town that had long ago forgotten you...
*FINISH
POSTs and PUTs can be used for both Create and Update requests. Generally, POST expects a file while PUT expects the payload in the body of the request.
POST /easy/games/new
Create a new game on the dashingdon.com system.
[DEVKEY]
– Developer API Key[CREATEKEY]
– Creation API Key (this is unique to each member's account)title
– [TITLE] Name of the New Game (must be unique to the author)desc
– [DESC] Short Description (assumed none)public
– [PUBLIC] Either 1 for public game or 0 for private game (assumed 0)stylesheet
– Which stylesheet? 0 to 9saveplugin
– Using the save plugin? 0 for no and 1 for yesusecompiled
– Using a compiled HTML file? 0 for no and 1 for yesdownloadable
– Can compiled HTML be downloaded? 0 for no and 1 for yesfeedback
– The URL or email address for game feedback201 Created
– On Success 401 Unauthorized
– Authentication Failed 409 Conflict
– Game (with that exact title!) Exists$username = '[DEVKEY]';
$password = '[CREATEKEY]';
$ch = curl_init();
$data = array(
'title' => '[TITLE]',
'description' => '[DESC]',
'public' => '[PUBLIC]'
);
curl_setopt($ch, CURLOPT_URL, 'https://dashingdon.com/easy/games');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
The [GAMEKEY]
of the created game will be returned so that you can further manage that game through your system.
{"gamekey":"[GAMEKEY]"}
PUT /easy/games/new
Create a new game on the dashingdon.com system using PUT.
[DEVKEY]
– Developer API Key[CREATEKEY]
– Creation API Key (this is unique to each member)title
– [TITLE] Name of the New Game (must be unique to the author)desc
– Short Description (assumed none)public
– Either 1 for public game or 0 for private game (assumed 0)stylesheet
– Which stylesheet? 0 to 9saveplugin
– Using the save plugin? 0 for no and 1 for yesusecompiled
– Using a compiled HTML file? 0 for no and 1 for yesdownloadable
– Can compiled HTML be downloaded? 0 for no and 1 for yesfeedback
– The URL or email address for game feedback201 Created
– On Success 401 Unauthorized
– Authentication Failed 409 Conflict
– Game (with that exact title!) Exists{
"title":"thistitle",
"public":"no",
"desc":"The short description.",
"stylesheet":9,
"saveplugin":1,
"usecompiled":0,
"downloadable":0,
"feedback":"http://thisfeedbackurl.dot/coolgame/"
}
The [GAMEKEY]
of the created game will be returned so that you can further manage that game through your system.
{"gamekey":"[GAMEKEY]"}
POST /easy/games/[GAMEID]/scenes
Create or update a scene for a game using a POSTed file.
[DEVKEY]
– Developer API Key[GAMEKEY]
– Game API Key[SCENENAME]
– Name of the Scene File without .txt extentionfile
– Scene .txt (UTF-8) File (will be renamed to [SCENENAME])200 OK
– On Successful Update201 Created
– On Successful Create 401 Unauthorized
– Authentication Failed 403 Forbidden
– No API Access to Game OR File Is Not a Text File 413 Request Entity Too Large
– File Exceeds Max Size Allowed$username = '[DEVKEY]';
$password = '[GAMEKEY]';
$filepath = $_FILES['file']['tmp_name'];
$filename = $_FILES['file']['name'];
$data = array(
'scenename' => '[SCENENAME]',
'file' => "@$filepath",
'filename' =>$filename
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://dashingdon.com/easy/games/[GAMEID]/scenes');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_exec($ch);
curl_close($ch);
https://[DEVKEY]:[CREATEKEY]@dashingdon.com/easy/games/[GAMEID]/scenes
curl_setopt($ch, CURLOPT_USERPWD, "[DEVKEY]:[CREATEKEY]");
curl_setopt($ch, CURLOPT_HTTPHEADER, "authorization: Basic [BASE64([DEVKEY]:[GAMEKEY])]");
{"location": "https://dashingdon.com/play/[AUTHORNAME]/[GAMENAME]/mygame/scenes/[SCENENAME].txt"}
PUT /easy/games/[GAMEID]/scenes/[SCENENAME]
Create or update an existing scene .txt file in a game's directory using PUT. The body of the PUT request must contain the content of the file in raw text.
[DEVKEY]
– Developer API Key[GAMEKEY]
– Game API Key [SCENENAME]
– Name of the Scene File without .txt extention[BODY]
– The Raw Text Contents of the Scene200 OK
– On Successful Update201 Created
– On Successful Create 401 Unauthorized
– Authentication Failed 413 Request Entity Too Large
– Content Exceeds Max Size Allowed$username = '[DEVKEY]';
$password = '[GAMEKEY]';
$data = "...*FAKE_CHOICE\r\n\t#I've grown\r\n\t\t*set distinction \"taller\"\r\n\t#I didn't even..."
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://dashingdon.com/easy/games/[GAMEID]/scenes/[SCENENAME]');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_exec($ch);
curl_close($ch);
var http = require("https");
var options = {
"method": "PUT",
"hostname": "dashingdon.com",
"port": null,
"path": "/easy/games/[GAMEID]/scenes/[SCENENAME]",
"headers": {
"authorization": "Basic [BASE64([DEVKEY]:[GAMEKEY])]",
"cache-control": "no-cache"
}
};
var req = http.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
var body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.write("...He turns and sprints to the tower.\r\n\r\n\t#\"Um… what do you plan on doing with my ${bet} if you win...");
req.end();
{"location": "https://dashingdon.com/play/[AUTHORNAME]/[GAMENAME]/mygame/scenes/[SCENENAME].txt"}