SSTP/1.x

Translated Document

This document has been translated from the original Japanese by members of the Ukagaka Dream Team community.

To see the original document, click here.

To submit corrections/updates, see our repository to open an issue or find where to contact us.

SSTP/1.x

Reference: SSTP (External site)

Currently, DirectSSTP relies heavily on Windows specifications and is not intended for implementation on other operating systems.
Since the IPC mechanism itself exists in other OSs, it would be desirable to define a separate specification.
If the specifications are decided, we will consider publishing them separately, so please contact Ukadoc Project.

Summary

SSTP is a general-purpose communication specification between ghosts. It can be used for simple SakuraScript playback, external event notification, etc.
Essentially, communication is done via TCP/IP. It listens on port 9801 or 9821 (SSP only), and when you send a request according to the SSTP protocol, the results of the processing are returned.
For security reasons, unless you change the settings, listening is now limited to localhost, and communication from outside the terminal is not possible. In the past, it also listened to port 11000, but this has now been discontinued as it was misidentified as communication by malware.
Although 7743 and 98901 are registered in IANA's port number registry, only 9801 is in actual operation.
There is a protocol with the same abbreviation, Secure Socket Tunneling Protocol, developed by Microsoft for VPN communication. There is no technical relationship between the two.
It does not take into account frequent communication that requires high performance, and does not have a keep-alive mechanism like HTTP. It disconnects at the end of each communication.

Direct SSTP

Direct SSTP is a communication specification that uses an IPC mechanism that is highly dependent on the OS. The protocol specifications are the same as (Socket) SSTP, but the purpose is to directly specify a ghost for lightweight communication without using TCP/IP, which requires relatively heavy processing.
Currently, the specifications have been determined only for Windows, and are as follows.

Send WM_COPYDATA using the SendMessage function (Post is not allowed)
hWnd in SendMessage = HWND of the target ghost, obtained from FMO
wParam = "own" HWND to which the reply is sent. The response is received by the HWND (window) that specified WM_COPYDATA.
lParam = pointer to COPYDATASTRUCT
copydatastruct.lpData = String according to SSTP protocol
copydatastruct.cbData = String length
copydatastruct.dwData = 9801
Note:
For safety reasons, the sender should provide a zero-terminated string in lpData, and it is desirable that cbData also include a zero-termination.
For safety reasons, the receiver should not expect zero-termination, and should always take cbData into consideration when processing.
The receiving side should treat the HWND that was specified as the communication target as being equivalent to the ghost that was specified to receive in the SSTP protocol, and give priority to that ghost as much as possible.
It is intended only for GUI applications that have at least one window on both the receiving and sending sides, and cannot be used with console applications.

SSTP over HTTP

SSTP over HTTP, implemented in SSP 2.6.32, is an extremely simple mechanism that plugs the SSTP request directly into the HTTP request message body, and returns the SSTP response directly in the HTTP response body.
It is intended to be used to more easily exchange SSTP communications when an application is built using JavaScript, such as Electron.
POST to /api/sstp/v1 using HTTP/1.1 with Content-Type: text/plain, to localhost:9801 (or a separately specified SSTP port).
The response is also returned as-is, with HTTP/1.1 200 OK Content-Type: text/plain.
Note that even if the SSTP response is an error, HTTP is 200 OK.
Note that the Content-Length header is required, and an error will result if it is not present.

Demo

You can use the existing js library to do SSTP over HTTP in js.

Note: If the Origin header does not point to localhost, the request is forced to be treated as an SSTP request from a remote address. In that case, strong restrictions are placed on SakuraScript tags and SSTP methods that can be executed, and the SecurityLevel header is ignored.
This restriction is relaxed only when the Origin of HTTP is localhost and the SecurityLevel of SSTP is local.

request/response

Like other protocols such as SHIORI, it is a proprietary protocol similar to HTTP.
It is mandatory to specify the Charset in the request; if it is not specified, an error will occur, or it will be interpreted as the charset specified by the OS standard.

request

request sample

SEND SSTP/1.0
Charset: UTF-8
Sender: SSTP client
Script: \h\s0Test.\u\s[10]It's a test.
Option: notranslate

Headers common to each method of request

For method-specific information, check the explanations for each method below.

Charset
Character code of the request. Should appear on the very first line.
UTF-8 is recommended if there is no particular reason to use otherwise.
Sender
A string indicating the sender. For example, "SSTP sender tool". For the COMMUNICATE method, the sending ghost's \0 name.
SecurityLevel
Specify the security level when processing with SHIORI or SakuraScript, either local or external.
Only valid for DirectSSTP or requests that are clearly local, such as 127.0.0.1.

