-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ported files from other projects and made some modifications.
- Loading branch information
Showing
44 changed files
with
2,027 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,104 +1,3 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
lerna-debug.log* | ||
|
||
# Diagnostic reports (https://nodejs.org/api/report.html) | ||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
*.pid.lock | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
*.lcov | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# Bower dependency directory (https://bower.io/) | ||
bower_components | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (https://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules/ | ||
jspm_packages/ | ||
|
||
# TypeScript v1 declaration files | ||
typings/ | ||
|
||
# TypeScript cache | ||
*.tsbuildinfo | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional eslint cache | ||
.eslintcache | ||
|
||
# Microbundle cache | ||
.rpt2_cache/ | ||
.rts2_cache_cjs/ | ||
.rts2_cache_es/ | ||
.rts2_cache_umd/ | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Output of 'npm pack' | ||
*.tgz | ||
|
||
# Yarn Integrity file | ||
.yarn-integrity | ||
|
||
# dotenv environment variables file | ||
.env | ||
.env.test | ||
|
||
# parcel-bundler cache (https://parceljs.org/) | ||
.cache | ||
|
||
# Next.js build output | ||
.next | ||
|
||
# Nuxt.js build / generate output | ||
.nuxt | ||
dist | ||
|
||
# Gatsby files | ||
.cache/ | ||
# Comment in the public line in if your project uses Gatsby and *not* Next.js | ||
# https://nextjs.org/blog/next-9-1#public-directory-support | ||
# public | ||
|
||
# vuepress build output | ||
.vuepress/dist | ||
|
||
# Serverless directories | ||
.serverless/ | ||
|
||
# FuseBox cache | ||
.fusebox/ | ||
|
||
# DynamoDB Local files | ||
.dynamodb/ | ||
|
||
# TernJS port file | ||
.tern-port | ||
node_modules | ||
.npmrc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import Action from './actions/Action' | ||
import Resolver from './actions/Resolver' | ||
|
||
/** | ||
* AliasedActions are the lowest level of user-facing elements. Actions are executed by the user and are simply | ||
* a wrapper to reference an Action and it's arguments. | ||
*/ | ||
class AliasedAction { | ||
|
||
/** | ||
* The key of this AliasedAction. Should probably be CAPS_SNAKE_CASE. | ||
*/ | ||
key: string | ||
/** | ||
* Array of server identifiers that this AliasedAction is available on. | ||
*/ | ||
availableOn: string[] = [] | ||
/** | ||
* The Action which this AliasedAction is a wrapper for. | ||
*/ | ||
action: Action | ||
|
||
/** | ||
* Constructor | ||
* @param key {string} The key of this item. | ||
*/ | ||
constructor (key: string) { | ||
this.key = key | ||
|
||
} | ||
|
||
/** | ||
* Deserialize a JSON-stringified AliasedAction into an AliasedAction object. | ||
* @param json {string} The JSON to deserialize. | ||
* @return {Promise<AliasedAction>} The AliasedAction that was deserialized. | ||
*/ | ||
static async deserialize(json: string) : Promise<AliasedAction> { | ||
const obj = JSON.parse(json) | ||
const aa = new AliasedAction(obj.key) | ||
for(const prop in obj) { | ||
if(!obj.hasOwnProperty(prop)) { | ||
continue | ||
} | ||
aa[prop] = obj[prop] | ||
} | ||
aa.action = await Resolver.deserialize(JSON.stringify(obj.action)) | ||
return aa | ||
} | ||
} | ||
|
||
export default AliasedAction |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/** | ||
* Buttons are the median user-facing element, between AliasedActions and Screens. Screens contain a list of | ||
* Buttons, and Buttons contain a list of AliasedActions. | ||
*/ | ||
class Button { | ||
|
||
/** | ||
* The key of this Button. Unique identifier, should probably be CAPS_SNAKE_CASE | ||
*/ | ||
key: string | ||
/** | ||
* Array of server identifiers that this Button is available on. | ||
*/ | ||
availableOn: string[] = [] | ||
/** | ||
* Array of AliasedAction keys which this Button executes. AliasedAction objects are not used directly to reduce | ||
* Action size, remove redundant references to AliasedActions, and due to the async nature in how AliasedActions are | ||
* handled by the client. | ||
*/ | ||
actions: string[] = [] | ||
/** | ||
* The URL to the image which can be displayed as this Button, specifically on "IMAGES" type Screens. | ||
*/ | ||
imageURL = '' | ||
/** | ||
* The translation key for this Button's title. | ||
*/ | ||
translationKey = '' | ||
|
||
/** | ||
* Constructor | ||
* @param key {string} The key/ID of this item. | ||
*/ | ||
constructor (key: string) { | ||
this.key = key | ||
} | ||
|
||
/** | ||
* Deserialize a JSON-stringified Button into an Button object. | ||
* @param json {string} The JSON to deserialize. | ||
* @return {Promise<Button>} The Button that was deserialized. | ||
*/ | ||
static async deserialize(json: string) : Promise<Button> { | ||
const obj = JSON.parse(json) | ||
const btn = new Button(obj.key) | ||
for(const prop in obj) { | ||
if(!obj.hasOwnProperty(prop)) { | ||
continue | ||
} | ||
btn[prop] = obj[prop] | ||
} | ||
return btn | ||
} | ||
} | ||
|
||
export default Button |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
const ScreenTypes = Object.freeze({ | ||
IMAGES: 'IMAGES', | ||
BUTTONS: 'BUTTONS' | ||
}) | ||
|
||
/** | ||
* A Screen in Quickplay is the highest level of user-facing objects. Screens are a set of Buttons which can be laid | ||
* out in a variety of ways. The client can display these Screens. | ||
*/ | ||
class Screen { | ||
|
||
/** | ||
* The key of this Screen. Unique identifier, should probably be CAPS_SNAKE_CASE. | ||
*/ | ||
key: string | ||
/** | ||
* Array of server identifiers that this Screen is available on. | ||
*/ | ||
availableOn: string[] = [] | ||
/** | ||
* Array of Button keys which this Screen renders. Button objects are not used directly to reduce Action | ||
* size, remove redundant references to Buttons, and due to the async nature in how Buttons are | ||
* handled by the client. | ||
*/ | ||
buttons: string[] = [] | ||
/** | ||
* Type of Screen that this Screen is. Should be "IMAGES" or "BUTTONS", in most cases. | ||
* @see ScreenTypes | ||
*/ | ||
screenType = '' | ||
/** | ||
* The translation key for this Screen's title. | ||
*/ | ||
translationKey = '' | ||
/** | ||
* List of AliasedActions which should be executed when the client clicks this Screen's back button. | ||
*/ | ||
backButtonActions: string[] = [] | ||
/** | ||
* The URL to the image which can be displayed at the top of this Screen. | ||
*/ | ||
imageURL = '' | ||
|
||
/** | ||
* Constructor | ||
* @param key {string} The key/ID of this item. | ||
* @param screenType {string} Type of screen that this screen is. | ||
*/ | ||
constructor (key: string, screenType: string) { | ||
this.key = key | ||
this.buttons = [] | ||
this.screenType = screenType | ||
if(!ScreenTypes[this.screenType]) { | ||
throw new Error('Invalid screen type: Screen type must be IMAGES or BUTTONS.') | ||
} | ||
this.backButtonActions = [] | ||
} | ||
|
||
/** | ||
* Deserialize a JSON-stringified Screen into an Screen object. | ||
* @param json {string} The JSON to deserialize. | ||
* @return {Promise<Screen>} The Screen that was deserialized. | ||
*/ | ||
static async deserialize(json: string) : Promise<Screen> { | ||
const obj = JSON.parse(json) | ||
const screen = new Screen(obj.key, obj.screenType) | ||
for(const prop in obj) { | ||
if(!obj.hasOwnProperty(prop)) { | ||
continue | ||
} | ||
screen[prop] = obj[prop] | ||
} | ||
return screen | ||
} | ||
|
||
} | ||
|
||
export default Screen | ||
export {ScreenTypes} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import {Buffer} from 'buffer' | ||
|
||
/** | ||
* Actions are the core mechanism behind how Quickplay operates. Whenever the client/user | ||
* clicks a button, presses a keybind, receives instructions from the web server, etc., | ||
* Besides some of the current commands system, the client is not able to do any I/O other than what | ||
* is available through Actions (eventually, ideally all the Quickplay commands would also run Actions). | ||
* | ||
* Actions are serializable in a similar format to Minecraft packets, and can be sent over the wire. | ||
* The structure is as follows: | ||
* When serialized, all Actions must contain at least 2 bytes. These are the first two bytes, which | ||
* are the Action's ID. All subsequent bytes are considered the payload. They can be considered arguments | ||
* to the Action, and are split up into partitions, each of which is one argument. An argument begins | ||
* with the first 4 bytes being the length x of the argument. After those bytes, the next x bytes are | ||
* the actual argument. This signature repeats, until there are no more bytes. | ||
* | ||
* If there are too few bytes in the Action, a RangeError will be thrown. It is possible | ||
* for a serialized Action to be valid, but the subsequent execution of the Action to fail if there were | ||
* not enough arguments provided in the payload. | ||
* | ||
* Actions can also be sent to the web server, providing context to actions/events occurring on the client, | ||
* such as exceptions, connection status, button presses, etc. | ||
*/ | ||
class Action { | ||
|
||
static id = 0 | ||
id = 0 | ||
payloadObjs:Buffer[] = [] | ||
|
||
/** | ||
* Build an action into a Buffer from its ID and payload list. | ||
* @return {Buffer} Built buffer which can be sent over the wire. | ||
*/ | ||
build () : Buffer { | ||
let body = Buffer.alloc(2) | ||
body.writeUInt16BE(this.id, 0) | ||
|
||
for(let i = 0; i < this.payloadObjs.length; i++) { | ||
const payloadSize = Buffer.alloc(4) | ||
|
||
payloadSize.writeInt32BE(this.payloadObjs[i].byteLength, 0) | ||
body = Buffer.concat([body, payloadSize, this.payloadObjs[i]]) | ||
} | ||
|
||
return body | ||
} | ||
|
||
/** | ||
* Add an item to the payload. | ||
* @param obj {Buffer} Item to add. | ||
*/ | ||
addPayload (obj: Buffer) : void { | ||
this.payloadObjs.push(obj) | ||
} | ||
|
||
/** | ||
* Get an object from the payload at the specified index | ||
* @param index {number} Index of the item to get. Should be >= 0 and < payloadObjs.length | ||
* @return {Buffer} The payload item, or null if it does not exist. | ||
*/ | ||
getPayloadObject(index: number) : Buffer { | ||
if(this.payloadObjs.length <= index) { | ||
return null | ||
} | ||
return this.payloadObjs[index] | ||
} | ||
|
||
/** | ||
* Get an item from the Payload and convert it to a String in UTF-8. | ||
* @param index {number} Index of the item to get. Must be >= 0 and < payloadObjs.length | ||
* @return {string} Decoded String | ||
*/ | ||
getPayloadObjectAsString(index: number) : string { | ||
const obj = this.getPayloadObject(index) | ||
if(obj == null) { | ||
return null | ||
} | ||
return obj.toString() | ||
} | ||
|
||
} | ||
|
||
export default Action |
Oops, something went wrong.