SSTP over HTTP is always considered external, except when sent from html, etc., delivered from localhost.
SecurityOrigin [SSP 2.6.59]
送信元サーバを示すURL風の文字列。以下の形式となる。HTTPヘッダのOriginと考え方は同じ。
SecurityOrigin: null
SecurityOrigin: <scheme>://<hostname>
SecurityOrigin: <scheme>://<hostname>:<port>
scheme は通常、http,https,sstpのいずれか。hostnameは送信元サーバ名かIP。portは返信受付可能なポート。
特に指定がない場合は、nullが指定されたものとみなされる。
SSTP over HTTPは、HTTPのOriginヘッダの中身が常に設定され、SSTPの中のSecurityOriginは無視される。
Option
Specify options for how SakuraScript executed by SSTP is handled.
Multiple options can be specified by separating them with commas. The strings that can be specified are as follows.
nodescript - Disable SSTP display on the balloon (disabled for SSTP from remote).
notranslate - No translate processing with OnTranslate or MAKOTO
nobreak - Do not interrupt the currently running script; wait until it finishes.
ID
"Owned SSTP", which is an ID sent by the SHIORI uniqueid or FMO's identification ID (SSP only). This SSTP is treated with the same priority as the ghost's internal processes, ignoring various security checks, locks, etc.
SecurityLevel specification becomes local, and it also enables forced interrupt of playback even in interrupt-disabled states such as \t.
X-SSTP-PassThru-(arbitrary string)
Header passed directly to SHIORI when communicating with the ghost side, such as NOTIFY.
Only minimal processing such as character code conversion is performed, and the (arbitrary string) part and contents are relayed as-is.
HWnd
For DirectSSTP only. Indicates the window handle to which the response should be returned.
The window handle (equivalent to a pointer) data is treated as an unsigned decimal integer and converted to a string.
If omitted, wParam of WM_COMMUNICATE.
ReceiverGhostHWnd [SSP 2.5.57]
For (Socket)SSTP only. Indicates the ghost's \0 window handle to which the request should be sent.
By specifying this, the ghost to be processed is fixed, and the same processing as DirectSSTP is possible via Socket.
If not found, an immediate error termination with 404 Not Found will occur.
ReceiverGhostName [SSP 2.5.57]
For (Socket)SSTP only. Indicates the \0 name of the ghost to which the request should be sent.
By specifying this, the ghost to be processed is fixed, and the same processing as DirectSSTP is possible via Socket. Name version of HWnd.
If not found, an immediate error termination with 404 Not Found will occur.

response

response sample (no data)

SSTP/1.4 200 OK
Charset: UTF-8
Script: \h\s0Test.\u\s[10]It's a test.

response sample (data available)

SSTP/1.4 200 OK
Charset: UTF-8
Script: \h\s0Test.\u\s[10]It's a test.

Additional data here

Headers common to each method of response

Charset
Character code of the request. Should appear on the very first line.
UTF-8 is recommended if there is no particular reason to use otherwise.
It may be intentionally omitted to solve compatibility problems. In such cases, it should be assumed that the character coode is the same as that of the request.
X-SSTP-PassThru-(arbitrary string)
Headers returned directly from SHIORI when communicating with the ghost side, such as NOTIFY.
Only minimal processing such as character code conversion is performed, and the (arbitrary string) part and contents are relayed as-is.

Status code of response

As with HTTP, numbers in the 200s are accepted as normal, and others are errors.

200 OK
Normal completion (with return value)
204 No Content
Normal completion (no return value)
210 Break
Executed but broken during script execution
※Only in very limited circumstances, such as SEND/1.x with Entry. Usually an immediate 200 or 204 return.
400 Bad Request
There is something wrong with the request that cannot be covered.
404 Not Found ※SSP only
The ghost specified by SSTP has not been installed or is not running.
408 Request Timeout
Timeout: When unable to communicate with the Ghost/SHIORI side (usually a very rare occurrence)
409 Conflict
Interrupts are disabled, such as via a \t tag, or other requests are being processed.
413 Payload Too Large ※SSP only
SSTP request was too long and was refused for processing.
420 Refuse
Reception was rejected due to ghost side settings.
500 Internal Server Error ※SSP only
The processing could not be completed due to some problem detected within the processing system.
501 Not Implemented
Could not be processed because it contained unimplemented commands, etc.
503 Service Unavailable
SSTP cannot be accepted due to internal circumstances within the processing system.
505 Version Not Supported ※SSP only
The SSTP version is incorrect (less than 1.0, more than 3.0, etc.)
512 Invisible
Ghost is not visible, e.g. because it is minimized, and nothing can be processed.

Method: NOTIFY

Methods for notifying ghosts of events.
Event header = corresponds to SHIORI/3.0 ID, Reference* remains the same.

Event notification only sample (NOTIFY/1.0)

NOTIFY SSTP/1.0
Charset: UTF-8
Sender: Media Player
Event: OnMusicPlay
Reference0: Wings of Freedom
Reference1: Linked Horizon

If the ghost does not respond to the specified event ID, you can specify an "insurance" script to play.
In such a case, if an IfGhost header is specified, the Script header immediately following is treated as a script exclusively for the specified ghost.

Sample with insurance response (NOTIFY/1.1)

NOTIFY SSTP/1.1
Charset: UTF-8
Sender: Media Player
Event: OnMusicPlay
Reference0: Bow and arrow of red lotus
Reference1: Linked Horizon
IfGhost: Emily,Teddy
Script: \0\s[6]That day, Emily recalled...\n\s[7]I haven't eaten a potato yet today!\1\s[11]Why did you bother to remember now?
IfGhost: ラーシェ,ティセ
Script: \0\s[3]Even though he's a giant, he's only a few train cars tall.\1\s[14]When it stands up vertically, I think it's big indeed.

request specific header

Event
Event ID. In SHIORI/3.0, it is treated as an ID header specification.
Reference*
Reference header of the event, which is passed to SHIORI after minimal processing such as character code conversion.
Script
SakuraScript to be played if the event is not responded to.
IfGhost
If you specify a ghost name in the format "\0 side name, \1 side name", the Script header that comes immediately after is treated as dedicated to that specific ghost.
If there is a Script header that is not immediately after IfGhost, it will be the Script for default processing when IfGhost is not applicable.
If omitted, the same Script header is played for all ghosts.
If the SSTP ghost startup option is enabled, the ghost specified here will be temporarily launched.

response specific header

Script
Script played as a result of event notification. Currently only SSP is supported.

Method: SEND

(To be written)

Method: COMMUNICATE

Using the COMMUNICATE method, you can give an arbitrary string to the ghost from the outside and have it react.
Basically, the reaction is the same as using the communication box inside the ghost, but since it is SSTP, it may not be accepted by the ghost.

Simple COMMUNICATE (COMMUNICATE/1.1)

COMMUNICATE SSTP/1.1
Charset: UTF-8
Sender: User
Sentence: Good morning.

Communicate can be sent and received repeatedly between SSTP servers (≒ ghosts).
When sending with response Reference0 of SHIORI/3.0, the timing for sending SSTP is when SakuraScript has finished playing.
This makes it possible to set up a process in which ghosts that are running simultaneously have a conversation with each other.

Ghost to ghost communication (COMMUNICATE/1.2)

COMMUNICATE SSTP/1.2
Charset: UTF-8
Sender: Emily
HWnd: 28236
Sentence: \0\s[5]Charaaaan! My name is Emily!\nI still have some room in my stomach...?\1\s[11]If you say that, won't you gain weight again?
Surface: 5,11
Reference0: Please give me a sweet potato
Reference1: Give me a lot
Reference2: Give it to me now

request specific header

Reference*
Communicate extended information. In SHIORI/3.0, it is stored in Reference2 or later. SSTP Reference0 = SHIORI Reference2.
Surface
Surface numbers of \0 and \1 at the time the sender ghost sends the communication (≒ at the end of the script execution).
Passed as Surface header in OnCommunicate event.
Option
[Old specification]When "substitute" is specified, \1 speaks the contents of Sentence. ※Not implemented in SSP.

Method: EXECUTE

Using the EXECUTE method, you can obtain various information about ghosts and execute various commands that do not rely on SakuraScript.
Execution of this method will not cause the ghost to speak, but its internal state may be rewritten.

EXECUTE sample

EXECUTE SSTP/1.1
Charset: UTF-8
Sender: SSTP Client
Command: GetName

request specific header

Command or Command[param1,param2...]
The command to be executed. The content to be executed and the information returned are described below.
After the brackets, specify the parameters to be passed to the command to be executed.
Reference* [SSP]
Parameters can also be specified in the header of Reference0~ instead of specifying them in brackets.

See below for the strings that can be specified in the Command header and the results returned by the "additional data" in the response.

Commands that can be specified in the Command header, and additional data that will be returned

GetName
(\0 name),(\1 name) of running ghosts, separated by commas
GetNames [SSP]
List of the \0 names of currently installed ghosts. Newline delimited. Terminated by a blank line.
GetFMO [SSP 2.5.57] [Restricted in Remote]
Obtain information equivalent to the contents of the FMO.
However, this differs from the original FMO (which is shared by a group of concurrently running applications), as it is limited to the internal management of applications that communicate using SSTP.
It is mainly used in console applications that do not have a window and cannot send Direct SSTP, and is used to implement functions equivalent to Direct SSTP by utilizing the ReceiverGhostHWnd header with Socket SSTP only.
Newline delimited, terminated by a blank line.
In the case of a remote request, each path information is omitted, and the header and hwnd are replaced with a dummy.
GetGhostName [SSP]
Name of the running ghost (name in descript.txt)
GetShellName [SSP]
Name of the shell currently in use by the running ghost
GetBalloonName [SSP]
Name of the balloon currently in use by the running ghost
GetVersion
Baseware (running software) version
GetGhostNameList [SSP 2.6.53]
Newline-separated list of all ghost names (names in descript.txt) recognized by SSP.
GetShellNameList [SSP 2.6.53]
Newline-separated list of all shell names (names in descript.txt) recognized by the running ghost.
GetBalloonNameList [SSP 2.6.53]
Newline-separated list of all balloon names (names in descript.txt) recognized by SSP.
GetHeadlineNameList [SSP 2.6.53]
Newline-separated list of all headline names (names in descript.txt) recognized by SSP.
GetPluginNameList [SSP 2.6.53]
Newline-separated list of all plugin names (names in descript.txt) recognized by SSP.
GetShortVersion [SSP 2.6.53]
Baseware (running software) version (period-separated version number only).
You can check if it is the latest version by a simple comparison with ssp.full.version in version.json.
Quiet [Not supported in Remote]
Perform a Restore or remain silent until 16 seconds have elapsed. No additional data (status code 200 successful)
Restore
Quiet is cancelled. No additional data (status code 200 successful)
CompressArchive [SSP] [Not supported in Remote]
Compresses a group of files in a specified folder into a compressed file.
Note that no response will be returned until the process is completed.
Parameter 0: Compressed file name
Parameter 1: Full path of the folder to be compressed
No additional data (status code 200 successful)
ExtractArchive [SSP] [Not supported in Remote]
Decompresses the specified compressed file.
Note that no response will be returned until the process is completed.
Parameter 0: Compressed file name
Parameter 1: Full path of the folder to unzip to
No additional data (status code 200 successful)
DumpSurface [SSP 2.5.98] [Not supported in Remote]
Outputs a composited surface image to the specified directory. Parameters are the same as \![execute,dumpsurface].
Note that no response will be returned until the process is completed.
No additional data (status code 200 successful)
MoveAsync [SSP] [Not supported in Remote]
Perform the same thing as \![moveasync] without SakuraScript. The method of specifying parameters is the same as the SakuraScript version.
Move without async cannot be performed because the response cannot be returned before the SSTP timeout, and it will cause a deadlock.
No additional data (status code 200 successful)
SetTrayIcon [SSP] [Not supported in Remote]
Perform the same thing as \![set,tasktrayicon] without SakuraScript. The method of specifying parameters is the same as the SakuraScript version.
No additional data (status code 200 successful)
SetTrayBalloon [SSP] [Not supported in Remote]
Perform the same thing as \![set,trayballoon] without SakuraScript. The method of specifying parameters is the same as the SakuraScript version.
No additional data (status code 200 successful)
SetProperty [SSP] [Not supported in Remote]
Writes values to the property system.
Parameter 0: Property name
Parameter 1: Value to be set
No additional data (status code 200 successful)
GetProperty [SSP]
Read values from the property system.
Parameter 0: Property name
Additional data is the value of the acquired property.
SetCookie
Writes to the general data storage area, which is saved for each client name specified in Sender.
It is intended to be used similarly to browser "cookies".
Parameter 0: Name of cookie
Parameter 1: Value to be set
No additional data (status code 200 successful)
GetCookie
Read from the general data storage area, which is saved for each client name specified in Sender.
Parameter 0: Name of cookie
Additional data is the value of the cookie obtained.

Method: GIVE

[Old specification] Methods for giving various data to ghost to be processed or reacted to.
This is a very old specification and there is no point in using it now. Please use NOTIFY or COMMUNICATE.

request sample

GIVE SSTP/1.1
Charset: UTF-8
Sender: SSTP client
Document: First, water. Then the powder.

GIVE SSTP/1.1
Charset: UTF-8
Sender: SSTP client
Song: Sasebo no Shigure

request specific header

Document
Document (generic string)
In SHIORI/3.0, it is treated the same as a user communicate, and the OnCommunicate event is fired.
Song
Name of song.
In SHIORI/3.0, the OnMusicPlay event occurs, and Reference0 becomes the string specified in the Song header.