├── .prettierrc.json ├── examples ├── tcp │ ├── advanced │ │ ├── client │ │ │ ├── .gitignore │ │ │ ├── icon.png │ │ │ ├── TCP.tscn │ │ │ ├── default_env.tres │ │ │ ├── project.godot │ │ │ ├── icon.png.import │ │ │ ├── networking.gd │ │ │ └── TCP.gd │ │ └── server │ │ │ ├── src │ │ │ ├── packets.js │ │ │ ├── process │ │ │ │ ├── index.js │ │ │ │ ├── i_want_to_go_right.js │ │ │ │ └── i_want_to_go_left.js │ │ │ ├── StreamTcp.js │ │ │ └── index.js │ │ │ ├── .gitignore │ │ │ ├── package.json │ │ │ └── yarn.lock │ ├── basic │ │ ├── client │ │ │ ├── .gitignore │ │ │ ├── icon.png │ │ │ ├── TCP.tscn │ │ │ ├── default_env.tres │ │ │ ├── project.godot │ │ │ ├── icon.png.import │ │ │ ├── TCP.gd │ │ │ └── networking.gd │ │ └── server │ │ │ ├── .gitignore │ │ │ ├── package.json │ │ │ ├── yarn.lock │ │ │ └── src │ │ │ └── index.js │ └── basic-ssl │ │ ├── client │ │ ├── .gitignore │ │ ├── icon.png │ │ ├── TCP.tscn │ │ ├── default_env.tres │ │ ├── project.godot │ │ ├── icon.png.import │ │ ├── TCP.gd │ │ └── networking.gd │ │ └── server │ │ ├── README.md │ │ ├── .gitignore │ │ ├── package.json │ │ ├── yarn.lock │ │ └── src │ │ └── index.js ├── udp │ ├── advanced │ │ ├── client │ │ │ ├── .gitignore │ │ │ ├── icon.png │ │ │ ├── UDP.tscn │ │ │ ├── default_env.tres │ │ │ ├── project.godot │ │ │ ├── icon.png.import │ │ │ └── UDP.gd │ │ └── server │ │ │ ├── src │ │ │ ├── packets.js │ │ │ ├── process │ │ │ │ ├── i_want_to_go_left.js │ │ │ │ ├── i_want_to_go_right.js │ │ │ │ └── index.js │ │ │ └── index.js │ │ │ ├── .gitignore │ │ │ ├── package.json │ │ │ └── yarn.lock │ ├── basic │ │ ├── client │ │ │ ├── .gitignore │ │ │ ├── icon.png │ │ │ ├── UDP.tscn │ │ │ ├── default_env.tres │ │ │ ├── project.godot │ │ │ ├── UDP.gd │ │ │ └── icon.png.import │ │ └── server │ │ │ ├── .gitignore │ │ │ ├── package.json │ │ │ ├── src │ │ │ └── index.js │ │ │ └── yarn.lock │ └── basic-dtls │ │ ├── client │ │ ├── .gitignore │ │ ├── icon.png │ │ ├── UDP.tscn │ │ ├── default_env.tres │ │ ├── project.godot │ │ ├── UDP.gd │ │ └── icon.png.import │ │ └── server │ │ ├── .gitignore │ │ ├── .gitattributes │ │ ├── UDP_DTLS.tscn │ │ ├── project.godot │ │ ├── icon.svg.import │ │ ├── UDP_DTLS.gd │ │ └── icon.svg ├── websocket │ ├── advanced │ │ ├── client │ │ │ ├── .gitignore │ │ │ ├── icon.png │ │ │ ├── WS.tscn │ │ │ ├── default_env.tres │ │ │ ├── project.godot │ │ │ ├── icon.png.import │ │ │ ├── networking.gd │ │ │ └── WS.gd │ │ └── server │ │ │ ├── .gitignore │ │ │ ├── src │ │ │ ├── packets.js │ │ │ ├── process │ │ │ │ ├── i_want_to_go_left.js │ │ │ │ ├── index.js │ │ │ │ └── i_want_to_go_right.js │ │ │ └── index.js │ │ │ ├── package.json │ │ │ └── yarn.lock │ ├── basic │ │ ├── client │ │ │ ├── .gitignore │ │ │ ├── icon.png │ │ │ ├── WS.tscn │ │ │ ├── default_env.tres │ │ │ ├── project.godot │ │ │ ├── icon.png.import │ │ │ ├── networking.gd │ │ │ └── WS.gd │ │ └── server │ │ │ ├── .gitignore │ │ │ ├── package.json │ │ │ ├── src │ │ │ └── index.js │ │ │ └── yarn.lock │ └── basic-ssl │ │ ├── client │ │ ├── .gitignore │ │ ├── icon.png │ │ ├── WS.tscn │ │ ├── default_env.tres │ │ ├── project.godot │ │ ├── icon.png.import │ │ ├── networking.gd │ │ └── WS.gd │ │ └── server │ │ ├── .gitignore │ │ ├── package.json │ │ ├── README.md │ │ ├── yarn.lock │ │ └── src │ │ └── index.js ├── certs_generator │ ├── icon.png │ ├── .gitignore │ ├── default_env.tres │ ├── project.godot │ ├── ROOT.gd │ ├── icon.png.import │ └── ROOT.tscn └── .gitignore ├── src ├── types │ ├── GodotNull.ts │ ├── GodotArray.ts │ ├── GodotFloat.ts │ ├── GodotString.ts │ ├── GodotBoolean.ts │ ├── GodotNodePath.ts │ ├── GodotDictionnary.ts │ ├── GodotInteger.ts │ ├── IGetReturn.ts │ ├── IDecoderList.ts │ ├── IEncoderList.ts │ ├── GodotVector2.ts │ ├── GodotAabb.ts │ ├── GodotRect2.ts │ ├── GodotVector3.ts │ ├── GodotBasis.ts │ ├── GodotTransform2D.ts │ ├── GodotQuat.ts │ ├── GodotColor.ts │ ├── GodotPlane.ts │ ├── index.ts │ └── GodotTransform.ts ├── index.ts ├── put │ ├── put_64.ts │ ├── put_8.ts │ ├── put_u64.ts │ ├── put_16.ts │ ├── put_32.ts │ ├── put_float.ts │ ├── put_u8.ts │ ├── put_double.ts │ ├── put_u16.ts │ ├── put_u32.ts │ ├── put_var │ │ ├── null.ts │ │ ├── bool.ts │ │ ├── integer.ts │ │ ├── vector2.ts │ │ ├── quat.ts │ │ ├── vector3.ts │ │ ├── color.ts │ │ ├── plane.ts │ │ ├── rect2.ts │ │ ├── aabb.ts │ │ ├── string.ts │ │ ├── float.ts │ │ ├── rawArray.ts │ │ ├── array.ts │ │ ├── dictionnary.ts │ │ └── index.ts │ ├── put_string.ts │ └── index.ts ├── get │ ├── get_var │ │ ├── null.ts │ │ ├── bool.ts │ │ ├── vector2.ts │ │ ├── rawArray.ts │ │ ├── vector3.ts │ │ ├── color.ts │ │ ├── plane.ts │ │ ├── quat.ts │ │ ├── string.ts │ │ ├── rect2.ts │ │ ├── aabb.ts │ │ ├── integer.ts │ │ ├── basis.ts │ │ ├── float.ts │ │ ├── transform2d.ts │ │ ├── transform.ts │ │ ├── float32Array.ts │ │ ├── float64Array.ts │ │ ├── colorArray.ts │ │ ├── stringArray.ts │ │ ├── vector2Array.ts │ │ ├── vector3Array.ts │ │ ├── nodePath.ts │ │ ├── int32Array.ts │ │ ├── int64Array.ts │ │ ├── array.ts │ │ ├── dictionnary.ts │ │ └── index.ts │ ├── get_16.ts │ ├── get_32.ts │ ├── get_8.ts │ ├── get_u8.ts │ ├── get_u16.ts │ ├── get_u32.ts │ ├── get_float.ts │ ├── get_double.ts │ ├── get_64.ts │ ├── get_u64.ts │ ├── index.ts │ └── get_string.ts ├── constants.ts └── utils.ts ├── img ├── logo.png └── logo.svg ├── .npmignore ├── tsconfig.json ├── TODO.md ├── .gitignore ├── LICENSE ├── CHANGELOG.md ├── package.json ├── CONTRIBUTING.md ├── README.md └── test └── data-01.json /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true 3 | } 4 | -------------------------------------------------------------------------------- /examples/tcp/advanced/client/.gitignore: -------------------------------------------------------------------------------- 1 | .import 2 | .godot -------------------------------------------------------------------------------- /examples/tcp/basic/client/.gitignore: -------------------------------------------------------------------------------- 1 | .import 2 | .godot -------------------------------------------------------------------------------- /examples/udp/advanced/client/.gitignore: -------------------------------------------------------------------------------- 1 | .import 2 | .godot -------------------------------------------------------------------------------- /examples/udp/basic/client/.gitignore: -------------------------------------------------------------------------------- 1 | .import 2 | .godot -------------------------------------------------------------------------------- /src/types/GodotNull.ts: -------------------------------------------------------------------------------- 1 | export type GodotNull = null 2 | -------------------------------------------------------------------------------- /examples/websocket/advanced/client/.gitignore: -------------------------------------------------------------------------------- 1 | .import 2 | .godot -------------------------------------------------------------------------------- /examples/websocket/basic/client/.gitignore: -------------------------------------------------------------------------------- 1 | .import 2 | .godot -------------------------------------------------------------------------------- /src/types/GodotArray.ts: -------------------------------------------------------------------------------- 1 | export type GodotArray = T[] 2 | -------------------------------------------------------------------------------- /src/types/GodotFloat.ts: -------------------------------------------------------------------------------- 1 | export type GodotFloat = number 2 | -------------------------------------------------------------------------------- /src/types/GodotString.ts: -------------------------------------------------------------------------------- 1 | export type GodotString = string 2 | -------------------------------------------------------------------------------- /src/types/GodotBoolean.ts: -------------------------------------------------------------------------------- 1 | export type GodotBoolean = boolean 2 | -------------------------------------------------------------------------------- /src/types/GodotNodePath.ts: -------------------------------------------------------------------------------- 1 | export type GodotNodePath = string 2 | -------------------------------------------------------------------------------- /examples/tcp/basic-ssl/client/.gitignore: -------------------------------------------------------------------------------- 1 | .import 2 | .godot 3 | 4 | certs -------------------------------------------------------------------------------- /examples/udp/basic-dtls/client/.gitignore: -------------------------------------------------------------------------------- 1 | .import 2 | .godot 3 | 4 | certs -------------------------------------------------------------------------------- /examples/websocket/basic-ssl/client/.gitignore: -------------------------------------------------------------------------------- 1 | .import 2 | certs 3 | .godot -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tilican/gd-com/HEAD/img/logo.png -------------------------------------------------------------------------------- /src/types/GodotDictionnary.ts: -------------------------------------------------------------------------------- 1 | export type GodotDictionnary = Record 2 | -------------------------------------------------------------------------------- /examples/udp/basic-dtls/server/.gitignore: -------------------------------------------------------------------------------- 1 | # Godot 4+ specific ignores 2 | .godot/ 3 | certs -------------------------------------------------------------------------------- /src/types/GodotInteger.ts: -------------------------------------------------------------------------------- 1 | import Long from 'long' 2 | 3 | export type GodotInteger = number | Long 4 | -------------------------------------------------------------------------------- /src/types/IGetReturn.ts: -------------------------------------------------------------------------------- 1 | export interface IGetReturn { 2 | value: T 3 | length: number 4 | } 5 | -------------------------------------------------------------------------------- /examples/certs_generator/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tilican/gd-com/HEAD/examples/certs_generator/icon.png -------------------------------------------------------------------------------- /examples/tcp/basic/client/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tilican/gd-com/HEAD/examples/tcp/basic/client/icon.png -------------------------------------------------------------------------------- /examples/udp/basic/client/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tilican/gd-com/HEAD/examples/udp/basic/client/icon.png -------------------------------------------------------------------------------- /examples/certs_generator/.gitignore: -------------------------------------------------------------------------------- 1 | # misc 2 | .idea 3 | .DS_Store 4 | 5 | # godot 6 | .import 7 | .godot 8 | 9 | certs -------------------------------------------------------------------------------- /examples/tcp/advanced/client/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tilican/gd-com/HEAD/examples/tcp/advanced/client/icon.png -------------------------------------------------------------------------------- /examples/tcp/basic-ssl/client/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tilican/gd-com/HEAD/examples/tcp/basic-ssl/client/icon.png -------------------------------------------------------------------------------- /examples/udp/advanced/client/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tilican/gd-com/HEAD/examples/udp/advanced/client/icon.png -------------------------------------------------------------------------------- /examples/udp/basic-dtls/client/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tilican/gd-com/HEAD/examples/udp/basic-dtls/client/icon.png -------------------------------------------------------------------------------- /examples/udp/basic-dtls/server/.gitattributes: -------------------------------------------------------------------------------- 1 | # Normalize EOL for all files that Git considers text files. 2 | * text=auto eol=lf 3 | -------------------------------------------------------------------------------- /examples/websocket/basic/client/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tilican/gd-com/HEAD/examples/websocket/basic/client/icon.png -------------------------------------------------------------------------------- /examples/websocket/advanced/client/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tilican/gd-com/HEAD/examples/websocket/advanced/client/icon.png -------------------------------------------------------------------------------- /examples/websocket/basic-ssl/client/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tilican/gd-com/HEAD/examples/websocket/basic-ssl/client/icon.png -------------------------------------------------------------------------------- /src/types/IDecoderList.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../constants' 2 | 3 | export type IDecoderList = Record 4 | -------------------------------------------------------------------------------- /src/types/IEncoderList.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../constants' 2 | 3 | export type IEncoderList = Record 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test/ 2 | examples/ 3 | .idea 4 | 5 | yarn.lock 6 | .gitignore 7 | CHANGELOG.md 8 | TODO.md 9 | CONTRIBUTING.md 10 | .nyc_output -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # misc 5 | .idea 6 | .DS_Store 7 | 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* -------------------------------------------------------------------------------- /examples/tcp/basic-ssl/server/README.md: -------------------------------------------------------------------------------- 1 | Don't forget to generate cert from certs_generator project :) 2 | 3 | After just copy paste folder certs to server and client -------------------------------------------------------------------------------- /examples/tcp/advanced/server/src/packets.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | I_WANT_TO_GO_LEFT: 1001, 3 | I_WANT_TO_GO_RIGHT: 1002, 4 | 5 | OK_GO_LEFT: 1003, 6 | OK_GO_RIGHT: 1004 7 | } -------------------------------------------------------------------------------- /examples/tcp/basic/server/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # misc 5 | .idea 6 | .DS_Store 7 | 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* -------------------------------------------------------------------------------- /examples/udp/advanced/server/src/packets.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | I_WANT_TO_GO_LEFT: 1001, 3 | I_WANT_TO_GO_RIGHT: 1002, 4 | 5 | OK_GO_LEFT: 1003, 6 | OK_GO_RIGHT: 1004 7 | } -------------------------------------------------------------------------------- /examples/udp/basic/server/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # misc 5 | .idea 6 | .DS_Store 7 | 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* -------------------------------------------------------------------------------- /examples/tcp/advanced/server/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # misc 5 | .idea 6 | .DS_Store 7 | 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* -------------------------------------------------------------------------------- /examples/udp/advanced/server/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # misc 5 | .idea 6 | .DS_Store 7 | 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* -------------------------------------------------------------------------------- /examples/websocket/basic/server/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # misc 5 | .idea 6 | .DS_Store 7 | 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './get' 2 | export * from './put' 3 | export { TYPE } from './constants' 4 | export * from './types' 5 | export { StreamTcp, prefixWithLength } from './utils' -------------------------------------------------------------------------------- /examples/websocket/advanced/server/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # misc 5 | .idea 6 | .DS_Store 7 | 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* -------------------------------------------------------------------------------- /examples/websocket/advanced/server/src/packets.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | I_WANT_TO_GO_LEFT: 1001, 3 | I_WANT_TO_GO_RIGHT: 1002, 4 | 5 | OK_GO_LEFT: 1003, 6 | OK_GO_RIGHT: 1004 7 | } -------------------------------------------------------------------------------- /examples/tcp/basic-ssl/server/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # misc 5 | .idea 6 | .DS_Store 7 | 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | 12 | certs -------------------------------------------------------------------------------- /examples/websocket/basic-ssl/server/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # misc 5 | .idea 6 | .DS_Store 7 | 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | 12 | certs -------------------------------------------------------------------------------- /examples/certs_generator/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="Sky" id=1] 4 | 5 | [resource] 6 | background_mode = 2 7 | background_sky = SubResource( 1 ) 8 | -------------------------------------------------------------------------------- /examples/tcp/basic/client/TCP.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://bl1p1gpok5eek"] 2 | 3 | [ext_resource type="Script" path="res://TCP.gd" id="1"] 4 | 5 | [node name="TCP" type="Node"] 6 | script = ExtResource("1") 7 | -------------------------------------------------------------------------------- /examples/udp/basic/client/UDP.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://cyxbddrvnjph3"] 2 | 3 | [ext_resource type="Script" path="res://UDP.gd" id="1"] 4 | 5 | [node name="UDP" type="Node"] 6 | script = ExtResource("1") 7 | -------------------------------------------------------------------------------- /examples/tcp/advanced/client/TCP.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://bcly1e6ba3ul3"] 2 | 3 | [ext_resource type="Script" path="res://TCP.gd" id="1"] 4 | 5 | [node name="TCP" type="Node"] 6 | script = ExtResource("1") 7 | -------------------------------------------------------------------------------- /examples/tcp/basic-ssl/client/TCP.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://dcigg8kljxgp3"] 2 | 3 | [ext_resource type="Script" path="res://TCP.gd" id="1"] 4 | 5 | [node name="TCP" type="Node"] 6 | script = ExtResource("1") 7 | -------------------------------------------------------------------------------- /examples/udp/advanced/client/UDP.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://d06epso6m7y8p"] 2 | 3 | [ext_resource type="Script" path="res://UDP.gd" id="1"] 4 | 5 | [node name="UDP" type="Node"] 6 | script = ExtResource("1") 7 | -------------------------------------------------------------------------------- /examples/udp/basic-dtls/client/UDP.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://cyxbddrvnjph3"] 2 | 3 | [ext_resource type="Script" path="res://UDP.gd" id="1"] 4 | 5 | [node name="UDP" type="Node"] 6 | script = ExtResource("1") 7 | -------------------------------------------------------------------------------- /examples/websocket/basic/client/WS.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://dswxqm7pacijb"] 2 | 3 | [ext_resource type="Script" path="res://WS.gd" id="1"] 4 | 5 | [node name="Main" type="Node"] 6 | script = ExtResource("1") 7 | -------------------------------------------------------------------------------- /examples/websocket/advanced/client/WS.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://cv2g0axyerrnd"] 2 | 3 | [ext_resource type="Script" path="res://WS.gd" id="1"] 4 | 5 | [node name="Main" type="Node"] 6 | script = ExtResource("1") 7 | -------------------------------------------------------------------------------- /examples/websocket/basic-ssl/client/WS.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://m7p1napjxihy"] 2 | 3 | [ext_resource type="Script" path="res://WS.gd" id="1"] 4 | 5 | [node name="Main" type="Node"] 6 | script = ExtResource("1") 7 | -------------------------------------------------------------------------------- /src/put/put_64.ts: -------------------------------------------------------------------------------- 1 | import Long from 'long' 2 | /** 3 | * Encode Int 64 4 | * @param value 5 | * @returns {Buffer} 6 | */ 7 | export function put64 (value: Long): Buffer { 8 | return Buffer.from(Long.fromValue(value).toBytesLE()) 9 | } 10 | -------------------------------------------------------------------------------- /examples/udp/basic-dtls/server/UDP_DTLS.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://bms13knri0aws"] 2 | 3 | [ext_resource type="Script" path="res://UDP_DTLS.gd" id="1_8wfti"] 4 | 5 | [node name="Node" type="Node"] 6 | script = ExtResource("1_8wfti") 7 | -------------------------------------------------------------------------------- /src/put/put_8.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Encode Int 8 3 | * @param value 4 | * @returns {Buffer} 5 | */ 6 | export function put8 (value: number): Buffer { 7 | const newBuffer = Buffer.allocUnsafe(1) 8 | newBuffer.writeInt8(value, 0) 9 | return newBuffer 10 | } 11 | -------------------------------------------------------------------------------- /src/put/put_u64.ts: -------------------------------------------------------------------------------- 1 | import Long from 'long' 2 | /** 3 | * Encode Unsigned Int 64 4 | * @param value 5 | * @returns {Buffer} 6 | */ 7 | export function putU64 (value: Long): Buffer { 8 | return Buffer.from(Long.fromValue(value, true).toBytesLE()) 9 | } 10 | -------------------------------------------------------------------------------- /src/put/put_16.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Encode Int 16 3 | * @param value 4 | * @returns {Buffer} 5 | */ 6 | export function put16 (value: number): Buffer { 7 | const newBuffer = Buffer.allocUnsafe(2) 8 | newBuffer.writeInt16LE(value, 0) 9 | return newBuffer 10 | } 11 | -------------------------------------------------------------------------------- /src/put/put_32.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Encode Int 32 3 | * @param value 4 | * @returns {Buffer} 5 | */ 6 | export function put32 (value: number): Buffer { 7 | const newBuffer = Buffer.allocUnsafe(4) 8 | newBuffer.writeInt32LE(value, 0) 9 | return newBuffer 10 | } 11 | -------------------------------------------------------------------------------- /src/put/put_float.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Encode Float 3 | * @param value 4 | * @returns {Buffer} 5 | */ 6 | export function putFloat (value: number): Buffer { 7 | const newBuffer = Buffer.allocUnsafe(4) 8 | newBuffer.writeFloatLE(value, 0) 9 | return newBuffer 10 | } 11 | -------------------------------------------------------------------------------- /src/put/put_u8.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Encode Unsigned Int 8 3 | * @param value 4 | * @returns {Buffer} 5 | */ 6 | export function putU8 (value: number): Buffer { 7 | const newBuffer = Buffer.allocUnsafe(1) 8 | newBuffer.writeUInt8(value, 0) 9 | return newBuffer 10 | } 11 | -------------------------------------------------------------------------------- /src/put/put_double.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Encode Double 3 | * @param value 4 | * @returns {Buffer} 5 | */ 6 | export function putDouble (value: number): Buffer { 7 | const newBuffer = Buffer.allocUnsafe(8) 8 | newBuffer.writeDoubleLE(value, 0) 9 | return newBuffer 10 | } 11 | -------------------------------------------------------------------------------- /src/put/put_u16.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Encode Unsigned Int 16 3 | * @param value 4 | * @returns {Buffer} 5 | */ 6 | export function putU16 (value: number): Buffer { 7 | const newBuffer = Buffer.allocUnsafe(2) 8 | newBuffer.writeUInt16LE(value, 0) 9 | return newBuffer 10 | } 11 | -------------------------------------------------------------------------------- /src/put/put_u32.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Encode Unsigned Int 32 3 | * @param value 4 | * @returns {Buffer} 5 | */ 6 | export function putU32 (value: number): Buffer { 7 | const newBuffer = Buffer.allocUnsafe(4) 8 | newBuffer.writeUInt32LE(value, 0) 9 | return newBuffer 10 | } 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "declaration": true, 6 | "outDir": "./dist", 7 | "esModuleInterop": true, 8 | "strictNullChecks": true, 9 | }, 10 | "include": [ 11 | "src/**/*" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /src/put/put_var/null.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | 3 | /** 4 | * Encode Null 5 | * @returns {Buffer} 6 | */ 7 | export function subPutVarNull(): Buffer { 8 | const buf = Buffer.alloc(4) 9 | buf.writeUInt32LE(TYPE.NULL, 0) 10 | return buf 11 | } 12 | 13 | export const putVarNull = (): Buffer => subPutVarNull() -------------------------------------------------------------------------------- /src/put/put_string.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Encode String 3 | * @param value 4 | * @returns {Buffer} 5 | */ 6 | export function putString (value: string): Buffer { 7 | const len = Buffer.byteLength(value) 8 | const newBuffer = Buffer.allocUnsafe(4 + len) 9 | 10 | newBuffer.writeUInt32LE(len, 0) 11 | newBuffer.write(value, 4) 12 | return newBuffer 13 | } 14 | -------------------------------------------------------------------------------- /src/get/get_var/null.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotNull} from "../../types"; 2 | 3 | /** 4 | * Decode null 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Null, length: Number}} 8 | */ 9 | export function getVarNull (genericDecoder, buf: Buffer): IGetReturn { 10 | return { 11 | value: null, 12 | length: 0 13 | } 14 | } -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | ## TODO 2 | * Encode all packets 3 | - Transform2D 4 | - Basis 5 | - Transform 6 | - NodePath 7 | - PoolByteArray 8 | - PoolIntArray 9 | - PoolRealArray 10 | - PoolStringArray 11 | - PoolVector2Array 12 | - PoolVector3Array 13 | - PoolColorArray 14 | * Manage endianness for buffer (os.endianness()) 15 | * Manage x64 & x86 16 | -------------------------------------------------------------------------------- /src/get/get_16.ts: -------------------------------------------------------------------------------- 1 | import { IGetReturn } from '../types' 2 | 3 | /** 4 | * Decode Int 16 5 | * @param buffer {Buffer} 6 | * @param offset {Number} 7 | * @returns {{value: Number, length: Number}} 8 | */ 9 | export function get16 (buffer: Buffer, offset: number = 0): IGetReturn { 10 | return { 11 | value: buffer.readInt16LE(offset), 12 | length: 2 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/get/get_32.ts: -------------------------------------------------------------------------------- 1 | import { IGetReturn } from '../types' 2 | 3 | /** 4 | * Decode Int 32 5 | * @param buffer {Buffer} 6 | * @param offset {Number} 7 | * @returns {{value: Number, length: Number}} 8 | */ 9 | export function get32 (buffer: Buffer, offset: number = 0): IGetReturn { 10 | return { 11 | value: buffer.readInt32LE(offset), 12 | length: 4 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/get/get_8.ts: -------------------------------------------------------------------------------- 1 | import { IGetReturn } from '../types' 2 | 3 | /** 4 | * Decode Int 8 5 | * @param {Buffer} buffer 6 | * @param {Number} offset 7 | * @returns {{value: Number, length: Number}} 8 | */ 9 | 10 | export function get8 (buffer: Buffer, offset: number = 0): IGetReturn { 11 | return { 12 | value: buffer.readInt8(offset), 13 | length: 1 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/get/get_u8.ts: -------------------------------------------------------------------------------- 1 | import { IGetReturn } from '../types' 2 | 3 | /** 4 | * Decode Unsigned Int 8 5 | * @param buffer {Buffer} 6 | * @param offset {Number} 7 | * @returns {{value: Number, length: Number}} 8 | */ 9 | export function getU8 (buffer: Buffer, offset: number = 0): IGetReturn { 10 | return { 11 | value: buffer.readUInt8(offset), 12 | length: 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/get/get_u16.ts: -------------------------------------------------------------------------------- 1 | import { IGetReturn } from '../types' 2 | 3 | /** 4 | * Decode Unsigned Int 16 5 | * @param buffer {Buffer} 6 | * @param offset {Number} 7 | * @returns {{value: Number, length: Number}} 8 | */ 9 | export function getU16 (buffer: Buffer, offset: number = 0): IGetReturn { 10 | return { 11 | value: buffer.readUInt16LE(offset), 12 | length: 2 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/get/get_u32.ts: -------------------------------------------------------------------------------- 1 | import { IGetReturn } from '../types' 2 | 3 | /** 4 | * Decode Unsigned Int 32 5 | * @param buffer {Buffer} 6 | * @param offset {Number} 7 | * @returns {{value: Number, length: Number}} 8 | */ 9 | export function getU32 (buffer: Buffer, offset: number = 0): IGetReturn { 10 | return { 11 | value: buffer.readUInt32LE(offset), 12 | length: 4 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/tcp/basic/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gd-com-tcp-basic", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node src/index.js" 9 | }, 10 | "author": "", 11 | "license": "MIT", 12 | "dependencies": { 13 | "@gd-com/utils": "^5.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/udp/basic/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gd-com-udp-basic", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node src/index.js" 9 | }, 10 | "author": "", 11 | "license": "MIT", 12 | "dependencies": { 13 | "@gd-com/utils": "^5.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/tcp/basic-ssl/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gd-com-tcp-basic-ssl", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node src/index.js" 9 | }, 10 | "author": "", 11 | "license": "MIT", 12 | "dependencies": { 13 | "@gd-com/utils": "^5.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/get/get_float.ts: -------------------------------------------------------------------------------- 1 | import { IGetReturn } from '../types' 2 | 3 | /** 4 | * Decode Float 5 | * @param buffer {Buffer} 6 | * @param offset {Number} 7 | * @returns {{value: Number, length: Number}} 8 | */ 9 | export function getFloat ( 10 | buffer: Buffer, 11 | offset: number = 0 12 | ): IGetReturn { 13 | return { 14 | value: buffer.readFloatLE(offset), 15 | length: 4 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/get/get_double.ts: -------------------------------------------------------------------------------- 1 | import { IGetReturn } from '../types' 2 | 3 | /** 4 | * Decode Double 5 | * @param buffer {Buffer} 6 | * @param offset {Number} 7 | * @returns {{value: Number, length: Number}} 8 | */ 9 | export function getDouble ( 10 | buffer: Buffer, 11 | offset: number = 0 12 | ): IGetReturn { 13 | return { 14 | value: buffer.readDoubleLE(offset), 15 | length: 8 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/get/get_var/bool.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotBoolean} from "../../types"; 2 | 3 | /** 4 | * Decode boolean 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Boolean, length: Number}} 8 | */ 9 | export function getVarBool (genericDecoder: Array, buf: Buffer): IGetReturn { 10 | return { 11 | value: buf.readUInt32LE(0) === 1, 12 | length: 4 13 | } 14 | } -------------------------------------------------------------------------------- /examples/tcp/advanced/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gd-com-tcp-advanced", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node src/index.js" 9 | }, 10 | "author": "", 11 | "license": "MIT", 12 | "dependencies": { 13 | "@gd-com/utils": "^5.0.0", 14 | "uuid": "^3.3.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/udp/advanced/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gd-com-udp-advanced", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node src/index.js" 9 | }, 10 | "author": "", 11 | "license": "MIT", 12 | "dependencies": { 13 | "@gd-com/utils": "^5.0.0", 14 | "uuid": "^3.3.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/websocket/advanced/server/src/process/i_want_to_go_left.js: -------------------------------------------------------------------------------- 1 | const { putU16 } = require('@gd-com/utils') 2 | const packets = require("../packets") 3 | 4 | module.exports = { 5 | packet: packets.I_WANT_TO_GO_LEFT, 6 | process: (uuid, ws, recieve) => { 7 | 8 | console.log(`[${uuid}] >> Send packet code`, packets.OK_GO_LEFT) 9 | 10 | let packet = putU16(packets.OK_GO_LEFT) 11 | 12 | ws.send(packet) 13 | } 14 | } -------------------------------------------------------------------------------- /examples/websocket/basic/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gd-com-websocket-basic", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node src/index.js" 9 | }, 10 | "author": "", 11 | "license": "MIT", 12 | "dependencies": { 13 | "@gd-com/utils": "^5.0.0", 14 | "ws": "^6.1.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/get/get_64.ts: -------------------------------------------------------------------------------- 1 | import Long from 'long' 2 | import { IGetReturn } from '../types' 3 | 4 | /** 5 | * Decode Int 64 6 | * @param buffer {Buffer} 7 | * @param offset {Number} 8 | * @returns {{value: Number, length: Number}} 9 | */ 10 | export function get64 (buffer: Buffer, offset: number = 0): IGetReturn { 11 | return { 12 | value: Long.fromBytesLE(buffer.slice(offset).toJSON().data), 13 | length: 8 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/websocket/basic-ssl/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gd-com-websocket-basic-ssl", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node src/index.js" 9 | }, 10 | "author": "", 11 | "license": "MIT", 12 | "dependencies": { 13 | "@gd-com/utils": "^5.0.0", 14 | "ws": "^8.9.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/get/get_u64.ts: -------------------------------------------------------------------------------- 1 | import Long from 'long' 2 | import { IGetReturn } from '../types' 3 | 4 | /** 5 | * Decode Unsigned Int 64 6 | * @param buffer {Buffer} 7 | * @param offset {Number} 8 | * @returns {{value: Number, length: Number}} 9 | */ 10 | export function getU64 (buffer: Buffer, offset: number = 0): IGetReturn { 11 | return { 12 | value: Long.fromBytesLE(buffer.slice(offset).toJSON().data, true), 13 | length: 8 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/put/put_var/bool.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | import { putU32 } from '../put_u32' 3 | 4 | /** 5 | * Encode Boolean 6 | * @param value 7 | * @returns {Buffer} 8 | */ 9 | function subPutVarBool (value: boolean): Buffer { 10 | const type = putU32(TYPE.BOOL) 11 | const data = putU32(value ? 1 : 0) 12 | return Buffer.concat([type, data]) 13 | } 14 | 15 | export const putVarBool = (prepare, value: boolean): Buffer => subPutVarBool(value) -------------------------------------------------------------------------------- /examples/websocket/advanced/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gd-com-websocket-advanced", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/old.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node src/index.js" 9 | }, 10 | "author": "", 11 | "license": "MIT", 12 | "dependencies": { 13 | "@gd-com/utils": "^5.0.0", 14 | "uuid": "^3.3.2", 15 | "ws": "^6.1.3" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/get/get_var/vector2.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotVector2} from "../../types"; 2 | 3 | /** 4 | * Decode Vector2 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Object, length: Number}} 8 | */ 9 | export function getVarVector2 (genericDecoder, buf: Buffer): IGetReturn { 10 | return { 11 | value: new GodotVector2( 12 | buf.readFloatLE(0), 13 | buf.readFloatLE(4) 14 | ), 15 | length: 8 16 | } 17 | } -------------------------------------------------------------------------------- /src/get/get_var/rawArray.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn} from "../../types"; 2 | 3 | /** 4 | * Decode RawArray 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Array, length: Number}} 8 | */ 9 | export function getVarRawArray (genericDecoder, buf: Buffer): IGetReturn { 10 | const bufLength = buf.readUInt32LE(0) 11 | 12 | return { 13 | value: buf.slice(4, bufLength + 4), 14 | length: bufLength + 4 + 4 // type + length 15 | } 16 | } -------------------------------------------------------------------------------- /src/types/GodotVector2.ts: -------------------------------------------------------------------------------- 1 | export class GodotVector2 { 2 | private _x: number 3 | private _y: number 4 | 5 | constructor (x: number, y: number) { 6 | this._x = x 7 | this._y = y 8 | } 9 | 10 | get x (): number { 11 | return this._x 12 | } 13 | 14 | set x (value: number) { 15 | this._x = value 16 | } 17 | 18 | get y (): number { 19 | return this._y 20 | } 21 | 22 | set y (value: number) { 23 | this._y = value 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/udp/advanced/server/src/process/i_want_to_go_left.js: -------------------------------------------------------------------------------- 1 | const { putU16 } = require('@gd-com/utils') 2 | const packets = require("../packets") 3 | 4 | module.exports = { 5 | packet: packets.I_WANT_TO_GO_LEFT, 6 | process: (client, server, remote, data) => { 7 | 8 | console.log(`[${client.uuid}] >> Send packet code`, packets.OK_GO_LEFT) 9 | 10 | let packet = putU16(packets.OK_GO_LEFT) 11 | 12 | server.send(packet, remote.port, remote.address) 13 | } 14 | } -------------------------------------------------------------------------------- /src/get/index.ts: -------------------------------------------------------------------------------- 1 | export { get8 } from './get_8' 2 | export { get16 } from './get_16' 3 | export { get32 } from './get_32' 4 | export { get64 } from './get_64' 5 | export { getU8 } from './get_u8' 6 | export { getU16 } from './get_u16' 7 | export { getU32 } from './get_u32' 8 | export { getU64 } from './get_u64' 9 | export { getString } from './get_string' 10 | export { getFloat } from './get_float' 11 | export { getDouble } from './get_double' 12 | export { getVar } from './get_var' 13 | -------------------------------------------------------------------------------- /src/put/index.ts: -------------------------------------------------------------------------------- 1 | export { put8 } from './put_8' 2 | export { put16 } from './put_16' 3 | export { put32 } from './put_32' 4 | export { put64 } from './put_64' 5 | export { putU8 } from './put_u8' 6 | export { putU16 } from './put_u16' 7 | export { putU32 } from './put_u32' 8 | export { putU64 } from './put_u64' 9 | export { putFloat } from './put_float' 10 | export { putDouble } from './put_double' 11 | export { putString } from './put_string' 12 | export { putVar } from './put_var' 13 | -------------------------------------------------------------------------------- /examples/udp/advanced/server/src/process/i_want_to_go_right.js: -------------------------------------------------------------------------------- 1 | const { putU16 } = require('@gd-com/utils') 2 | const packets = require("../packets") 3 | 4 | module.exports = { 5 | packet: packets.I_WANT_TO_GO_RIGHT, 6 | process: (client, server, remote, data) => { 7 | 8 | console.log(`[${client.uuid}] >> Send packet code`, packets.OK_GO_RIGHT) 9 | 10 | let packet = putU16(packets.OK_GO_RIGHT) 11 | 12 | server.send(packet, remote.port, remote.address) 13 | } 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/get/get_var/vector3.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotVector3} from "../../types"; 2 | 3 | /** 4 | * Decode Vector3 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Object, length: Number}} 8 | */ 9 | export function getVarVector3 (genericDecoder, buf: Buffer): IGetReturn { 10 | return { 11 | value: new GodotVector3( 12 | buf.readFloatLE(0), 13 | buf.readFloatLE(4), 14 | buf.readFloatLE(8) 15 | ), 16 | length: 12 17 | } 18 | } -------------------------------------------------------------------------------- /src/get/get_var/color.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotColor} from "../../types"; 2 | 3 | /** 4 | * Decode color 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Object, length: Number}} 8 | */ 9 | export function getVarColor (genericDecoder, buf: Buffer): IGetReturn { 10 | return { 11 | value: new GodotColor( 12 | buf.readFloatLE(0), 13 | buf.readFloatLE(4), 14 | buf.readFloatLE(8), 15 | buf.readFloatLE(12) 16 | ), 17 | length: 16 18 | } 19 | } -------------------------------------------------------------------------------- /src/get/get_var/plane.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotPlane} from "../../types"; 2 | 3 | /** 4 | * Decode Plane 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Object, length: Number}} 8 | */ 9 | export function getVarPlane (genericDecoder, buf: Buffer): IGetReturn { 10 | return { 11 | value: new GodotPlane( 12 | buf.readFloatLE(0), 13 | buf.readFloatLE(4), 14 | buf.readFloatLE(8), 15 | buf.readFloatLE(12) 16 | ), 17 | length: 16 18 | } 19 | } -------------------------------------------------------------------------------- /src/get/get_var/quat.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotQuat} from "../../types"; 2 | 3 | /** 4 | * Decode Quat 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Object, length: Number}} 8 | */ 9 | export function getVarQuat (genericDecoder, buf: Buffer): IGetReturn { 10 | return { 11 | value: new GodotQuat( 12 | buf.readFloatLE(0), 13 | buf.readFloatLE(4), 14 | buf.readFloatLE(8), 15 | buf.readFloatLE(12) 16 | ), 17 | length: 16 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/websocket/advanced/client/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="Sky" id=1] 4 | sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 ) 5 | sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 ) 6 | sky_curve = 0.25 7 | ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 ) 8 | ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 ) 9 | ground_curve = 0.01 10 | 11 | [resource] 12 | background_mode = 2 13 | background_sky = SubResource( 1 ) 14 | -------------------------------------------------------------------------------- /examples/websocket/basic/client/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="Sky" id=1] 4 | sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 ) 5 | sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 ) 6 | sky_curve = 0.25 7 | ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 ) 8 | ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 ) 9 | ground_curve = 0.01 10 | 11 | [resource] 12 | background_mode = 2 13 | background_sky = SubResource( 1 ) 14 | -------------------------------------------------------------------------------- /examples/websocket/basic-ssl/client/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="Sky" id=1] 4 | sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 ) 5 | sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 ) 6 | sky_curve = 0.25 7 | ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 ) 8 | ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 ) 9 | ground_curve = 0.01 10 | 11 | [resource] 12 | background_mode = 2 13 | background_sky = SubResource( 1 ) 14 | -------------------------------------------------------------------------------- /src/get/get_var/string.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotString} from "../../types"; 2 | 3 | /** 4 | * Decode String 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: String, length: Number}} 8 | */ 9 | export function getVarString (genericDecoder, buf: Buffer): IGetReturn { 10 | const len = buf.readUInt32LE(0) 11 | const pad = len % 4 === 0 ? 0 : 4 - (len % 4) 12 | 13 | return { 14 | value: buf.toString('utf8', 4, 4 + len).replace('\u0000', ''), 15 | length: 4 + len + pad 16 | } 17 | } -------------------------------------------------------------------------------- /examples/udp/basic-dtls/server/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | [application] 12 | 13 | config/name="udp-basic-dtls-server" 14 | run/main_scene="res://UDP_DTLS.tscn" 15 | config/features=PackedStringArray("4.0", "Forward Plus") 16 | config/icon="res://icon.svg" 17 | -------------------------------------------------------------------------------- /src/get/get_string.ts: -------------------------------------------------------------------------------- 1 | import { IGetReturn } from '../types' 2 | 3 | /** 4 | * Decode String 5 | * @param buffer {Buffer} 6 | * @param offset {Number} 7 | * @returns {{value: String, length: Number}} 8 | */ 9 | 10 | export function getString ( 11 | buffer: Buffer, 12 | offset: number = 0 13 | ): IGetReturn { 14 | const len = buffer.readUInt32LE(offset) 15 | 16 | return { 17 | value: buffer 18 | .toString('utf8', offset + 4, offset + 4 + len) 19 | .replace('\u0000', ''), 20 | length: 4 + len 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/get/get_var/rect2.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotRect2, GodotVector2} from "../../types"; 2 | 3 | /** 4 | * Decode Rect2 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Object, length: Number}} 8 | */ 9 | export function getVarRect2 (genericDecoder, buf: Buffer): IGetReturn { 10 | return { 11 | value: new GodotRect2( 12 | new GodotVector2(buf.readFloatLE(0), buf.readFloatLE(4)), 13 | new GodotVector2(buf.readFloatLE(8), buf.readFloatLE(12)), 14 | ), 15 | length: 16 16 | } 17 | } -------------------------------------------------------------------------------- /src/put/put_var/integer.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | import { putU16 } from '../put_u16' 3 | import { put32 } from '../put_32' 4 | 5 | /** 6 | * Encode Integer 7 | * @param value 8 | * @returns {Buffer} 9 | */ 10 | export function subputVarInt(value: number): Buffer { 11 | const type = putU16(TYPE.INTEGER) 12 | const flag = putU16(0) 13 | const data = put32(value) 14 | 15 | // TODO x64 16 | 17 | return Buffer.concat([type, flag, data]) 18 | } 19 | 20 | export const putVarInt = (prepare, value: number): Buffer => subputVarInt(value) -------------------------------------------------------------------------------- /examples/tcp/advanced/server/src/process/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | 4 | const files = fs.readdirSync(__dirname); 5 | 6 | module.exports = files.reduce((processors, filename) => { 7 | const filePath = path.join(__dirname, filename); 8 | const extname = path.extname(filePath); 9 | 10 | if (__filename !== filePath && fs.statSync(filePath).isFile() && /^\.js$/i.test(extname)) { 11 | let process = require(filePath); 12 | processors[process.packet] = process.process; 13 | } 14 | 15 | return processors; 16 | }, {}) -------------------------------------------------------------------------------- /examples/udp/advanced/server/src/process/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | 4 | const files = fs.readdirSync(__dirname); 5 | 6 | module.exports = files.reduce((processors, filename) => { 7 | const filePath = path.join(__dirname, filename); 8 | const extname = path.extname(filePath); 9 | 10 | if (__filename !== filePath && fs.statSync(filePath).isFile() && /^\.js$/i.test(extname)) { 11 | let process = require(filePath); 12 | processors[process.packet] = process.process; 13 | } 14 | 15 | return processors; 16 | }, {}) -------------------------------------------------------------------------------- /examples/websocket/advanced/server/src/process/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | 4 | const files = fs.readdirSync(__dirname); 5 | 6 | module.exports = files.reduce((processors, filename) => { 7 | const filePath = path.join(__dirname, filename); 8 | const extname = path.extname(filePath); 9 | 10 | if (__filename !== filePath && fs.statSync(filePath).isFile() && /^\.js$/i.test(extname)) { 11 | let process = require(filePath); 12 | processors[process.packet] = process.process; 13 | } 14 | 15 | return processors; 16 | }, {}) -------------------------------------------------------------------------------- /src/put/put_var/vector2.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | import { putU32 } from '../put_u32' 3 | import { putFloat } from '../put_float' 4 | import {GodotVector2} from "../../types"; 5 | 6 | /** 7 | * Encode Vector2 8 | * @param value 9 | * @returns {Buffer} 10 | */ 11 | function subPutVarVector2 (value: GodotVector2): Buffer { 12 | const type = putU32(TYPE.VECTOR2) 13 | const x = putFloat(value.x) 14 | const y = putFloat(value.y) 15 | return Buffer.concat([type, x, y]) 16 | } 17 | 18 | export const putVarVector2 = (prepare, value: GodotVector2): Buffer => subPutVarVector2(value) -------------------------------------------------------------------------------- /examples/tcp/advanced/server/src/StreamTcp.js: -------------------------------------------------------------------------------- 1 | const Transform = require('stream').Transform 2 | 3 | class StreamTcp extends Transform { 4 | _transform (chunk, enc, done) { 5 | let buffer = chunk 6 | while (buffer.length > 0) { 7 | const length = buffer.readUInt16LE(0) 8 | 9 | const bufferSplitted = buffer.slice(4, length + 4) // 4 cause the length bytes is in buffer 10 | buffer = buffer.slice(length + 4, buffer.length) // 4 cause the length bytes is in buffer 11 | 12 | this.push(bufferSplitted) 13 | } 14 | done() 15 | } 16 | } 17 | 18 | module.exports = StreamTcp -------------------------------------------------------------------------------- /examples/tcp/advanced/server/src/process/i_want_to_go_right.js: -------------------------------------------------------------------------------- 1 | const { putU16 } = require('@gd-com/utils') 2 | const packets = require("../packets") 3 | 4 | module.exports = { 5 | packet: packets.I_WANT_TO_GO_RIGHT, 6 | process: (uuid, socket, recieve) => { 7 | 8 | console.log(`[${uuid}] >> Send packet code`, packets.OK_GO_RIGHT) 9 | 10 | let packet = putU16(packets.OK_GO_RIGHT) 11 | 12 | const lengthBuffer = Buffer.alloc(4) 13 | lengthBuffer.writeUInt32LE(packet.length, 0) 14 | 15 | const toSend = Buffer.concat([lengthBuffer, packet]) 16 | 17 | socket.write(toSend) 18 | } 19 | } 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /examples/tcp/basic/client/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="Sky" id=1] 4 | radiance_size = 4 5 | sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 ) 6 | sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 ) 7 | sky_curve = 0.25 8 | ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 ) 9 | ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 ) 10 | ground_curve = 0.01 11 | sun_energy = 16.0 12 | 13 | [resource] 14 | background_mode = 2 15 | background_sky = SubResource( 1 ) 16 | fog_height_min = 0.0 17 | fog_height_max = 100.0 18 | ssao_quality = 0 19 | -------------------------------------------------------------------------------- /examples/udp/basic/client/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="Sky" id=1] 4 | radiance_size = 4 5 | sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 ) 6 | sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 ) 7 | sky_curve = 0.25 8 | ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 ) 9 | ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 ) 10 | ground_curve = 0.01 11 | sun_energy = 16.0 12 | 13 | [resource] 14 | background_mode = 2 15 | background_sky = SubResource( 1 ) 16 | fog_height_min = 0.0 17 | fog_height_max = 100.0 18 | ssao_quality = 0 19 | -------------------------------------------------------------------------------- /examples/tcp/advanced/client/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="Sky" id=1] 4 | radiance_size = 4 5 | sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 ) 6 | sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 ) 7 | sky_curve = 0.25 8 | ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 ) 9 | ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 ) 10 | ground_curve = 0.01 11 | sun_energy = 16.0 12 | 13 | [resource] 14 | background_mode = 2 15 | background_sky = SubResource( 1 ) 16 | fog_height_min = 0.0 17 | fog_height_max = 100.0 18 | ssao_quality = 0 19 | -------------------------------------------------------------------------------- /examples/tcp/basic-ssl/client/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="Sky" id=1] 4 | radiance_size = 4 5 | sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 ) 6 | sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 ) 7 | sky_curve = 0.25 8 | ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 ) 9 | ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 ) 10 | ground_curve = 0.01 11 | sun_energy = 16.0 12 | 13 | [resource] 14 | background_mode = 2 15 | background_sky = SubResource( 1 ) 16 | fog_height_min = 0.0 17 | fog_height_max = 100.0 18 | ssao_quality = 0 19 | -------------------------------------------------------------------------------- /examples/udp/advanced/client/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="Sky" id=1] 4 | radiance_size = 4 5 | sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 ) 6 | sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 ) 7 | sky_curve = 0.25 8 | ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 ) 9 | ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 ) 10 | ground_curve = 0.01 11 | sun_energy = 16.0 12 | 13 | [resource] 14 | background_mode = 2 15 | background_sky = SubResource( 1 ) 16 | fog_height_min = 0.0 17 | fog_height_max = 100.0 18 | ssao_quality = 0 19 | -------------------------------------------------------------------------------- /examples/udp/basic-dtls/client/default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="Sky" id=1] 4 | radiance_size = 4 5 | sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 ) 6 | sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 ) 7 | sky_curve = 0.25 8 | ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 ) 9 | ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 ) 10 | ground_curve = 0.01 11 | sun_energy = 16.0 12 | 13 | [resource] 14 | background_mode = 2 15 | background_sky = SubResource( 1 ) 16 | fog_height_min = 0.0 17 | fog_height_max = 100.0 18 | ssao_quality = 0 19 | -------------------------------------------------------------------------------- /src/put/put_var/quat.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | import { putU32 } from '../put_u32' 3 | import { putFloat } from '../put_float' 4 | import {GodotQuat} from "../../types"; 5 | 6 | /** 7 | * Encode Quat 8 | * @param value 9 | * @returns {Buffer} 10 | */ 11 | function subPutVarQuat (value: GodotQuat): Buffer { 12 | const type = putU32(TYPE.QUAT) 13 | const x = putFloat(value.x) 14 | const y = putFloat(value.y) 15 | const z = putFloat(value.z) 16 | const w = putFloat(value.w) 17 | return Buffer.concat([type, x, y, z, w]) 18 | } 19 | 20 | export const putVarQuat = (prepare, value: GodotQuat): Buffer => subPutVarQuat(value) -------------------------------------------------------------------------------- /src/put/put_var/vector3.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | import { putU32 } from '../put_u32' 3 | import { putFloat } from '../put_float' 4 | import {GodotVector3} from "../../types/GodotVector3"; 5 | 6 | /** 7 | * Encode Vector3 8 | * @param value 9 | * @returns {Buffer} 10 | */ 11 | function subPutVarVector3 (value: GodotVector3): Buffer { 12 | const type = putU32(TYPE.VECTOR3) 13 | const x = putFloat(value.x) 14 | const y = putFloat(value.y) 15 | const z = putFloat(value.z) 16 | return Buffer.concat([type, x, y, z]) 17 | } 18 | 19 | export const putVarVector3 = (prepare, value: GodotVector3): Buffer => subPutVarVector3(value) -------------------------------------------------------------------------------- /src/put/put_var/color.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | import { putU32 } from '../put_u32' 3 | import { putFloat } from '../put_float' 4 | import {GodotColor} from "../../types"; 5 | 6 | /** 7 | * Encode Color 8 | * @param value 9 | * @returns {Buffer} 10 | */ 11 | function subPutVarColor (value: GodotColor): Buffer { 12 | const type = putU32(TYPE.COLOR) 13 | const r = putFloat(value.r) 14 | const g = putFloat(value.g) 15 | const b = putFloat(value.b) 16 | const a = putFloat(value.a) 17 | return Buffer.concat([type, r, g, b, a]) 18 | } 19 | 20 | export const putVarColor = (prepare, value: GodotColor): Buffer => subPutVarColor(value) -------------------------------------------------------------------------------- /src/types/GodotAabb.ts: -------------------------------------------------------------------------------- 1 | import { GodotVector3 } from './GodotVector3' 2 | 3 | export class GodotAabb { 4 | private _coordinate: GodotVector3 5 | private _size: GodotVector3 6 | 7 | constructor (coordinate: GodotVector3, size: GodotVector3) { 8 | this._coordinate = coordinate 9 | this._size = size 10 | } 11 | 12 | get coordinate (): GodotVector3 { 13 | return this._coordinate 14 | } 15 | 16 | set coordinate (value: GodotVector3) { 17 | this._coordinate = value 18 | } 19 | 20 | get size (): GodotVector3 { 21 | return this._size 22 | } 23 | 24 | set size (value: GodotVector3) { 25 | this._size = value 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/types/GodotRect2.ts: -------------------------------------------------------------------------------- 1 | import { GodotVector2 } from './GodotVector2' 2 | 3 | export class GodotRect2 { 4 | private _coordinate: GodotVector2 5 | private _size: GodotVector2 6 | 7 | constructor (coordinate: GodotVector2, size: GodotVector2) { 8 | this._coordinate = coordinate 9 | this._size = size 10 | } 11 | 12 | get coordinate (): GodotVector2 { 13 | return this._coordinate 14 | } 15 | 16 | set coordinate (value: GodotVector2) { 17 | this._coordinate = value 18 | } 19 | 20 | get size (): GodotVector2 { 21 | return this._size 22 | } 23 | 24 | set size (value: GodotVector2) { 25 | this._size = value 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/types/GodotVector3.ts: -------------------------------------------------------------------------------- 1 | export class GodotVector3 { 2 | private _x: number 3 | private _y: number 4 | private _z: number 5 | 6 | constructor (x: number, y: number, z: number) { 7 | this._x = x 8 | this._y = y 9 | this._z = z 10 | } 11 | 12 | get x (): number { 13 | return this._x 14 | } 15 | 16 | set x (value: number) { 17 | this._x = value 18 | } 19 | 20 | get y (): number { 21 | return this._y 22 | } 23 | 24 | set y (value: number) { 25 | this._y = value 26 | } 27 | 28 | get z (): number { 29 | return this._z 30 | } 31 | 32 | set z (value: number) { 33 | this._z = value 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /examples/tcp/basic/client/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | _global_script_classes=[] 12 | _global_script_class_icons={} 13 | 14 | [application] 15 | 16 | config/name="gd-com-tcp-basic" 17 | run/main_scene="res://TCP.tscn" 18 | config/features=PackedStringArray("4.0") 19 | config/icon="res://icon.png" 20 | 21 | [rendering] 22 | 23 | environment/default_environment="res://default_env.tres" 24 | -------------------------------------------------------------------------------- /examples/udp/basic/client/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | _global_script_classes=[] 12 | _global_script_class_icons={} 13 | 14 | [application] 15 | 16 | config/name="gd-com-udp-basic" 17 | run/main_scene="res://UDP.tscn" 18 | config/features=PackedStringArray("4.0") 19 | config/icon="res://icon.png" 20 | 21 | [rendering] 22 | 23 | environment/default_environment="res://default_env.tres" 24 | -------------------------------------------------------------------------------- /examples/udp/basic/server/src/index.js: -------------------------------------------------------------------------------- 1 | const dgram = require('dgram') 2 | const { putVar, getVar } = require('@gd-com/utils') 3 | 4 | const server = dgram.createSocket('udp4') 5 | 6 | server.on('listening', () => { 7 | let address = server.address() 8 | console.log(`UDP Server listening on ${address.address}:${address.port}`) 9 | }) 10 | 11 | server.on('message', (buf, remote) => { 12 | let buffer = new Buffer.from(buf) 13 | 14 | const recieve = getVar(buffer) 15 | console.log('Recieve ' , recieve.value) 16 | 17 | let send = putVar(Math.random()) 18 | 19 | server.send(send, remote.port, remote.host) 20 | }) 21 | 22 | server.bind(9091, '127.0.0.1') 23 | -------------------------------------------------------------------------------- /examples/tcp/advanced/client/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | _global_script_classes=[] 12 | _global_script_class_icons={} 13 | 14 | [application] 15 | 16 | config/name="gd-com-tcp-advanced" 17 | run/main_scene="res://TCP.tscn" 18 | config/features=PackedStringArray("4.0") 19 | config/icon="res://icon.png" 20 | 21 | [rendering] 22 | 23 | environment/default_environment="res://default_env.tres" 24 | -------------------------------------------------------------------------------- /examples/udp/advanced/client/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | _global_script_classes=[] 12 | _global_script_class_icons={} 13 | 14 | [application] 15 | 16 | config/name="gd-com-udp-advanced" 17 | run/main_scene="res://UDP.tscn" 18 | config/features=PackedStringArray("4.0") 19 | config/icon="res://icon.png" 20 | 21 | [rendering] 22 | 23 | environment/default_environment="res://default_env.tres" 24 | -------------------------------------------------------------------------------- /examples/udp/basic/client/UDP.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | var connection = PacketPeerUDP.new() 4 | var test = null 5 | var values = [ 6 | true,false, 7 | 1, -1, 500, -500, 8 | 1.2, -1.2, 50.1, -50.1, 80.852078542, 9 | "test1", "test2", "test3" 10 | ] 11 | 12 | func _ready(): 13 | print("Start client UDP") 14 | # Connect 15 | connection.connect_to_host("127.0.0.1", 9091) 16 | connection.put_var(null) 17 | 18 | func _process(_delta): 19 | if connection.is_socket_connected(): 20 | if connection.get_available_packet_count() > 0 : 21 | test = connection.get_var() 22 | print(test) 23 | 24 | if values.size() > 0 : 25 | connection.put_var(values.pop_front()) 26 | -------------------------------------------------------------------------------- /examples/tcp/basic-ssl/client/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | _global_script_classes=[] 12 | _global_script_class_icons={} 13 | 14 | [application] 15 | 16 | config/name="gd-com-tcp-basic-ssl" 17 | run/main_scene="res://TCP.tscn" 18 | config/features=PackedStringArray("4.0") 19 | config/icon="res://icon.png" 20 | 21 | [rendering] 22 | 23 | environment/default_environment="res://default_env.tres" 24 | -------------------------------------------------------------------------------- /examples/udp/basic-dtls/client/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | _global_script_classes=[] 12 | _global_script_class_icons={} 13 | 14 | [application] 15 | 16 | config/name="gd-com-udp-basic-dtls" 17 | run/main_scene="res://UDP.tscn" 18 | config/features=PackedStringArray("4.0") 19 | config/icon="res://icon.png" 20 | 21 | [rendering] 22 | 23 | environment/default_environment="res://default_env.tres" 24 | -------------------------------------------------------------------------------- /examples/websocket/basic/client/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | _global_script_classes=[] 12 | _global_script_class_icons={} 13 | 14 | [application] 15 | 16 | config/name="gd-com-websocket-basic" 17 | run/main_scene="res://WS.tscn" 18 | config/features=PackedStringArray("4.0") 19 | config/icon="res://icon.png" 20 | 21 | [rendering] 22 | 23 | environment/default_environment="res://default_env.tres" 24 | -------------------------------------------------------------------------------- /src/put/put_var/plane.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | import { putU32 } from '../put_u32' 3 | import { putFloat } from '../put_float' 4 | import {GodotPlane} from "../../types"; 5 | 6 | /** 7 | * Encode Plane 8 | * @param value 9 | * @returns {Buffer} 10 | */ 11 | function subPutVarPlane (value: GodotPlane): Buffer { 12 | const type = putU32(TYPE.PLANE) 13 | const x = putFloat(value.x) 14 | const y = putFloat(value.y) 15 | const z = putFloat(value.z) 16 | const distance = putFloat(value.distance) 17 | return Buffer.concat([type, x, y, z, distance]) 18 | } 19 | 20 | export const putVarPlane = (prepare, value: GodotPlane): Buffer => subPutVarPlane(value) -------------------------------------------------------------------------------- /examples/websocket/advanced/client/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | _global_script_classes=[] 12 | _global_script_class_icons={} 13 | 14 | [application] 15 | 16 | config/name="gd-com-websocket-advanced" 17 | run/main_scene="res://WS.tscn" 18 | config/features=PackedStringArray("4.0") 19 | config/icon="res://icon.png" 20 | 21 | [rendering] 22 | 23 | environment/default_environment="res://default_env.tres" 24 | -------------------------------------------------------------------------------- /src/get/get_var/aabb.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotAabb, GodotVector3} from "../../types"; 2 | 3 | /** 4 | * Decode AABB 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: AABB, length: Number}} 8 | */ 9 | export function getVarAABB (genericDecoder, buf: Buffer): IGetReturn { 10 | return { 11 | value: new GodotAabb( 12 | new GodotVector3( 13 | buf.readFloatLE(0), 14 | buf.readFloatLE(4), 15 | buf.readFloatLE(8), 16 | ), 17 | new GodotVector3( 18 | buf.readFloatLE(12), 19 | buf.readFloatLE(16), 20 | buf.readFloatLE(20) 21 | ), 22 | ), 23 | length: 24 24 | } 25 | } -------------------------------------------------------------------------------- /src/get/get_var/integer.ts: -------------------------------------------------------------------------------- 1 | import Long from 'long' 2 | import {IGetReturn, GodotInteger} from "../../types"; 3 | 4 | /** 5 | * Decode integer 6 | * @param genericDecoder 7 | * @param buf {Buffer} 8 | * @param flag 9 | * @returns {{value: Number, length: Number}} 10 | */ 11 | 12 | export function getVarInteger (genericDecoder, buf, flag = 0): IGetReturn { 13 | let result: IGetReturn; 14 | if (flag === 1) { 15 | result = { 16 | value: Long.fromBytesLE(buf.slice(0)), 17 | length: 8 18 | } 19 | } else { 20 | result = { 21 | value: buf.readInt32LE(0), 22 | length: 4 23 | } 24 | } 25 | 26 | return result 27 | } -------------------------------------------------------------------------------- /examples/websocket/basic-ssl/client/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | _global_script_classes=[] 12 | _global_script_class_icons={} 13 | 14 | [application] 15 | 16 | config/name="gd-com-websocket-basic-ssl" 17 | run/main_scene="res://WS.tscn" 18 | config/features=PackedStringArray("4.0") 19 | config/icon="res://icon.png" 20 | 21 | [rendering] 22 | 23 | environment/default_environment="res://default_env.tres" 24 | -------------------------------------------------------------------------------- /examples/websocket/basic-ssl/server/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Generate certificate 3 | 4 | openssl genrsa -out server-key.pem 4096 5 | openssl req -new -key server-key.pem -out server-csr.pem 6 | openssl x509 -req -in server-csr.pem -signkey server-key.pem -out server-cert.pem 7 | 8 | ## Chrome testing 9 | 10 | go to chrome://flags/#allow-insecure-localhost and enable allow-insecure-localhost 11 | 12 | /!\ Don't forget to disabled it after !!!!!! 13 | 14 | ## Test Websocket 15 | 16 | Go to https://websocketking.com/ enter wss://localhost:9090 en hit connect you should see 17 | 18 | - Connected to wss://localhost:9090 19 | - Connecting to wss://localhost:9090 20 | 21 | ## Now you can launch Godot example :) -------------------------------------------------------------------------------- /examples/tcp/basic/server/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@gd-com/utils@^5.0.0": 6 | version "5.0.0" 7 | resolved "https://registry.yarnpkg.com/@gd-com/utils/-/utils-5.0.0.tgz#510de74fdf634648d933ffaa2b925968b4511d3a" 8 | integrity sha512-gddq0BoZVtL/IfldtPxk5HH0n6PAPNG9W0FGKIh/u4V1jo8SJpsynAiE1xOQn5PoZ8Bljr/stnO+zkg1DY3aVw== 9 | dependencies: 10 | long "^5.2.0" 11 | 12 | long@^5.2.0: 13 | version "5.2.1" 14 | resolved "https://registry.yarnpkg.com/long/-/long-5.2.1.tgz#e27595d0083d103d2fa2c20c7699f8e0c92b897f" 15 | integrity sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A== 16 | -------------------------------------------------------------------------------- /examples/udp/basic/server/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@gd-com/utils@^5.0.0": 6 | version "5.0.0" 7 | resolved "https://registry.yarnpkg.com/@gd-com/utils/-/utils-5.0.0.tgz#510de74fdf634648d933ffaa2b925968b4511d3a" 8 | integrity sha512-gddq0BoZVtL/IfldtPxk5HH0n6PAPNG9W0FGKIh/u4V1jo8SJpsynAiE1xOQn5PoZ8Bljr/stnO+zkg1DY3aVw== 9 | dependencies: 10 | long "^5.2.0" 11 | 12 | long@^5.2.0: 13 | version "5.2.1" 14 | resolved "https://registry.yarnpkg.com/long/-/long-5.2.1.tgz#e27595d0083d103d2fa2c20c7699f8e0c92b897f" 15 | integrity sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A== 16 | -------------------------------------------------------------------------------- /examples/tcp/basic-ssl/server/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@gd-com/utils@^5.0.0": 6 | version "5.0.0" 7 | resolved "https://registry.yarnpkg.com/@gd-com/utils/-/utils-5.0.0.tgz#510de74fdf634648d933ffaa2b925968b4511d3a" 8 | integrity sha512-gddq0BoZVtL/IfldtPxk5HH0n6PAPNG9W0FGKIh/u4V1jo8SJpsynAiE1xOQn5PoZ8Bljr/stnO+zkg1DY3aVw== 9 | dependencies: 10 | long "^5.2.0" 11 | 12 | long@^5.2.0: 13 | version "5.2.1" 14 | resolved "https://registry.yarnpkg.com/long/-/long-5.2.1.tgz#e27595d0083d103d2fa2c20c7699f8e0c92b897f" 15 | integrity sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A== 16 | -------------------------------------------------------------------------------- /src/put/put_var/rect2.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | import { putU32 } from '../put_u32' 3 | import { putFloat } from '../put_float' 4 | import {GodotRect2} from "../../types"; 5 | 6 | /** 7 | * Encode Rect2 8 | * @param value 9 | * @returns {Buffer} 10 | */ 11 | function subPutVarRect2 (value: GodotRect2): Buffer { 12 | const type = putU32(TYPE.RECT2) 13 | const coordinateX = putFloat(value.coordinate.x) 14 | const coordinateY = putFloat(value.coordinate.y) 15 | const sizeX = putFloat(value.size.x) 16 | const sizeY = putFloat(value.size.y) 17 | return Buffer.concat([type, coordinateX, coordinateY, sizeX, sizeY]) 18 | } 19 | 20 | export const putVarRect2 = (prepare, value: GodotRect2): Buffer => subPutVarRect2(value) -------------------------------------------------------------------------------- /src/get/get_var/basis.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotBasis, GodotVector3} from "../../types"; 2 | 3 | /** 4 | * Decode BASIS 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Object, length: Number}} 8 | */ 9 | export function getVarBasis (genericDecoder, buf: Buffer): IGetReturn { 10 | 11 | const vector3x = new GodotVector3(buf.readFloatLE(0), buf.readFloatLE(4), buf.readFloatLE(8)); 12 | const vector3y = new GodotVector3(buf.readFloatLE(12), buf.readFloatLE(16), buf.readFloatLE(20)); 13 | const vector3z = new GodotVector3(buf.readFloatLE(24), buf.readFloatLE(28), buf.readFloatLE(32)); 14 | 15 | return { 16 | value: new GodotBasis(vector3x, vector3y, vector3z), 17 | length: 36 18 | } 19 | } -------------------------------------------------------------------------------- /src/get/get_var/float.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotFloat} from "../../types"; 2 | 3 | /** 4 | * Decode float 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @param flag 8 | * @returns {{value: Number, length: Number}} 9 | */ 10 | export function getVarFloat (genericDecoder, buf, flag): IGetReturn { 11 | let result: IGetReturn; 12 | // always encode real as double cf : marshalls.cpp L842 13 | // but sometimes can be float if double is not necessary 14 | if (flag === 1) { 15 | result = { 16 | value: buf.readDoubleLE(0), 17 | length: 8 18 | } 19 | } else { 20 | result = { 21 | value: buf.readFloatLE(0), 22 | length: 4 23 | } 24 | } 25 | return result 26 | } 27 | -------------------------------------------------------------------------------- /examples/websocket/advanced/server/src/process/i_want_to_go_right.js: -------------------------------------------------------------------------------- 1 | const { getString, putString, putU16 } = require('@gd-com/utils') 2 | const packets = require("../packets") 3 | 4 | module.exports = { 5 | packet: packets.I_WANT_TO_GO_RIGHT, 6 | process: (uuid, ws, recieve) => { 7 | let data = Buffer.from(recieve) 8 | let extra = getString(data) 9 | 10 | console.log(`With I_WANT_TO_GO_RIGHT packet i recieve : "${extra.value}"`) 11 | 12 | console.log(`[${uuid}] >> Send packet code`, packets.OK_GO_RIGHT) 13 | 14 | let packetId = putU16(packets.OK_GO_RIGHT) 15 | let packetData = putString('thanks !') 16 | 17 | let packet = Buffer.concat([packetId, packetData]) 18 | 19 | ws.send(packet) 20 | } 21 | } 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/get/get_var/transform2d.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotTransform2D, GodotVector2} from "../../types"; 2 | 3 | /** 4 | * Decode Transform2d 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Object, length: Number}} 8 | */ 9 | export function getVarTransform2d (genericDecoder, buf: Buffer): IGetReturn { 10 | return { 11 | value: new GodotTransform2D( 12 | new GodotVector2( 13 | buf.readFloatLE(0), 14 | buf.readFloatLE(4) 15 | ), 16 | new GodotVector2( 17 | buf.readFloatLE(8), 18 | buf.readFloatLE(12) 19 | ), 20 | new GodotVector2( 21 | buf.readFloatLE(16), 22 | buf.readFloatLE(20) 23 | ), 24 | ), 25 | length: 24 26 | } 27 | } -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | // take a look = http=//docs.godotengine.org/en/latest/tutorials/misc/binary_serialization_api.html 2 | 3 | export enum TYPE { 4 | NULL= 0, 5 | BOOL= 1, 6 | INTEGER= 2, 7 | FLOAT= 3, 8 | STRING= 4, 9 | VECTOR2= 5, 10 | RECT2= 6, 11 | VECTOR3= 7, 12 | TRANSFORM2D= 8, 13 | PLANE= 9, 14 | QUAT= 10, 15 | AABB= 11, 16 | BASIS= 12, 17 | TRANSFORM= 13, 18 | COLOR= 14, 19 | NODE_PATH= 15, 20 | RID= 16, // unsupported 21 | OBJECT= 17, // unsupported 22 | DICTIONARY= 18, 23 | ARRAY= 19, 24 | RAW_ARRAY= 20, 25 | INT_32_ARRAY= 21, 26 | INT_64_ARRAY= 22, 27 | FLOAT_32_ARRAY= 23, 28 | FLOAT_64_ARRAY= 24, 29 | STRING_ARRAY= 25, 30 | VECTOR2_ARRAY= 26, 31 | VECTOR3_ARRAY= 27, 32 | COLOR_ARRAY= 28, 33 | // MAX= 29 34 | } 35 | -------------------------------------------------------------------------------- /src/types/GodotBasis.ts: -------------------------------------------------------------------------------- 1 | import { GodotVector3 } from './GodotVector3' 2 | 3 | export class GodotBasis { 4 | private _x: GodotVector3 5 | private _y: GodotVector3 6 | private _z: GodotVector3 7 | 8 | constructor (x: GodotVector3, y: GodotVector3, z: GodotVector3) { 9 | this._x = x 10 | this._y = y 11 | this._z = z 12 | } 13 | 14 | get x (): GodotVector3 { 15 | return this._x 16 | } 17 | 18 | set x (value: GodotVector3) { 19 | this._x = value 20 | } 21 | 22 | get y (): GodotVector3 { 23 | return this._y 24 | } 25 | 26 | set y (value: GodotVector3) { 27 | this._y = value 28 | } 29 | 30 | get z (): GodotVector3 { 31 | return this._z 32 | } 33 | 34 | set z (value: GodotVector3) { 35 | this._z = value 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/tcp/advanced/server/src/process/i_want_to_go_left.js: -------------------------------------------------------------------------------- 1 | const { putU16, getU16, getString } = require('@gd-com/utils') 2 | const packets = require("../packets") 3 | 4 | module.exports = { 5 | packet: packets.I_WANT_TO_GO_LEFT, 6 | process: (uuid, socket, recieve) => { 7 | console.log(`[${uuid}] >> Send packet code`, packets.OK_GO_LEFT) 8 | 9 | // we know we got a string in recieve ! 10 | const recievedString = getString(recieve) 11 | 12 | console.log(`we recieve : ${recievedString.value}`) 13 | 14 | let packet = putU16(packets.OK_GO_LEFT) 15 | 16 | const lengthBuffer = Buffer.alloc(4) 17 | lengthBuffer.writeUInt32LE(packet.length, 0) 18 | 19 | const toSend = Buffer.concat([lengthBuffer, packet]) 20 | 21 | socket.write(toSend) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/websocket/basic/server/src/index.js: -------------------------------------------------------------------------------- 1 | const WebSocket = require('ws') 2 | const gdCom = require('@gd-com/utils') 3 | 4 | const wss = new WebSocket.Server({ port: 8080 }) 5 | 6 | wss.on('connection', ws => { 7 | console.log('connected') 8 | ws.on('message', (data) => { 9 | const packetWithLength = new Buffer.from(data) 10 | const length = packetWithLength.readUInt16LE(0) 11 | 12 | const packet = packetWithLength.slice(4, length + 4) 13 | 14 | const decoded = gdCom.getVar(packet) 15 | console.log('receive :', decoded.value) 16 | 17 | // we need to put the packet length on top cause it's tcp 18 | const packetToSend = gdCom.prefixWithLength(gdCom.putVar(Math.random())) 19 | 20 | console.log('send :', packetToSend) 21 | ws.send(packetToSend) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules/ 28 | 29 | # Remove some common IDE working directories 30 | .idea 31 | .vscode 32 | 33 | # coverage test 34 | .nyc_output/* 35 | 36 | # docs generated 37 | docs/* 38 | dist/* -------------------------------------------------------------------------------- /src/types/GodotTransform2D.ts: -------------------------------------------------------------------------------- 1 | import { GodotVector2 } from './GodotVector2' 2 | 3 | export class GodotTransform2D { 4 | private _x: GodotVector2 5 | private _y: GodotVector2 6 | private _origin: GodotVector2 7 | 8 | constructor (x: GodotVector2, y: GodotVector2, origin: GodotVector2) { 9 | this._x = x 10 | this._y = y 11 | this._origin = origin 12 | } 13 | 14 | get x (): GodotVector2 { 15 | return this._x 16 | } 17 | 18 | set x (value: GodotVector2) { 19 | this._x = value 20 | } 21 | 22 | get y (): GodotVector2 { 23 | return this._y 24 | } 25 | 26 | set y (value: GodotVector2) { 27 | this._y = value 28 | } 29 | 30 | get origin (): GodotVector2 { 31 | return this._origin 32 | } 33 | 34 | set origin (value: GodotVector2) { 35 | this._origin = value 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/types/GodotQuat.ts: -------------------------------------------------------------------------------- 1 | export class GodotQuat { 2 | private _x: number 3 | private _y: number 4 | private _z: number 5 | private _w: number 6 | 7 | constructor (x: number, y: number, z: number, w: number) { 8 | this._x = x 9 | this._y = y 10 | this._z = z 11 | this._w = w 12 | } 13 | 14 | get x (): number { 15 | return this._x 16 | } 17 | 18 | set x (value: number) { 19 | this._x = value 20 | } 21 | 22 | get y (): number { 23 | return this._y 24 | } 25 | 26 | set y (value: number) { 27 | this._y = value 28 | } 29 | 30 | get z (): number { 31 | return this._z 32 | } 33 | 34 | set z (value: number) { 35 | this._z = value 36 | } 37 | 38 | get w (): number { 39 | return this._w 40 | } 41 | 42 | set w (value: number) { 43 | this._w = value 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /examples/certs_generator/project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=5 10 | 11 | [application] 12 | 13 | config/name="certs-generator" 14 | run/main_scene="res://ROOT.tscn" 15 | config/features=PackedStringArray("4.0") 16 | config/icon="res://icon.png" 17 | 18 | [display] 19 | 20 | window/size/resizable=false 21 | window/size/width=400 22 | window/size/height=300 23 | 24 | [gui] 25 | 26 | common/drop_mouse_on_gui_input_disabled=true 27 | 28 | [physics] 29 | 30 | common/enable_pause_aware_picking=true 31 | 32 | [rendering] 33 | 34 | environment/default_environment="res://default_env.tres" 35 | -------------------------------------------------------------------------------- /src/types/GodotColor.ts: -------------------------------------------------------------------------------- 1 | export class GodotColor { 2 | private _r: number 3 | private _g: number 4 | private _b: number 5 | private _a: number 6 | 7 | constructor (r: number, g: number, b: number, a: number = 1) { 8 | this._r = r 9 | this._g = g 10 | this._b = b 11 | this._a = a 12 | } 13 | 14 | get r (): number { 15 | return this._r 16 | } 17 | 18 | set r (value: number) { 19 | this._r = value 20 | } 21 | 22 | get g (): number { 23 | return this._g 24 | } 25 | 26 | set g (value: number) { 27 | this._g = value 28 | } 29 | 30 | get b (): number { 31 | return this._b 32 | } 33 | 34 | set b (value: number) { 35 | this._b = value 36 | } 37 | 38 | get a (): number { 39 | return this._a 40 | } 41 | 42 | set a (value: number) { 43 | this._a = value 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/put/put_var/aabb.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | import { putU32 } from '../put_u32' 3 | import { putFloat } from '../put_float' 4 | import { GodotAabb } from "../../types"; 5 | 6 | /** 7 | * Encode Vector3 8 | * @param value 9 | * @returns {Buffer} 10 | */ 11 | function subPutVarAABB(value: GodotAabb): Buffer { 12 | const type = putU32(TYPE.AABB) 13 | const xCoordinate = putFloat(value.coordinate.x) 14 | const yCoordinate = putFloat(value.coordinate.y) 15 | const zCoordinate = putFloat(value.coordinate.z) 16 | const xSize = putFloat(value.size.x) 17 | const ySize = putFloat(value.size.y) 18 | const zSize = putFloat(value.size.z) 19 | return Buffer.concat([type, xCoordinate, yCoordinate, zCoordinate, xSize, ySize, zSize]) 20 | } 21 | 22 | export const putVarAABB = (prepare, value: GodotAabb): Buffer => subPutVarAABB(value) 23 | -------------------------------------------------------------------------------- /examples/certs_generator/ROOT.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | var O = "GD-COM" 4 | var C = "FR" 5 | 6 | func _ready(): 7 | if not DirAccess.dir_exists_absolute("res://certs"): 8 | DirAccess.make_dir_absolute("res://certs") 9 | 10 | func GenerateX509(name: String): 11 | var X509_cert_filename = name + ".crt" 12 | var X509_key_filename = name + ".key" 13 | var X509_cert_path = "res://certs/" + X509_cert_filename 14 | var X509_key_path = "res://certs/" + X509_key_filename 15 | 16 | var CNOC = "CN=" + $Panel/LineEditCN.text + ",O=" + O + ",C=" + C 17 | print(CNOC) 18 | var crypto = Crypto.new() 19 | var crypto_key = crypto.generate_rsa(4096) 20 | var X509_cert = crypto.generate_self_signed_certificate(crypto_key,CNOC) 21 | X509_cert.save(X509_cert_path) 22 | crypto_key.save(X509_key_path) 23 | 24 | 25 | func _on_Button_pressed(): 26 | GenerateX509($Panel/LineEdit.text) 27 | -------------------------------------------------------------------------------- /src/types/GodotPlane.ts: -------------------------------------------------------------------------------- 1 | export class GodotPlane { 2 | private _x: number 3 | private _y: number 4 | private _z: number 5 | private _distance: number 6 | 7 | constructor (x: number, y: number, z: number, distance: number) { 8 | this._x = x 9 | this._y = y 10 | this._z = z 11 | this._distance = distance 12 | } 13 | 14 | get x (): number { 15 | return this._x 16 | } 17 | 18 | set x (value: number) { 19 | this._x = value 20 | } 21 | 22 | get y (): number { 23 | return this._y 24 | } 25 | 26 | set y (value: number) { 27 | this._y = value 28 | } 29 | 30 | get z (): number { 31 | return this._z 32 | } 33 | 34 | set z (value: number) { 35 | this._z = value 36 | } 37 | 38 | get distance (): number { 39 | return this._distance 40 | } 41 | 42 | set distance (value: number) { 43 | this._distance = value 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /examples/udp/basic-dtls/client/UDP.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | var connection = PacketPeerUDP.new() 4 | var dtls = PacketPeerDTLS.new() 5 | 6 | var _cert: X509Certificate = X509Certificate.new() 7 | 8 | var test = null 9 | var values = [ 10 | true,false, 11 | 1, -1, 500, -500, 12 | 1.2, -1.2, 50.1, -50.1, 80.852078542, 13 | "test1", "test2", "test3" 14 | ] 15 | 16 | func _ready(): 17 | _cert.load('res://certs/x509.crt') 18 | print("Start client UDP") 19 | # Connect 20 | connection.connect_to_host("127.0.0.1", 9091) 21 | dtls.connect_to_peer(connection, true, "127.0.0.1", _cert) 22 | connection.put_var(null) 23 | 24 | func _process(_delta): 25 | dtls.poll() 26 | 27 | if dtls.get_status() == PacketPeerDTLS.STATUS_CONNECTED: 28 | while dtls.get_available_packet_count() > 0: 29 | test = connection.get_var() 30 | print(test) 31 | if values.size() > 0 : 32 | connection.put_var(values.pop_front()) 33 | -------------------------------------------------------------------------------- /examples/certs_generator/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bj28ycppjbhti" 6 | path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.png" 14 | dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/lossy_quality=0.7 20 | compress/hdr_compression=1 21 | compress/bptc_ldr=0 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /examples/tcp/advanced/client/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bv67f0j6n0jvq" 6 | path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.png" 14 | dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/lossy_quality=0.7 20 | compress/hdr_compression=1 21 | compress/bptc_ldr=0 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /examples/tcp/basic/client/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://b536qlt1f0trl" 6 | path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.png" 14 | dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/lossy_quality=0.7 20 | compress/hdr_compression=1 21 | compress/bptc_ldr=0 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /examples/udp/advanced/client/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bf3ndetvievmc" 6 | path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.png" 14 | dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/lossy_quality=0.7 20 | compress/hdr_compression=1 21 | compress/bptc_ldr=0 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /examples/udp/basic/client/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://df7wwr8tqebec" 6 | path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.png" 14 | dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/lossy_quality=0.7 20 | compress/hdr_compression=1 21 | compress/bptc_ldr=0 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /examples/tcp/basic-ssl/client/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://cabjcbgj02ynd" 6 | path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.png" 14 | dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/lossy_quality=0.7 20 | compress/hdr_compression=1 21 | compress/bptc_ldr=0 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /examples/udp/basic-dtls/client/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://df7wwr8tqebec" 6 | path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.png" 14 | dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/lossy_quality=0.7 20 | compress/hdr_compression=1 21 | compress/bptc_ldr=0 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /examples/websocket/basic/client/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://1vb1y4tsaei3" 6 | path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.png" 14 | dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/lossy_quality=0.7 20 | compress/hdr_compression=1 21 | compress/bptc_ldr=0 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /examples/websocket/advanced/client/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dnb8n4sesci6f" 6 | path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.png" 14 | dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/lossy_quality=0.7 20 | compress/hdr_compression=1 21 | compress/bptc_ldr=0 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /examples/websocket/basic-ssl/client/icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://s87272jhn3po" 6 | path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.png" 14 | dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/lossy_quality=0.7 20 | compress/hdr_compression=1 21 | compress/bptc_ldr=0 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | -------------------------------------------------------------------------------- /src/put/put_var/string.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | import { putU32 } from '../put_u32' 3 | 4 | function putString (value: string): Buffer { 5 | const len = Buffer.byteLength(value) 6 | const pad = len % 4 === 0 ? 0 : 4 - len % 4 7 | const newBuffer = Buffer.allocUnsafe(4 + len + pad) 8 | 9 | newBuffer.writeUInt32LE(len, 0) 10 | newBuffer.write(value, 4) 11 | if (pad !== 0) { 12 | const pos = 4 + len 13 | 14 | for (let i = 0; i < pad; i++) { 15 | newBuffer.write('\0', i + pos) 16 | } 17 | } 18 | return newBuffer 19 | } 20 | 21 | /** 22 | * Encode string 23 | * @param value 24 | * @returns {Buffer} 25 | */ 26 | function subPutVarString(value: string): Buffer { 27 | const type = putU32(TYPE.STRING) 28 | const data = putString(value) 29 | return Buffer.concat([type, data]) 30 | } 31 | 32 | export const putVarString = (prepare, value: string): Buffer => subPutVarString(value); -------------------------------------------------------------------------------- /src/put/put_var/float.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | import { putU16 } from '../put_u16' 3 | import { putFloat } from '../put_float' 4 | 5 | /** 6 | * Encode Float 7 | * @param value 8 | * @returns {Buffer} 9 | */ 10 | function subPutVarFloat (value: number): Buffer { 11 | // always encode real as double cf : marshalls.cpp L842 12 | // if (x64) { // TODO x64 13 | // /* eslint-enable */ 14 | // let buf = putU16(FLOAT) 15 | // buf = putU16(1, buf) // flag 1 for double 16 | // buf = putDouble(value, buf) 17 | // return Promise.resolve({ 18 | // value: buf, 19 | // length: buf.length 20 | // }) 21 | // } 22 | 23 | const type = putU16(TYPE.FLOAT) 24 | const flag = putU16(0) // flag 0 for float 25 | const data = putFloat(value) 26 | 27 | return Buffer.concat([type, flag, data]) 28 | } 29 | 30 | export const putVarFloat = (prepare, value: number): Buffer => subPutVarFloat(value) -------------------------------------------------------------------------------- /src/put/put_var/rawArray.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | import { putU32 } from '../put_u32' 3 | 4 | function putBuffer (value: Buffer): Buffer { 5 | const len = value.byteLength 6 | const pad = len % 4 === 0 ? 0 : 4 - len % 4 7 | const newBuffer = Buffer.allocUnsafe(4 + len + pad) 8 | 9 | newBuffer.writeUInt32LE(len, 0) 10 | value.copy(newBuffer, 4) 11 | 12 | if (pad !== 0) { 13 | const pos = 4 + len 14 | 15 | for (let i = 0; i < pad; i++) { 16 | newBuffer.write('\0', i + pos) 17 | } 18 | } 19 | return newBuffer 20 | } 21 | 22 | /** 23 | * Encode PoolByteArray 24 | * @param value 25 | * @returns {Buffer} 26 | */ 27 | function subPutVarRawArray (value: Buffer): Buffer { 28 | const type = putU32(TYPE.RAW_ARRAY) 29 | const data = putBuffer(value) 30 | return Buffer.concat([type, data]) 31 | } 32 | 33 | export const putVarRawArray = (prepare, value: Buffer): Buffer => subPutVarRawArray(value) 34 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import { Transform } from 'stream' 2 | 3 | export class StreamTcp extends Transform { 4 | private _buffer: Buffer; 5 | 6 | constructor(opts) { 7 | super({ 8 | ...opts, 9 | objectMode: true, 10 | }) 11 | this._buffer = Buffer.from([]) 12 | } 13 | 14 | _transform(chunk, enc, done) { 15 | this._buffer = Buffer.concat([this._buffer, chunk]) 16 | 17 | while (this._buffer.length >= 4) { 18 | let _length = this._buffer.readUInt16LE(0) 19 | 20 | if (this._buffer.length >= (_length + 4)) { 21 | this.push(this._buffer.slice(4, _length + 4)) 22 | this._buffer = this._buffer.slice(_length + 4) 23 | } else { 24 | break; 25 | } 26 | } 27 | 28 | done() 29 | } 30 | } 31 | 32 | export const prefixWithLength = (buffer: Buffer) => { 33 | const lengthBuffer = Buffer.alloc(4) 34 | lengthBuffer.writeUInt32LE(buffer.length, 0) 35 | return Buffer.concat([lengthBuffer, buffer]) 36 | } -------------------------------------------------------------------------------- /examples/tcp/advanced/server/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@gd-com/utils@^5.0.0": 6 | version "5.0.0" 7 | resolved "https://registry.yarnpkg.com/@gd-com/utils/-/utils-5.0.0.tgz#510de74fdf634648d933ffaa2b925968b4511d3a" 8 | integrity sha512-gddq0BoZVtL/IfldtPxk5HH0n6PAPNG9W0FGKIh/u4V1jo8SJpsynAiE1xOQn5PoZ8Bljr/stnO+zkg1DY3aVw== 9 | dependencies: 10 | long "^5.2.0" 11 | 12 | long@^5.2.0: 13 | version "5.2.1" 14 | resolved "https://registry.yarnpkg.com/long/-/long-5.2.1.tgz#e27595d0083d103d2fa2c20c7699f8e0c92b897f" 15 | integrity sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A== 16 | 17 | uuid@^3.3.2: 18 | version "3.4.0" 19 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" 20 | integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== 21 | -------------------------------------------------------------------------------- /examples/udp/advanced/server/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@gd-com/utils@^5.0.0": 6 | version "5.0.0" 7 | resolved "https://registry.yarnpkg.com/@gd-com/utils/-/utils-5.0.0.tgz#510de74fdf634648d933ffaa2b925968b4511d3a" 8 | integrity sha512-gddq0BoZVtL/IfldtPxk5HH0n6PAPNG9W0FGKIh/u4V1jo8SJpsynAiE1xOQn5PoZ8Bljr/stnO+zkg1DY3aVw== 9 | dependencies: 10 | long "^5.2.0" 11 | 12 | long@^5.2.0: 13 | version "5.2.1" 14 | resolved "https://registry.yarnpkg.com/long/-/long-5.2.1.tgz#e27595d0083d103d2fa2c20c7699f8e0c92b897f" 15 | integrity sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A== 16 | 17 | uuid@^3.3.2: 18 | version "3.4.0" 19 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" 20 | integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== 21 | -------------------------------------------------------------------------------- /examples/websocket/basic-ssl/server/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@gd-com/utils@^5.0.0": 6 | version "5.0.0" 7 | resolved "https://registry.yarnpkg.com/@gd-com/utils/-/utils-5.0.0.tgz#510de74fdf634648d933ffaa2b925968b4511d3a" 8 | integrity sha512-gddq0BoZVtL/IfldtPxk5HH0n6PAPNG9W0FGKIh/u4V1jo8SJpsynAiE1xOQn5PoZ8Bljr/stnO+zkg1DY3aVw== 9 | dependencies: 10 | long "^5.2.0" 11 | 12 | long@^5.2.0: 13 | version "5.2.1" 14 | resolved "https://registry.yarnpkg.com/long/-/long-5.2.1.tgz#e27595d0083d103d2fa2c20c7699f8e0c92b897f" 15 | integrity sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A== 16 | 17 | ws@^8.9.0: 18 | version "8.11.0" 19 | resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" 20 | integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== 21 | -------------------------------------------------------------------------------- /src/get/get_var/transform.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotTransform, GodotVector3} from "../../types"; 2 | 3 | /** 4 | * Decode Transform 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Object, length: Number}} 8 | */ 9 | export function getVarTransform (genericDecoder, buf: Buffer): IGetReturn { 10 | return { 11 | value: new GodotTransform( 12 | new GodotVector3( 13 | buf.readFloatLE(0), 14 | buf.readFloatLE(4), 15 | buf.readFloatLE(8) 16 | ), 17 | new GodotVector3( 18 | buf.readFloatLE(12), 19 | buf.readFloatLE(16), 20 | buf.readFloatLE(20) 21 | ), 22 | new GodotVector3( 23 | buf.readFloatLE(24), 24 | buf.readFloatLE(28), 25 | buf.readFloatLE(32) 26 | ), 27 | new GodotVector3( 28 | buf.readFloatLE(36), 29 | buf.readFloatLE(40), 30 | buf.readFloatLE(44) 31 | ), 32 | ), 33 | length: 48 34 | } 35 | } -------------------------------------------------------------------------------- /examples/websocket/advanced/server/src/index.js: -------------------------------------------------------------------------------- 1 | const WebSocket = require('ws') 2 | const { getU16, putU16, putString } = require('@gd-com/utils') 3 | const { v4 } = require('uuid') 4 | const process = require('./process') 5 | 6 | const wss = new WebSocket.Server({ port: 8080 }) 7 | 8 | wss.on('connection', ws => { 9 | let uuid = v4() 10 | console.log(`[${uuid}] Connected`) 11 | 12 | // send is uuid 13 | let uuidPacketId = putU16(1) 14 | let uuidPacketData = putString(uuid) 15 | let uuidPacket = Buffer.concat([uuidPacketId, uuidPacketData]) 16 | ws.send(uuidPacket) 17 | 18 | ws.on('message', (message) => { 19 | let recieve = Buffer.from(message) 20 | 21 | const type = getU16(recieve) 22 | console.log(`[${uuid}] << Recieve packet code`, type.value) 23 | if (process.hasOwnProperty(type.value)) { 24 | process[`${type.value}`](uuid, ws, recieve.slice(type.length)) 25 | } else { 26 | console.log(`[${uuid}] << Unknow packet code`, type.value) 27 | } 28 | }) 29 | }) 30 | -------------------------------------------------------------------------------- /examples/tcp/basic/server/src/index.js: -------------------------------------------------------------------------------- 1 | const net = require('net') 2 | const { putVar, getVar, prefixWithLength, StreamTcp } = require('@gd-com/utils') 3 | 4 | let server = net.createServer((socket) => { 5 | console.log('A client is connected !') 6 | 7 | const tcpSplit = new StreamTcp() 8 | 9 | socket.pipe(tcpSplit).on('data', (data) => { 10 | const packet = new Buffer.from(data) 11 | 12 | const decoded = getVar(packet) 13 | console.log('receive :', decoded.value) 14 | 15 | // we need to put the packet length on top cause it's tcp 16 | const packetToSend = prefixWithLength(putVar(Math.random())) 17 | 18 | console.log('send :', packetToSend) 19 | socket.write(packetToSend) 20 | }) 21 | 22 | socket.on('error', () => console.log('Bye :(')) 23 | socket.on('close', () => console.log('Bye :(')) 24 | }) 25 | 26 | server.on('error', (err) => { 27 | throw err 28 | }) 29 | 30 | server.listen(9090, '127.0.0.1', () => { 31 | console.log(`Server launched TCP 127.0.0.1:${9090}`) 32 | }) 33 | -------------------------------------------------------------------------------- /src/put/put_var/array.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | /** 3 | * Encode array 4 | * @param value 5 | * @returns {Buffer} 6 | */ 7 | function subPutVarArray (value: Array): Buffer { 8 | let len = 8 9 | 10 | for (const i in value) { 11 | if (Object.prototype.hasOwnProperty.call(value, i)) { 12 | len += value[i].length 13 | } 14 | } 15 | 16 | const buf = Buffer.alloc(len) 17 | 18 | buf.writeUInt16LE(TYPE.ARRAY, 0) 19 | buf.writeUInt16LE(value.length & 0x7FFFFFFF, 4) 20 | 21 | let bufPos = 8 22 | 23 | for (const i in value) { 24 | if (Object.prototype.hasOwnProperty.call(value, i)) { 25 | value[i].copy(buf, bufPos) 26 | bufPos += value[i].length 27 | } 28 | } 29 | 30 | return buf 31 | } 32 | 33 | export function putVarArray(prepare, array: Array): Buffer { 34 | const results = array.reduce((rawData, item) => { 35 | const data = prepare(item) 36 | rawData.push(data) 37 | return rawData 38 | }, []) 39 | return subPutVarArray(results) 40 | } -------------------------------------------------------------------------------- /examples/udp/basic-dtls/server/icon.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://ca67iatwidbb5" 6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.svg" 14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/lossy_quality=0.7 20 | compress/hdr_compression=1 21 | compress/bptc_ldr=0 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | svg/scale=1.0 36 | editor/scale_with_editor_scale=false 37 | editor/convert_colors_with_editor_theme=false 38 | -------------------------------------------------------------------------------- /src/get/get_var/float32Array.ts: -------------------------------------------------------------------------------- 1 | import { getVarFloat } from './float' 2 | import {IGetReturn, GodotArray, GodotFloat} from "../../types"; 3 | 4 | /** 5 | * Decode PoolRealArray 6 | * @param genericDecoder 7 | * @param buf {Buffer} 8 | * @returns {{value: Array, length: Number}} 9 | */ 10 | export function getVarFloat32Array (genericDecoder, buf): IGetReturn> { 11 | const nbEntries = buf.readUInt32LE(0) 12 | 13 | // start at 4 cause of nbEntries 14 | const data: { 15 | array: Array, 16 | buffer: Buffer, 17 | pos: number, 18 | } = { 19 | array: [], 20 | buffer: buf.slice(4), 21 | pos: 4 22 | } 23 | 24 | for (let index = 0; index < nbEntries; index++) { 25 | const decodedValue = getVarFloat(genericDecoder, data.buffer, 0) 26 | data.array.push(decodedValue.value) 27 | data.buffer = data.buffer.slice(decodedValue.length) 28 | data.pos += decodedValue.length 29 | } 30 | 31 | return { 32 | value: data.array, 33 | length: data.pos 34 | } 35 | } -------------------------------------------------------------------------------- /src/get/get_var/float64Array.ts: -------------------------------------------------------------------------------- 1 | import { getVarFloat } from './float' 2 | import {IGetReturn, GodotArray, GodotFloat} from "../../types"; 3 | 4 | /** 5 | * Decode PoolRealArray 6 | * @param genericDecoder 7 | * @param buf {Buffer} 8 | * @returns {{value: Array, length: Number}} 9 | */ 10 | export function getVarFloat64Array (genericDecoder, buf): IGetReturn> { 11 | const nbEntries = buf.readUInt32LE(0) 12 | 13 | // start at 4 cause of nbEntries 14 | const data: { 15 | array: Array, 16 | buffer: Buffer, 17 | pos: number, 18 | } = { 19 | array: [], 20 | buffer: buf.slice(4), 21 | pos: 4 22 | } 23 | 24 | for (let index = 0; index < nbEntries; index++) { 25 | const decodedValue = getVarFloat(genericDecoder, data.buffer, 1) 26 | data.array.push(decodedValue.value) 27 | data.buffer = data.buffer.slice(decodedValue.length) 28 | data.pos += decodedValue.length 29 | } 30 | 31 | return { 32 | value: data.array, 33 | length: data.pos 34 | } 35 | } -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | export { GodotAabb } from './GodotAabb' 2 | export { GodotArray } from './GodotArray' 3 | export { GodotBasis } from './GodotBasis' 4 | export { GodotBoolean } from './GodotBoolean' 5 | export { GodotColor } from './GodotColor' 6 | export { GodotDictionnary } from './GodotDictionnary' 7 | export { GodotFloat } from './GodotFloat' 8 | export { GodotInteger } from './GodotInteger' 9 | export { GodotNodePath } from './GodotNodePath' 10 | export { GodotNull } from './GodotNull' 11 | export { GodotPlane } from './GodotPlane' 12 | export { GodotQuat } from './GodotQuat' 13 | export { GodotRect2 } from './GodotRect2' 14 | export { GodotString } from './GodotString' 15 | export { GodotTransform } from './GodotTransform' 16 | export { GodotTransform2D } from './GodotTransform2D' 17 | export { GodotVector2 } from './GodotVector2' 18 | export { GodotVector3 } from './GodotVector3' 19 | export { IGetReturn } from './IGetReturn' 20 | export { IDecoderList } from './IDecoderList' 21 | export { IEncoderList } from './IEncoderList' 22 | -------------------------------------------------------------------------------- /examples/udp/basic-dtls/server/UDP_DTLS.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | var dtls := DTLSServer.new() 4 | var server := UDPServer.new() 5 | var peers = [] 6 | 7 | func _ready(): 8 | server.listen(9091) 9 | var key = load("res://certs/x509.key") 10 | var cert = load("res://certs/x509.crt") 11 | dtls.setup(key, cert) 12 | 13 | func _process(_delta): 14 | while server.is_connection_available(): 15 | var peer : PacketPeerUDP = server.take_connection() 16 | var dtls_peer : PacketPeerDTLS = dtls.take_connection(peer) 17 | if dtls_peer.get_status() != PacketPeerDTLS.STATUS_HANDSHAKING: 18 | continue # It is normal that 50% of the connections fails due to cookie exchange. 19 | print("Peer connected!") 20 | peers.append(dtls_peer) 21 | for p in peers: 22 | p.poll() # Must poll to update the state. 23 | if p.get_status() == PacketPeerDTLS.STATUS_CONNECTED: 24 | while p.get_available_packet_count() > 0: 25 | print("Received message from client: %s" % p.get_packet().get_string_from_utf8()) 26 | p.put_packet("Hello DTLS client") 27 | -------------------------------------------------------------------------------- /src/get/get_var/colorArray.ts: -------------------------------------------------------------------------------- 1 | import { getVarColor } from './color' 2 | import {IGetReturn, GodotColor, GodotArray} from "../../types"; 3 | 4 | /** 5 | * Decode PoolColorArray 6 | * @param genericDecoder 7 | * @param buf {Buffer} 8 | * @returns {{value: Array, length: Number}} 9 | */ 10 | export function getVarColorArray (genericDecoder, buf: Buffer): IGetReturn> { 11 | const nbEntries = buf.readUInt32LE(0) 12 | 13 | // start at 4 cause of nbEntries 14 | const data: { 15 | array: Array, 16 | buffer: Buffer, 17 | pos: number, 18 | } = { 19 | array: [], 20 | buffer: buf.slice(4), 21 | pos: 4 22 | } 23 | 24 | for (let index = 0; index < nbEntries; index++) { 25 | const decodedValue = getVarColor(genericDecoder, data.buffer) 26 | data.array.push(decodedValue.value) 27 | data.buffer = data.buffer.slice(decodedValue.length) 28 | data.pos += decodedValue.length 29 | } 30 | 31 | return { 32 | value: data.array, 33 | length: data.pos 34 | } 35 | } -------------------------------------------------------------------------------- /src/get/get_var/stringArray.ts: -------------------------------------------------------------------------------- 1 | import { getVarString } from './string' 2 | import {IGetReturn, GodotString, GodotArray} from "../../types"; 3 | 4 | /** 5 | * Decode PoolStringArray 6 | * @param genericDecoder 7 | * @param buf {Buffer} 8 | * @returns {{value: Array, length: Number}} 9 | */ 10 | export function getVarStringArray (genericDecoder, buf: Buffer): IGetReturn> { 11 | const nbEntries = buf.readUInt32LE(0) 12 | 13 | // start at 4 cause of nbEntries 14 | const data: { 15 | array: Array, 16 | buffer: Buffer, 17 | pos: number, 18 | } = { 19 | array: [], 20 | buffer: buf.slice(4), 21 | pos: 4 22 | } 23 | 24 | for (let index = 0; index < nbEntries; index++) { 25 | const decodedValue = getVarString(genericDecoder, data.buffer) 26 | data.array.push(decodedValue.value) 27 | data.buffer = data.buffer.slice(decodedValue.length) 28 | data.pos += decodedValue.length 29 | } 30 | 31 | return { 32 | value: data.array, 33 | length: data.pos 34 | } 35 | } -------------------------------------------------------------------------------- /src/get/get_var/vector2Array.ts: -------------------------------------------------------------------------------- 1 | import { getVarVector2 } from './vector2' 2 | import {IGetReturn, GodotArray, GodotVector2} from "../../types"; 3 | 4 | /** 5 | * Decode Vector2Array 6 | * @param genericDecoder 7 | * @param buf {Buffer} 8 | * @returns {{value: Array, length: Number}} 9 | */ 10 | export function getVarVector2Array (genericDecoder, buf: Buffer): IGetReturn> { 11 | const nbEntries = buf.readUInt32LE(0) 12 | 13 | // start at 4 cause of nbEntries 14 | const data: { 15 | array: Array, 16 | buffer: Buffer, 17 | pos: number, 18 | } = { 19 | array: [], 20 | buffer: buf.slice(4), 21 | pos: 4 22 | } 23 | 24 | for (let index = 0; index < nbEntries; index++) { 25 | const decodedValue = getVarVector2(genericDecoder, data.buffer) 26 | data.array.push(decodedValue.value) 27 | data.buffer = data.buffer.slice(decodedValue.length) 28 | data.pos += decodedValue.length 29 | } 30 | 31 | return { 32 | value: data.array, 33 | length: data.pos 34 | } 35 | } -------------------------------------------------------------------------------- /src/get/get_var/vector3Array.ts: -------------------------------------------------------------------------------- 1 | import { getVarVector3 } from './vector3' 2 | import {IGetReturn, GodotVector3, GodotArray} from "../../types"; 3 | 4 | /** 5 | * Decode Vector3Array 6 | * @param genericDecoder 7 | * @param buf {Buffer} 8 | * @returns {{value: Array, length: Number}} 9 | */ 10 | export function getVarVector3Array (genericDecoder, buf: Buffer): IGetReturn> { 11 | const nbEntries = buf.readUInt32LE(0) 12 | 13 | // start at 4 cause of nbEntries 14 | const data: { 15 | array: Array, 16 | buffer: Buffer, 17 | pos: number, 18 | } = { 19 | array: [], 20 | buffer: buf.slice(4), 21 | pos: 4 22 | } 23 | 24 | for (let index = 0; index < nbEntries; index++) { 25 | const decodedValue = getVarVector3(genericDecoder, data.buffer) 26 | data.array.push(decodedValue.value) 27 | data.buffer = data.buffer.slice(decodedValue.length) 28 | data.pos += decodedValue.length 29 | } 30 | 31 | return { 32 | value: data.array, 33 | length: data.pos 34 | } 35 | } -------------------------------------------------------------------------------- /src/get/get_var/nodePath.ts: -------------------------------------------------------------------------------- 1 | import { getVarString } from './string' 2 | import {IGetReturn, GodotNodePath} from "../../types"; 3 | 4 | /** 5 | * Decode Node Path 6 | * @param genericDecoder 7 | * @param buf {Buffer} 8 | * @returns {{value: String, length: Number}} 9 | */ 10 | export function getVarNodePath (genericDecoder, buf: Buffer): IGetReturn { 11 | const strlen = buf.readUInt32LE(0) 12 | const nameCount = strlen & 0x7FFFFFFF 13 | const subnameCount = buf.readUInt32LE(4) 14 | const total = nameCount + subnameCount 15 | 16 | const names: Array = [] 17 | const subnames: Array = [] 18 | 19 | let len = 12 20 | 21 | for (let i = 0; i < total; i++) { 22 | const strValue = getVarString(genericDecoder, buf.slice(len)) 23 | len = len + strValue.length 24 | if (i < nameCount) { 25 | names.push(strValue.value) 26 | } else { 27 | subnames.push(strValue.value) 28 | } 29 | } 30 | 31 | return { 32 | value: names.join('/') + subnames.join('/'), 33 | length: len 34 | } 35 | } -------------------------------------------------------------------------------- /src/get/get_var/int32Array.ts: -------------------------------------------------------------------------------- 1 | import { getVarInteger } from './integer' 2 | import {IGetReturn, GodotArray, GodotInteger} from "../../types"; 3 | import Long from "long"; 4 | 5 | /** 6 | * Decode PoolIntArray 7 | * @param genericDecoder 8 | * @param buf {Buffer} 9 | * @returns {{value: Array, length: Number}} 10 | */ 11 | export function getVarInt32Array (genericDecoder, buf): IGetReturn> { 12 | const nbEntries = buf.readUInt32LE(0) 13 | 14 | // start at 4 cause of nbEntries 15 | const data: { 16 | array: Array, 17 | buffer: Buffer, 18 | pos: number, 19 | } = { 20 | array: [], 21 | buffer: buf.slice(4), 22 | pos: 4 23 | } 24 | 25 | for (let index = 0; index < nbEntries; index++) { 26 | const decodedValue = getVarInteger(genericDecoder, data.buffer, 0) 27 | data.array.push(decodedValue.value) 28 | data.buffer = data.buffer.slice(decodedValue.length) 29 | data.pos += decodedValue.length 30 | } 31 | 32 | return { 33 | value: data.array, 34 | length: data.pos 35 | } 36 | } -------------------------------------------------------------------------------- /src/get/get_var/int64Array.ts: -------------------------------------------------------------------------------- 1 | import { getVarInteger } from './integer' 2 | import {IGetReturn, GodotArray, GodotInteger} from "../../types"; 3 | import Long from "long"; 4 | 5 | /** 6 | * Decode PoolIntArray 7 | * @param genericDecoder 8 | * @param buf {Buffer} 9 | * @returns {{value: Array, length: Number}} 10 | */ 11 | export function getVarInt64Array (genericDecoder, buf): IGetReturn> { 12 | const nbEntries = buf.readUInt32LE(0) 13 | 14 | // start at 4 cause of nbEntries 15 | const data: { 16 | array: Array, 17 | buffer: Buffer, 18 | pos: number, 19 | } = { 20 | array: [], 21 | buffer: buf.slice(4), 22 | pos: 4 23 | } 24 | 25 | for (let index = 0; index < nbEntries; index++) { 26 | const decodedValue = getVarInteger(genericDecoder, data.buffer, 1) 27 | data.array.push(decodedValue.value) 28 | data.buffer = data.buffer.slice(decodedValue.length) 29 | data.pos += decodedValue.length 30 | } 31 | 32 | return { 33 | value: data.array, 34 | length: data.pos 35 | } 36 | } -------------------------------------------------------------------------------- /src/types/GodotTransform.ts: -------------------------------------------------------------------------------- 1 | import { GodotVector3 } from './GodotVector3' 2 | 3 | export class GodotTransform { 4 | private _x: GodotVector3 5 | private _y: GodotVector3 6 | private _z: GodotVector3 7 | private _origin: GodotVector3 8 | 9 | constructor ( 10 | x: GodotVector3, 11 | y: GodotVector3, 12 | z: GodotVector3, 13 | origin: GodotVector3 14 | ) { 15 | this._x = x 16 | this._y = y 17 | this._z = z 18 | this._origin = origin 19 | } 20 | 21 | get x (): GodotVector3 { 22 | return this._x 23 | } 24 | 25 | set x (value: GodotVector3) { 26 | this._x = value 27 | } 28 | 29 | get y (): GodotVector3 { 30 | return this._y 31 | } 32 | 33 | set y (value: GodotVector3) { 34 | this._y = value 35 | } 36 | 37 | get z (): GodotVector3 { 38 | return this._z 39 | } 40 | 41 | set z (value: GodotVector3) { 42 | this._z = value 43 | } 44 | 45 | get origin (): GodotVector3 { 46 | return this._origin 47 | } 48 | 49 | set origin (value: GodotVector3) { 50 | this._origin = value 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /examples/certs_generator/ROOT.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://dofttrro6exa1"] 2 | 3 | [ext_resource type="Script" path="res://ROOT.gd" id="1"] 4 | 5 | [node name="ROOT" type="Node"] 6 | script = ExtResource("1") 7 | 8 | [node name="Panel" type="Panel" parent="."] 9 | offset_right = 400.0 10 | offset_bottom = 299.0 11 | 12 | [node name="LineEdit" type="LineEdit" parent="Panel"] 13 | layout_mode = 0 14 | offset_left = 112.0 15 | offset_top = 14.0 16 | offset_right = 263.0 17 | offset_bottom = 66.0 18 | text = "x509" 19 | placeholder_text = "Cert name" 20 | 21 | [node name="LineEditCN" type="LineEdit" parent="Panel"] 22 | layout_mode = 1 23 | offset_left = 112.0 24 | offset_top = 83.0 25 | offset_right = 263.0 26 | offset_bottom = 135.0 27 | text = "127.0.0.1" 28 | placeholder_text = "CN" 29 | 30 | [node name="Button" type="Button" parent="Panel"] 31 | layout_mode = 0 32 | offset_left = 115.0 33 | offset_top = 164.0 34 | offset_right = 258.0 35 | offset_bottom = 223.0 36 | text = "Generate" 37 | 38 | [connection signal="pressed" from="Panel/Button" to="." method="_on_Button_pressed"] 39 | -------------------------------------------------------------------------------- /src/get/get_var/array.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotArray} from "../../types"; 2 | 3 | /** 4 | * Decode Array 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Array, length: Number}} 8 | */ 9 | export function getVarArray (genericDecoder, buf: Buffer): IGetReturn> { 10 | const nbEntries = buf.readUInt32LE(0) & 0x7FFFFFFF 11 | // const shared = !!buf.readUInt32LE(0) & 0x80000000 12 | 13 | // start at 4 cause of nbEntries 14 | const data: { 15 | array: Array, 16 | buffer: Buffer, 17 | pos: number, 18 | } = { 19 | array: [], 20 | buffer: buf.slice(4), 21 | pos: 4 22 | } 23 | 24 | for (let index = 0; index < nbEntries; index++) { 25 | const decodedValue = genericDecoder(data.buffer) 26 | const nextBufferOffset = (decodedValue.length + ((4 - decodedValue.length % 4) % 4)) + 4 // Pad to 4 bytes + 4 bytes type 27 | data.array.push(decodedValue.value) 28 | data.buffer = data.buffer.slice(nextBufferOffset) 29 | data.pos += nextBufferOffset 30 | } 31 | 32 | return { 33 | value: data.array, 34 | length: data.pos 35 | } 36 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 gd-com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/tcp/basic-ssl/server/src/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const tls = require('tls') 3 | const {putVar, getVar, StreamTcp, prefixWithLength} = require('@gd-com/utils') 4 | 5 | const server = tls.createServer( 6 | { 7 | key: fs.readFileSync('certs/x509.key'), 8 | cert: fs.readFileSync('certs/x509.crt'), 9 | rejectUnauthorized: true 10 | }, 11 | (socket) => { 12 | console.log('client connected', socket.authorized ? 'authorized' : 'unauthorized'); 13 | 14 | const tcpSplit = new StreamTcp() 15 | 16 | socket.pipe(tcpSplit).on('data', (data) => { 17 | const packet = new Buffer.from(data) 18 | 19 | const decoded = getVar(packet) 20 | console.log('receive :', decoded.value) 21 | 22 | // we need to put the packet length on top cause it's tcp 23 | const packetToSend = prefixWithLength(putVar(Math.random())) 24 | 25 | console.log('send :', packetToSend) 26 | socket.write(packetToSend) 27 | }) 28 | 29 | socket.on('error', () => console.log('Bye :(')) 30 | }); 31 | 32 | server.listen(9090, '127.0.0.1', () => { 33 | console.log(`Server launched TLS 127.0.0.1:${9090}`) 34 | }) 35 | -------------------------------------------------------------------------------- /examples/udp/advanced/client/UDP.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | var connection = PacketPeerUDP.new() 4 | 5 | var ADDRESS = '127.0.0.1' 6 | var PORT_SERVER = 9091 7 | 8 | func _ready(): 9 | print("Start client UDP") 10 | # Connect 11 | connection.connect_to_host(ADDRESS, PORT_SERVER) 12 | 13 | func _process(delta): 14 | if Input.is_action_just_released("ui_left"): 15 | var buffer = StreamPeerBuffer.new() 16 | buffer.put_u16(1001) 17 | connection.put_packet(buffer.get_data_array()) 18 | 19 | if Input.is_action_just_released("ui_right"): 20 | var buffer = StreamPeerBuffer.new() 21 | buffer.put_u16(1002) 22 | print('pass') 23 | connection.put_packet(buffer.get_data_array()) 24 | 25 | if connection.get_available_packet_count() > 0 : 26 | var packet = connection.get_packet() 27 | var buffer = StreamPeerBuffer.new() 28 | buffer.set_data_array(packet) 29 | 30 | var type = buffer.get_u16() 31 | print('Recieve %s' % type) 32 | match type: 33 | 1: 34 | var length = buffer.get_u32() 35 | print("My id is %s !" % buffer.get_string(length)) 36 | 1003: 37 | print("We recieve OK_GO_LEFT !") 38 | 1004: 39 | print("We recieve OK_GO_RIGHT !") 40 | -------------------------------------------------------------------------------- /examples/websocket/basic-ssl/server/src/index.js: -------------------------------------------------------------------------------- 1 | const { createServer } = require('https'); 2 | const { readFileSync } = require('fs'); 3 | const { WebSocketServer, createWebSocketStream } = require('ws'); 4 | 5 | const gdCom = require('@gd-com/utils') 6 | 7 | const server = createServer({ 8 | cert: readFileSync('certs/x509.crt'), 9 | key: readFileSync('certs/x509.key') 10 | }); 11 | 12 | server.on('request', (req, res) => { 13 | res.writeHead(200); 14 | res.end('hello HTTPS world\n'); 15 | }); 16 | 17 | const wss = new WebSocketServer({ server }); 18 | 19 | wss.on('connection', (ws) => { 20 | console.log('Client connected') 21 | const tcpSplit = new gdCom.StreamTcp() 22 | createWebSocketStream(ws).pipe(tcpSplit).on('data', (data) => { 23 | let recieveBuff = Buffer.from(data) 24 | console.log(recieveBuff) 25 | let recieve = gdCom.getVar(recieveBuff) 26 | console.log('Recieve : ', recieve.value) 27 | 28 | let buffer = gdCom.prefixWithLength(gdCom.putVar(Math.random())) 29 | ws.send(buffer) 30 | }); 31 | 32 | ws.on('disconnect', () => { 33 | console.log('Bye :(') 34 | }) 35 | }); 36 | 37 | server.listen(9090, '127.0.0.1', () => { 38 | console.log(`Server HTTPS WS launched 127.0.0.1:${9090}`) 39 | }); -------------------------------------------------------------------------------- /src/put/put_var/dictionnary.ts: -------------------------------------------------------------------------------- 1 | import { TYPE } from '../../constants' 2 | import {GodotDictionnary} from "../../types"; 3 | 4 | /** 5 | * Encode dictionnary 6 | * @param value 7 | * @returns {Buffer} 8 | */ 9 | function subPutVarDictionnary (value: GodotDictionnary): Buffer { 10 | let len = 8 11 | 12 | for (const i in value) { 13 | if (Object.prototype.hasOwnProperty.call(value, i)) { 14 | len += value[i].length 15 | } 16 | } 17 | 18 | const buf = Buffer.alloc(len) 19 | 20 | buf.writeUInt16LE(TYPE.DICTIONARY, 0) 21 | buf.writeUInt32LE((value.length / 2) & 0x7FFFFFFF, 4) 22 | 23 | let bufPos = 8 24 | for (const i in value) { 25 | if (Object.prototype.hasOwnProperty.call(value, i)) { 26 | value[i].copy(buf, bufPos) 27 | bufPos += value[i].length 28 | } 29 | } 30 | 31 | return buf 32 | } 33 | 34 | export const putVarDictionnary = (prepare, dictionary: GodotDictionnary): Buffer => { 35 | const results = Object.keys(dictionary).reduce((rawData: Array, key: string) => { 36 | const rawKey = prepare(key) 37 | const rawValue = prepare(dictionary[key]) 38 | rawData.push(rawKey, rawValue) 39 | return rawData 40 | }, []) 41 | return subPutVarDictionnary(results) 42 | } -------------------------------------------------------------------------------- /src/get/get_var/dictionnary.ts: -------------------------------------------------------------------------------- 1 | import {IGetReturn, GodotDictionnary} from "../../types"; 2 | 3 | /** 4 | * Decode Dictionnary 5 | * @param genericDecoder 6 | * @param buf {Buffer} 7 | * @returns {{value: Object, length: Number}} 8 | */ 9 | 10 | export function getVarDictionnary (genericDecoder, buf: Buffer): IGetReturn> { 11 | const nbEntries = buf.readUInt32LE(0) & 0x7FFFFFFF 12 | // const shared = !!buf.readUInt32LE(0) & 0x80000000 13 | 14 | const data = { 15 | dictionary: {}, 16 | pos: 0, 17 | buffer: buf.slice(4) 18 | } 19 | 20 | for (let index = 0; index < nbEntries; index++) { 21 | const decodedKey = genericDecoder(data.buffer) 22 | data.pos += decodedKey.length + 4 // 4 type length 23 | const nextBuffer = data.buffer.slice(decodedKey.length + 4) 24 | 25 | const decodedValue = genericDecoder(nextBuffer) 26 | const nextBufferOffset = (decodedValue.length + ((4 - decodedValue.length % 4) % 4)) + 4 // Pad to 4 bytes + 4 bytes type 27 | data.pos += nextBufferOffset 28 | data.dictionary[decodedKey.value] = decodedValue.value 29 | data.buffer = nextBuffer.slice(nextBufferOffset) 30 | } 31 | 32 | return { 33 | value: data.dictionary, 34 | length: data.pos + 4 // 4 type length 35 | } 36 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## CHANGELOG 2 | 3 | * v4.1.4 4 | * Fix bug on StreamTCP 5 | * more tests ! 6 | 7 | * v4.1.3 8 | * Export StreamTCP and prefixWithLength 9 | * more tests ! 10 | 11 | * v4.1.2 12 | * Typescript 13 | * Migrate all tests to Jest 14 | 15 | * v4.1.1 16 | * Fix padding when reading dictionaries and arrays thx @timoschwarzer 17 | * putVar POOL_BYTE_ARRAY thx @timoschwarzer 18 | * can now force encode to specific type 19 | * more tests ! 20 | 21 | * v4.1.0 22 | * remove useless function 23 | * putVar can now encode Variant : AABB Color Plane Quat Rect2 Vector2 Vector3 24 | * Use NodeJs Buffer, no more GdBuffer anymore !! 25 | 26 | * v4.0.0 27 | * remove async/await thx @phated 28 | 29 | * v3.0.0 30 | * merge tcp, udp and ws features in @gd-com/utils 31 | 32 | * v2.1.3 33 | * put_var now return only buffer (in promise) 34 | 35 | * v2.1.2 36 | * some bugfix 37 | 38 | * v2.1.1 39 | * int64 40 | 41 | * v2.1.0 42 | * promisify function 43 | 44 | * v2.0.0 45 | * rethink of the architecture 46 | * add put / get method like in StreamPeer 47 | 48 | * v1.0.0 49 | * Encode 50 | * Null 51 | * Boolean 52 | * Integer 53 | * Float 54 | * String 55 | * Array 56 | * Dictionnary 57 | * Decode everything except node path 58 | -------------------------------------------------------------------------------- /examples/udp/advanced/server/src/index.js: -------------------------------------------------------------------------------- 1 | const dgram = require('dgram') 2 | const { getU16 } = require('@gd-com/utils') 3 | const { v4 } = require('uuid') 4 | const process = require('./process') 5 | 6 | const server = dgram.createSocket('udp4') 7 | 8 | let clients = {} 9 | 10 | server.on('listening', () => { 11 | let address = server.address() 12 | console.log(`UDP Server listening on ${address.address}:${address.port}`) 13 | }) 14 | 15 | server.on('message', (buf, remote) => { 16 | let client = null 17 | if (!clients.hasOwnProperty(`${remote.address}-${remote.port}`)) { 18 | clients[`${remote.address}-${remote.port}`] = {uuid: v4()} 19 | client = clients[`${remote.address}-${remote.port}`] 20 | console.log(`[${client.uuid}] New client from ${remote.address}:${remote.port}`) 21 | } else { 22 | client = clients[`${remote.address}-${remote.port}`] 23 | } 24 | 25 | let recieve = new Buffer.from(buf) 26 | const type = getU16(recieve) 27 | 28 | console.log(`[${client.uuid}] << Recieve packet code`, type.value) 29 | if (process.hasOwnProperty(type.value)) { 30 | process[`${type.value}`](client, server, remote, recieve.slice(type.length)) 31 | } else { 32 | console.log(`[${client.uuid}] << Unknow packet code`, type.value) 33 | } 34 | }) 35 | 36 | server.bind(9091, '127.0.0.1') 37 | -------------------------------------------------------------------------------- /examples/websocket/basic/server/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@gd-com/utils@^5.0.0": 6 | version "5.0.0" 7 | resolved "https://registry.yarnpkg.com/@gd-com/utils/-/utils-5.0.0.tgz#510de74fdf634648d933ffaa2b925968b4511d3a" 8 | integrity sha512-gddq0BoZVtL/IfldtPxk5HH0n6PAPNG9W0FGKIh/u4V1jo8SJpsynAiE1xOQn5PoZ8Bljr/stnO+zkg1DY3aVw== 9 | dependencies: 10 | long "^5.2.0" 11 | 12 | async-limiter@~1.0.0: 13 | version "1.0.1" 14 | resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" 15 | integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== 16 | 17 | long@^5.2.0: 18 | version "5.2.1" 19 | resolved "https://registry.yarnpkg.com/long/-/long-5.2.1.tgz#e27595d0083d103d2fa2c20c7699f8e0c92b897f" 20 | integrity sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A== 21 | 22 | ws@^6.1.3: 23 | version "6.2.2" 24 | resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" 25 | integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw== 26 | dependencies: 27 | async-limiter "~1.0.0" 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gd-com/utils", 3 | "version": "5.0.0", 4 | "description": "Serializer/deserializer utils for godot engine", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "files": [ 8 | "/dist" 9 | ], 10 | "scripts": { 11 | "build": "tsc", 12 | "lint": "ts-standard --fix src/**/*.ts", 13 | "prettier": "prettier --write src/**/*.ts", 14 | "test": "jest", 15 | "test:clear": "jest --clearCache", 16 | "publish-lib": "npm run build && npm publish", 17 | "publish-beta": "npm run build && npm publish --tag beta", 18 | "publish-dryrun": "npm run build && npm publish --dry-run" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/gd-com/utils.git" 23 | }, 24 | "bugs": { 25 | "url": "https://github.com/gd-com/utils/issues" 26 | }, 27 | "homepage": "https://github.com/gd-com/utils#readme", 28 | "devDependencies": { 29 | "@types/node": "^16.11.10", 30 | "jest": "^27.3.1", 31 | "nyc": "^15.1.0", 32 | "prettier": "^2.5.0", 33 | "ts-standard": "^11.0.0", 34 | "typescript": "^4.4.4" 35 | }, 36 | "keywords": [ 37 | "library", 38 | "godot", 39 | "nodejs", 40 | "tcp", 41 | "udp", 42 | "socket", 43 | "websocket", 44 | "helper" 45 | ], 46 | "author": "Tilican", 47 | "license": "MIT", 48 | "contributors": [ 49 | "Xavier Sellier " 50 | ], 51 | "dependencies": { 52 | "long": "^5.2.0" 53 | }, 54 | "peerDependencies": { 55 | "long": "^5.2.0" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /examples/websocket/advanced/server/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@gd-com/utils@^5.0.0": 6 | version "5.0.0" 7 | resolved "https://registry.yarnpkg.com/@gd-com/utils/-/utils-5.0.0.tgz#510de74fdf634648d933ffaa2b925968b4511d3a" 8 | integrity sha512-gddq0BoZVtL/IfldtPxk5HH0n6PAPNG9W0FGKIh/u4V1jo8SJpsynAiE1xOQn5PoZ8Bljr/stnO+zkg1DY3aVw== 9 | dependencies: 10 | long "^5.2.0" 11 | 12 | async-limiter@~1.0.0: 13 | version "1.0.1" 14 | resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" 15 | integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== 16 | 17 | long@^5.2.0: 18 | version "5.2.1" 19 | resolved "https://registry.yarnpkg.com/long/-/long-5.2.1.tgz#e27595d0083d103d2fa2c20c7699f8e0c92b897f" 20 | integrity sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A== 21 | 22 | uuid@^3.3.2: 23 | version "3.4.0" 24 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" 25 | integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== 26 | 27 | ws@^6.1.3: 28 | version "6.2.2" 29 | resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" 30 | integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw== 31 | dependencies: 32 | async-limiter "~1.0.0" 33 | -------------------------------------------------------------------------------- /examples/tcp/advanced/server/src/index.js: -------------------------------------------------------------------------------- 1 | const net = require('net') 2 | const { getU16, putU16, putString } = require('@gd-com/utils') 3 | const { v4 } = require('uuid') 4 | const process = require('./process') 5 | const StreamTcp = require('./StreamTcp') 6 | 7 | const tcpSplit = new StreamTcp() 8 | 9 | let server = net.createServer((socket) => { 10 | let uuid = v4() 11 | 12 | console.log(`[${uuid}] Connected`); 13 | 14 | // send is uuid 15 | const uuidPacketID = putU16(1) 16 | const uuidPacketData = putString(uuid) 17 | 18 | const lengthBuffer = Buffer.alloc(4) 19 | lengthBuffer.writeUInt32LE(uuidPacketID.length + uuidPacketData.length, 0) 20 | const toSend = Buffer.concat([lengthBuffer, uuidPacketID, uuidPacketData]) 21 | 22 | socket.write(toSend) 23 | 24 | socket.pipe(tcpSplit).on('data', (data) => { 25 | let recieve = new Buffer.from(data) 26 | console.log(recieve) 27 | 28 | const type = getU16(recieve) 29 | 30 | console.log(`[${uuid}] << Recieve packet code`, type.value) 31 | if (process.hasOwnProperty(type.value)) { 32 | process[`${type.value}`](uuid, socket, recieve.slice(type.length)) 33 | } else { 34 | console.log(`[${uuid}] << Unknow packet code`, type.value) 35 | } 36 | 37 | }) 38 | 39 | socket.on('end', () => { 40 | console.log('Bye :(') 41 | }) 42 | socket.on('error', () => { 43 | console.log('Bye :(') 44 | }) 45 | }) 46 | 47 | server.on('error', (err) => { 48 | throw err 49 | }) 50 | 51 | server.listen(9090, '127.0.0.1', () => { 52 | console.log(`Server launched TCP 127.0.0.1:${9090}`) 53 | }) 54 | -------------------------------------------------------------------------------- /examples/websocket/basic/client/networking.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | signal connected 4 | signal data 5 | signal disconnected 6 | signal error 7 | 8 | var _status: int = WebSocketPeer.STATE_CONNECTING 9 | var _stream: WebSocketPeer = WebSocketPeer.new() 10 | 11 | func _ready() -> void: 12 | _status = _stream.get_ready_state() 13 | 14 | func _process(_delta: float) -> void: 15 | _stream.poll() 16 | var new_status: int = _stream.get_ready_state() 17 | if new_status != _status: 18 | _status = new_status 19 | match _status: 20 | _stream.STATE_CLOSED: 21 | print("Disconnected from host.") 22 | emit_signal("disconnected") 23 | _stream.STATE_CONNECTING: 24 | print("Connecting to host.") 25 | _stream.STATE_OPEN: 26 | print("Connected to host.") 27 | emit_signal("connected") 28 | _stream.STATE_CLOSING: 29 | print("Closing with socket stream.") 30 | emit_signal("error") 31 | 32 | if _status == _stream.STATE_OPEN: 33 | var available_packet_count: int = _stream.get_available_packet_count() 34 | if available_packet_count > 0: 35 | emit_signal("data", _stream.get_packet()) 36 | 37 | func connect_to_host(host: String, port: int) -> void: 38 | var url = "ws://%s:%d" % [host, port] 39 | print("Connecting to %s" % [url]) 40 | # Reset status so we can tell if it changes to error again. 41 | _status = _stream.STATE_CONNECTING 42 | if _stream.connect_to_url(url, false) != OK: 43 | print("Error connecting to host.") 44 | emit_signal("error") 45 | 46 | func send(data) -> bool: 47 | if _status != _stream.STATE_OPEN: 48 | print("Error: Stream is not currently connected.") 49 | return false 50 | var error: int = _stream.send(data) 51 | if error != OK: 52 | print("Error writing to stream: ", error) 53 | return false 54 | return true 55 | -------------------------------------------------------------------------------- /examples/websocket/advanced/client/networking.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | signal connected 4 | signal data 5 | signal disconnected 6 | signal error 7 | 8 | var _status: int = WebSocketPeer.STATE_CONNECTING 9 | var _stream: WebSocketPeer = WebSocketPeer.new() 10 | 11 | func _ready() -> void: 12 | _status = _stream.get_ready_state() 13 | 14 | func _process(_delta: float) -> void: 15 | _stream.poll() 16 | var new_status: int = _stream.get_ready_state() 17 | if new_status != _status: 18 | _status = new_status 19 | match _status: 20 | _stream.STATE_CLOSED: 21 | print("Disconnected from host.") 22 | emit_signal("disconnected") 23 | _stream.STATE_CONNECTING: 24 | print("Connecting to host.") 25 | _stream.STATE_OPEN: 26 | print("Connected to host.") 27 | emit_signal("connected") 28 | _stream.STATE_CLOSING: 29 | print("Closing with socket stream.") 30 | emit_signal("error") 31 | 32 | if _status == _stream.STATE_OPEN: 33 | var available_packet_count: int = _stream.get_available_packet_count() 34 | if available_packet_count > 0: 35 | emit_signal("data", _stream.get_packet()) 36 | 37 | func connect_to_host(host: String, port: int) -> void: 38 | var url = "ws://%s:%d" % [host, port] 39 | print("Connecting to %s" % [url]) 40 | # Reset status so we can tell if it changes to error again. 41 | _status = _stream.STATE_CONNECTING 42 | if _stream.connect_to_url(url, false) != OK: 43 | print("Error connecting to host.") 44 | emit_signal("error") 45 | 46 | func send(dataToSend) -> bool: 47 | if _status != _stream.STATE_OPEN: 48 | print("Error: Stream is not currently connected.") 49 | return false 50 | var errorCode: int = _stream.send(dataToSend) 51 | if errorCode != OK: 52 | print("Error writing to stream: ", errorCode) 53 | return false 54 | return true 55 | -------------------------------------------------------------------------------- /examples/websocket/basic-ssl/client/networking.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | signal connected 4 | signal data 5 | signal disconnected 6 | signal error 7 | 8 | var _status: int = WebSocketPeer.STATE_CONNECTING 9 | var _stream: WebSocketPeer = WebSocketPeer.new() 10 | var _cert: X509Certificate = X509Certificate.new() 11 | 12 | func _ready() -> void: 13 | _status = _stream.get_ready_state() 14 | _cert.load('res://certs/x509.crt') 15 | 16 | func _process(_delta: float) -> void: 17 | _stream.poll() 18 | var new_status: int = _stream.get_ready_state() 19 | if new_status != _status: 20 | _status = new_status 21 | match _status: 22 | _stream.STATE_CLOSED: 23 | print("Disconnected from host.") 24 | emit_signal("disconnected") 25 | _stream.STATE_CONNECTING: 26 | print("Connecting to host.") 27 | _stream.STATE_OPEN: 28 | print("Connected to host.") 29 | emit_signal("connected") 30 | _stream.STATE_CLOSING: 31 | print("Closing with socket stream.") 32 | emit_signal("error") 33 | 34 | if _status == _stream.STATE_OPEN: 35 | var available_packet_count: int = _stream.get_available_packet_count() 36 | if available_packet_count > 0: 37 | emit_signal("data", _stream.get_packet()) 38 | 39 | func connect_to_host(host: String, port: int) -> void: 40 | var url = "wss://%s:%d" % [host, port] 41 | print("Connecting to %s" % [url]) 42 | # Reset status so we can tell if it changes to error again. 43 | _status = _stream.STATE_CONNECTING 44 | if _stream.connect_to_url(url, true, _cert) != OK: 45 | print("Error connecting to host.") 46 | emit_signal("error") 47 | 48 | func send(dataToSend) -> bool: 49 | if _status != _stream.STATE_OPEN: 50 | print("Error: Stream is not currently connected.") 51 | return false 52 | var errorCode: int = _stream.send(dataToSend) 53 | if errorCode != OK: 54 | print("Error writing to stream: ", errorCode) 55 | return false 56 | return true 57 | -------------------------------------------------------------------------------- /examples/tcp/basic-ssl/client/TCP.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | const HOST: String = "127.0.0.1" 4 | const PORT: int = 9090 5 | const RECONNECT_TIMEOUT: float = 3.0 6 | 7 | const Client = preload("res://networking.gd") 8 | var _client: Client = Client.new() 9 | 10 | var values = [ 11 | true,false, 12 | 1, -1, 500, -500, 13 | 1.2, -1.2, 50.1, -50.1, 80.852078542, 14 | "test1", "test2", "test3" 15 | ] 16 | 17 | func _ready() -> void: 18 | _client.connect("connected",Callable(self,"_handle_client_connected")) 19 | _client.connect("disconnected",Callable(self,"_handle_client_disconnected")) 20 | _client.connect("error",Callable(self,"_handle_client_error")) 21 | _client.connect("data",Callable(self,"_handle_client_data")) 22 | add_child(_client) 23 | _client.connect_to_host(HOST, PORT) 24 | 25 | func _connect_after_timeout(timeout: float) -> void: 26 | await get_tree().create_timer(timeout).timeout # Delay for timeout 27 | _client.connect_to_host(HOST, PORT) 28 | 29 | func _handle_client_connected() -> void: 30 | print("Client connected to server.") 31 | # send a first variant ! 32 | var bufferToSend = StreamPeerBuffer.new() 33 | bufferToSend.put_var(values.pop_front()) 34 | _client.send(bufferToSend.data_array) 35 | 36 | func _handle_client_data(data: PackedByteArray) -> void: 37 | var buffer = StreamPeerBuffer.new() 38 | buffer.data_array = data 39 | 40 | print("Client data: ", buffer.get_var()) 41 | 42 | if values.size() > 0 : 43 | var bufferToSend = StreamPeerBuffer.new() 44 | bufferToSend.put_var(values.pop_front()) 45 | _client.send(bufferToSend.data_array) 46 | 47 | func _handle_client_disconnected() -> void: 48 | print("Client disconnected from server.") 49 | _connect_after_timeout(RECONNECT_TIMEOUT) # Try to reconnect after 3 seconds 50 | 51 | func _handle_client_error() -> void: 52 | print("Client error.") 53 | _connect_after_timeout(RECONNECT_TIMEOUT) # Try to reconnect after 3 seconds 54 | -------------------------------------------------------------------------------- /examples/tcp/basic/client/TCP.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | const HOST: String = "127.0.0.1" 4 | const PORT: int = 9090 5 | const RECONNECT_TIMEOUT: float = 3.0 6 | 7 | const Client = preload("res://networking.gd") 8 | var _client: Client = Client.new() 9 | 10 | var values = [ 11 | true,false, 12 | 1, -1, 500, -500, 13 | 1.2, -1.2, 50.1, -50.1, 80.852078542, 14 | "test1", "test2", "test3" 15 | ] 16 | 17 | func _ready() -> void: 18 | _client.connect("connected",Callable(self,"_handle_client_connected")) 19 | _client.connect("disconnected",Callable(self,"_handle_client_disconnected")) 20 | _client.connect("error",Callable(self,"_handle_client_error")) 21 | _client.connect("data",Callable(self,"_handle_client_data")) 22 | add_child(_client) 23 | _client.connect_to_host(HOST, PORT) 24 | 25 | func _connect_after_timeout(timeout: float) -> void: 26 | await get_tree().create_timer(timeout).timeout # Delay for timeout 27 | _client.connect_to_host(HOST, PORT) 28 | 29 | func _handle_client_connected() -> void: 30 | print("Client connected to server.") 31 | 32 | # send a first variant ! 33 | var bufferToSend = StreamPeerBuffer.new() 34 | bufferToSend.put_var(values.pop_front()) 35 | _client.send(bufferToSend.data_array) 36 | 37 | func _handle_client_data(data: PackedByteArray) -> void: 38 | var buffer = StreamPeerBuffer.new() 39 | buffer.data_array = data 40 | 41 | print("Client receive : ", buffer.get_var()) 42 | 43 | if values.size() > 0 : 44 | var bufferToSend = StreamPeerBuffer.new() 45 | bufferToSend.put_var(values.pop_front()) 46 | _client.send(bufferToSend.data_array) 47 | 48 | func _handle_client_disconnected() -> void: 49 | print("Client disconnected from server.") 50 | _connect_after_timeout(RECONNECT_TIMEOUT) # Try to reconnect after 3 seconds 51 | 52 | func _handle_client_error() -> void: 53 | print("Client error.") 54 | _connect_after_timeout(RECONNECT_TIMEOUT) # Try to reconnect after 3 seconds 55 | -------------------------------------------------------------------------------- /examples/websocket/basic-ssl/client/WS.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | const HOST: String = "127.0.0.1" 4 | const PORT: int = 9090 5 | const RECONNECT_TIMEOUT: float = 3.0 6 | 7 | const Client = preload("res://networking.gd") 8 | var _client: Client = Client.new() 9 | 10 | var values = [ 11 | true,false, 12 | 1, -1, 500, -500, 13 | 1.2, -1.2, 50.1, -50.1, 80.852078542, 14 | "test1", "test2", "test3" 15 | ] 16 | 17 | func _ready() -> void: 18 | _client.connect("connected",Callable(self,"_handle_client_connected")) 19 | _client.connect("disconnected",Callable(self,"_handle_client_disconnected")) 20 | _client.connect("error",Callable(self,"_handle_client_error")) 21 | _client.connect("data",Callable(self,"_handle_client_data")) 22 | add_child(_client) 23 | _client.connect_to_host(HOST, PORT) 24 | 25 | func _connect_after_timeout(timeout: float) -> void: 26 | await get_tree().create_timer(timeout).timeout # Delay for timeout 27 | _client.connect_to_host(HOST, PORT) 28 | 29 | func _handle_client_connected() -> void: 30 | print("Client connected to server.") 31 | 32 | # send a first variant ! 33 | var bufferToSend = StreamPeerBuffer.new() 34 | bufferToSend.put_var(values.pop_front()) 35 | _client.send(bufferToSend.data_array) 36 | 37 | func _handle_client_data(data: PackedByteArray) -> void: 38 | var buffer = StreamPeerBuffer.new() 39 | buffer.data_array = data 40 | 41 | print("Client receive : ", buffer.get_var(), values.size()) 42 | 43 | if values.size() > 0 : 44 | var bufferToSend = StreamPeerBuffer.new() 45 | bufferToSend.put_var(values.pop_front()) 46 | _client.send(bufferToSend.data_array) 47 | 48 | func _handle_client_disconnected() -> void: 49 | print("Client disconnected from server.") 50 | _connect_after_timeout(RECONNECT_TIMEOUT) # Try to reconnect after 3 seconds 51 | 52 | func _handle_client_error() -> void: 53 | print("Client error.") 54 | _connect_after_timeout(RECONNECT_TIMEOUT) # Try to reconnect after 3 seconds 55 | -------------------------------------------------------------------------------- /examples/websocket/basic/client/WS.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | const HOST: String = "127.0.0.1" 4 | const PORT: int = 8080 5 | const RECONNECT_TIMEOUT: float = 3.0 6 | 7 | const Client = preload("res://networking.gd") 8 | var _client: Client = Client.new() 9 | 10 | var values = [ 11 | true,false, 12 | 1, -1, 500, -500, 13 | 1.2, -1.2, 50.1, -50.1, 80.852078542, 14 | "test1", "test2", "test3" 15 | ] 16 | 17 | func _ready() -> void: 18 | _client.connect("connected",Callable(self,"_handle_client_connected")) 19 | _client.connect("disconnected",Callable(self,"_handle_client_disconnected")) 20 | _client.connect("error",Callable(self,"_handle_client_error")) 21 | _client.connect("data",Callable(self,"_handle_client_data")) 22 | add_child(_client) 23 | _client.connect_to_host(HOST, PORT) 24 | 25 | func _connect_after_timeout(timeout: float) -> void: 26 | await get_tree().create_timer(timeout).timeout # Delay for timeout 27 | _client.connect_to_host(HOST, PORT) 28 | 29 | func _handle_client_connected() -> void: 30 | print("Client connected to server.") 31 | 32 | # send a first variant ! 33 | var bufferToSend = StreamPeerBuffer.new() 34 | bufferToSend.put_var(values.pop_front()) 35 | _client.send(bufferToSend.data_array) 36 | 37 | func _handle_client_data(data: PackedByteArray) -> void: 38 | var buffer = StreamPeerBuffer.new() 39 | buffer.data_array = data 40 | 41 | print("Client receive : ", buffer.get_var(), values.size()) 42 | 43 | if values.size() > 0 : 44 | var bufferToSend = StreamPeerBuffer.new() 45 | bufferToSend.put_var(values.pop_front()) 46 | _client.send(bufferToSend.data_array) 47 | 48 | func _handle_client_disconnected() -> void: 49 | print("Client disconnected from server.") 50 | _connect_after_timeout(RECONNECT_TIMEOUT) # Try to reconnect after 3 seconds 51 | 52 | func _handle_client_error() -> void: 53 | print("Client error.") 54 | _connect_after_timeout(RECONNECT_TIMEOUT) # Try to reconnect after 3 seconds 55 | -------------------------------------------------------------------------------- /examples/tcp/advanced/client/networking.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | signal connected 4 | signal data 5 | signal disconnected 6 | signal error 7 | 8 | var _status: int = 0 9 | var _stream: StreamPeerTCP = StreamPeerTCP.new() 10 | 11 | func _ready() -> void: 12 | _status = _stream.get_status() 13 | 14 | func _process(delta: float) -> void: 15 | _stream.poll() 16 | var new_status: int = _stream.get_status() 17 | if new_status != _status: 18 | _status = new_status 19 | match _status: 20 | _stream.STATUS_NONE: 21 | print("Disconnected from host.") 22 | emit_signal("disconnected") 23 | _stream.STATUS_CONNECTING: 24 | print("Connecting to host.") 25 | _stream.STATUS_CONNECTED: 26 | print("Connected to host.") 27 | emit_signal("connected") 28 | _stream.STATUS_ERROR: 29 | print("Error with socket stream.") 30 | emit_signal("error") 31 | 32 | if _status == _stream.STATUS_CONNECTED: 33 | var available_bytes: int = _stream.get_available_bytes() 34 | if available_bytes > 0: 35 | # print("available bytes: ", available_bytes) 36 | var data: Array = _stream.get_partial_data(available_bytes) 37 | # Check for read error. 38 | if data[0] != OK: 39 | print("Error getting data from stream: ", data[0]) 40 | emit_signal("error") 41 | else: 42 | emit_signal("data", data[1]) 43 | 44 | func connect_to_host(host: String, port: int) -> void: 45 | print("Connecting to %s:%d" % [host, port]) 46 | # Reset status so we can tell if it changes to error again. 47 | _status = _stream.STATUS_NONE 48 | if _stream.connect_to_host(host, port) != OK: 49 | print("Error connecting to host.") 50 | emit_signal("error") 51 | 52 | func send(data: PackedByteArray) -> bool: 53 | if _status != _stream.STATUS_CONNECTED: 54 | print("Error: Stream is not currently connected.") 55 | return false 56 | var error: int = _stream.put_data(data) 57 | if error != OK: 58 | print("Error writing to stream: ", error) 59 | return false 60 | return true 61 | -------------------------------------------------------------------------------- /examples/tcp/basic/client/networking.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | signal connected 4 | signal data 5 | signal disconnected 6 | signal error 7 | 8 | var _status: int = 0 9 | var _stream: StreamPeerTCP = StreamPeerTCP.new() 10 | 11 | func _ready() -> void: 12 | _status = _stream.get_status() 13 | 14 | func _process(delta: float) -> void: 15 | _stream.poll() 16 | var new_status: int = _stream.get_status() 17 | if new_status != _status: 18 | _status = new_status 19 | match _status: 20 | _stream.STATUS_NONE: 21 | print("Disconnected from host.") 22 | emit_signal("disconnected") 23 | _stream.STATUS_CONNECTING: 24 | print("Connecting to host.") 25 | _stream.STATUS_CONNECTED: 26 | print("Connected to host.") 27 | emit_signal("connected") 28 | _stream.STATUS_ERROR: 29 | print("Error with socket stream.") 30 | emit_signal("error") 31 | 32 | if _status == _stream.STATUS_CONNECTED: 33 | var available_bytes: int = _stream.get_available_bytes() 34 | if available_bytes > 0: 35 | # print("available bytes: ", available_bytes) 36 | var data: Array = _stream.get_partial_data(available_bytes) 37 | # Check for read error. 38 | if data[0] != OK: 39 | print("Error getting data from stream: ", data[0]) 40 | emit_signal("error") 41 | else: 42 | emit_signal("data", data[1]) 43 | 44 | func connect_to_host(host: String, port: int) -> void: 45 | print("Connecting to %s:%d" % [host, port]) 46 | # Reset status so we can tell if it changes to error again. 47 | _status = _stream.STATUS_NONE 48 | if _stream.connect_to_host(host, port) != OK: 49 | print("Error connecting to host.") 50 | emit_signal("error") 51 | 52 | func send(data: PackedByteArray) -> bool: 53 | if _status != _stream.STATUS_CONNECTED: 54 | print("Error: Stream is not currently connected.") 55 | return false 56 | var error: int = _stream.put_data(data) 57 | if error != OK: 58 | print("Error writing to stream: ", error) 59 | return false 60 | return true 61 | -------------------------------------------------------------------------------- /examples/tcp/advanced/client/TCP.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | const HOST: String = "127.0.0.1" 4 | const PORT: int = 9090 5 | const RECONNECT_TIMEOUT: float = 3.0 6 | 7 | const Client = preload("res://networking.gd") 8 | var _client: Client = Client.new() 9 | 10 | func _ready() -> void: 11 | _client.connect("connected",Callable(self,"_handle_client_connected")) 12 | _client.connect("disconnected",Callable(self,"_handle_client_disconnected")) 13 | _client.connect("error",Callable(self,"_handle_client_error")) 14 | _client.connect("data",Callable(self,"_handle_client_data")) 15 | add_child(_client) 16 | _client.connect_to_host(HOST, PORT) 17 | 18 | func _process(delta): 19 | if Input.is_action_just_released("ui_left"): 20 | var buffer = StreamPeerBuffer.new() 21 | buffer.put_u16(1001) 22 | buffer.put_string("COUCOU") 23 | _client.send(buffer.get_data_array()) 24 | 25 | if Input.is_action_just_released("ui_right"): 26 | var buffer = StreamPeerBuffer.new() 27 | buffer.put_u16(1002) 28 | _client.send(buffer.get_data_array()) 29 | 30 | func _connect_after_timeout(timeout: float) -> void: 31 | await get_tree().create_timer(timeout).timeout # Delay for timeout 32 | _client.connect_to_host(HOST, PORT) 33 | 34 | func _handle_client_connected() -> void: 35 | print("Client connected to server.") 36 | 37 | func _handle_client_data(data: PackedByteArray) -> void: 38 | var buffer = StreamPeerBuffer.new() 39 | buffer.data_array = data 40 | 41 | var type = buffer.get_u16() 42 | print('Recieve %s' % type) 43 | match type: 44 | 1: 45 | var length = buffer.get_u32() 46 | print("My id is %s !" % buffer.get_string(length)) 47 | 1003: 48 | print("We recieve OK_GO_LEFT !") 49 | 1004: 50 | print("We recieve OK_GO_RIGHT !") 51 | 52 | func _handle_client_disconnected() -> void: 53 | print("Client disconnected from server.") 54 | _connect_after_timeout(RECONNECT_TIMEOUT) # Try to reconnect after 3 seconds 55 | 56 | func _handle_client_error() -> void: 57 | print("Client error.") 58 | _connect_after_timeout(RECONNECT_TIMEOUT) # Try to reconnect after 3 seconds 59 | -------------------------------------------------------------------------------- /examples/websocket/advanced/client/WS.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | const HOST: String = "127.0.0.1" 4 | const PORT: int = 8080 5 | const RECONNECT_TIMEOUT: float = 3.0 6 | 7 | const Client = preload("res://networking.gd") 8 | var _client: Client = Client.new() 9 | 10 | func _ready() -> void: 11 | _client.connect("connected",Callable(self,"_handle_client_connected")) 12 | _client.connect("disconnected",Callable(self,"_handle_client_disconnected")) 13 | _client.connect("error",Callable(self,"_handle_client_error")) 14 | _client.connect("data",Callable(self,"_handle_client_data")) 15 | add_child(_client) 16 | _client.connect_to_host(HOST, PORT) 17 | 18 | func _connect_after_timeout(timeout: float) -> void: 19 | await get_tree().create_timer(timeout).timeout # Delay for timeout 20 | _client.connect_to_host(HOST, PORT) 21 | 22 | func _handle_client_connected() -> void: 23 | print("Client connected to server.") 24 | 25 | func _handle_client_data(data: PackedByteArray) -> void: 26 | var buffer = StreamPeerBuffer.new() 27 | buffer.data_array = data 28 | 29 | var type = buffer.get_u16() 30 | print('Recieve %s' % type) 31 | match type: 32 | 1: 33 | print("My id is %s !" % buffer.get_string()) 34 | 1003: 35 | print("We recieve OK_GO_LEFT !") 36 | 1004: 37 | print("We recieve OK_GO_RIGHT !") 38 | # extra data 39 | print("Recieve extra %s : " % buffer.get_string()) 40 | 41 | func _handle_client_disconnected() -> void: 42 | print("Client disconnected from server.") 43 | _connect_after_timeout(RECONNECT_TIMEOUT) # Try to reconnect after 3 seconds 44 | 45 | func _handle_client_error() -> void: 46 | print("Client error.") 47 | _connect_after_timeout(RECONNECT_TIMEOUT) # Try to reconnect after 3 seconds 48 | 49 | func _process(_delta): 50 | if Input.is_action_just_released("ui_left"): 51 | var buffer = StreamPeerBuffer.new() 52 | buffer.put_u16(1001) 53 | _client.send(buffer.get_data_array()) 54 | 55 | if Input.is_action_just_released("ui_right"): 56 | var buffer = StreamPeerBuffer.new() 57 | buffer.put_u16(1002) 58 | buffer.put_string('an extra parameter') 59 | _client.send(buffer.get_data_array()) 60 | -------------------------------------------------------------------------------- /examples/tcp/basic-ssl/client/networking.gd: -------------------------------------------------------------------------------- 1 | extends Node 2 | 3 | signal connected 4 | signal data 5 | signal disconnected 6 | signal error 7 | 8 | var _status: int = 0 9 | var _stream: StreamPeerTLS = StreamPeerTLS.new() 10 | var _cert: X509Certificate = X509Certificate.new() 11 | 12 | func _ready() -> void: 13 | _status = _stream.get_status() 14 | _cert.load('res://certs/x509.crt') 15 | 16 | func _process(_delta: float) -> void: 17 | var new_status: int = _stream.get_status() 18 | if new_status == _stream.STATUS_CONNECTED || new_status == _stream.STATUS_HANDSHAKING: 19 | _stream.poll() 20 | if new_status != _status: 21 | _status = new_status 22 | match _status: 23 | _stream.STATUS_DISCONNECTED: 24 | print("Disconnected from host.") 25 | emit_signal("disconnected") 26 | _stream.STATUS_HANDSHAKING: 27 | print("Performing SSL handshake with host.") 28 | _stream.STATUS_CONNECTED: 29 | print("Connected to host.") 30 | emit_signal("connected") 31 | _stream.STATUS_ERROR: 32 | print("Error with socket stream.") 33 | emit_signal("error") 34 | _stream.STATUS_ERROR_HOSTNAME_MISMATCH: 35 | print("Error with socket stream: Hostname mismatch.") 36 | emit_signal("error") 37 | 38 | if _status == _stream.STATUS_CONNECTED: 39 | var available_bytes: int = _stream.get_available_bytes() 40 | if available_bytes > 0: 41 | var dataToSend: Array = _stream.get_partial_data(available_bytes) 42 | # Check for read error. 43 | if dataToSend[0] != OK: 44 | print("Error getting data from stream: ", dataToSend[0]) 45 | emit_signal("error") 46 | else: 47 | emit_signal("data", dataToSend[1]) 48 | 49 | func connect_to_host(host: String, port: int) -> void: 50 | print("Connecting to %s:%d" % [host, port]) 51 | # Reset status so we can tell if it changes to error again. 52 | _status = _stream.STATUS_DISCONNECTED 53 | var tcp: StreamPeerTCP = StreamPeerTCP.new() 54 | var errorCode: int = tcp.connect_to_host(host, port) 55 | if errorCode != OK: 56 | print("Error connecting to host: ", errorCode) 57 | emit_signal("error") 58 | return 59 | 60 | errorCode = _stream.connect_to_stream(tcp, true, host, _cert) 61 | if errorCode != OK: 62 | print("Error upgrading connection to SSL: ", errorCode) 63 | 64 | func send(dataToSend) -> bool: 65 | if _status != _stream.STATUS_CONNECTED: 66 | print("Error: Stream is not currently connected.") 67 | return false 68 | var errorCode: int = _stream.put_data(dataToSend) 69 | if errorCode != OK: 70 | print("Error writing to stream: ", errorCode) 71 | return false 72 | return true 73 | -------------------------------------------------------------------------------- /src/get/get_var/index.ts: -------------------------------------------------------------------------------- 1 | import { getVarNull } from './null' 2 | import { getVarBool } from "./bool"; 3 | import {getVarInteger} from "./integer"; 4 | import {getVarFloat} from "./float"; 5 | import {getVarString} from "./string"; 6 | import {getVarVector2} from "./vector2"; 7 | import {getVarRect2} from "./rect2"; 8 | import {getVarVector3} from "./vector3"; 9 | import {getVarTransform2d} from "./transform2d"; 10 | import {getVarPlane} from "./plane"; 11 | import {getVarQuat} from "./quat"; 12 | import {getVarAABB} from "./aabb"; 13 | import {getVarBasis} from "./basis"; 14 | import {getVarTransform} from "./transform"; 15 | import {getVarColor} from "./color"; 16 | import {getVarNodePath} from "./nodePath"; 17 | import {getVarDictionnary} from "./dictionnary"; 18 | import {getVarArray} from "./array"; 19 | import {getVarRawArray} from "./rawArray"; 20 | import {getVarInt32Array} from "./int32Array"; 21 | import {getVarInt64Array} from "./int64Array"; 22 | import {getVarFloat32Array} from "./float32Array"; 23 | import {getVarFloat64Array} from "./float64Array"; 24 | import {getVarStringArray} from "./stringArray"; 25 | import {getVarVector2Array} from "./vector2Array"; 26 | import {getVarVector3Array} from "./vector3Array"; 27 | import {getVarColorArray} from "./colorArray"; 28 | import {IDecoderList, IGetReturn} from "../../types"; 29 | import { TYPE } from '../../constants' 30 | 31 | const decoderList: IDecoderList = { 32 | [TYPE.NULL]: getVarNull, 33 | [TYPE.BOOL]: getVarBool, 34 | [TYPE.INTEGER]: getVarInteger, 35 | [TYPE.FLOAT]: getVarFloat, 36 | [TYPE.STRING]: getVarString, 37 | [TYPE.VECTOR2]: getVarVector2, 38 | [TYPE.RECT2]: getVarRect2, 39 | [TYPE.VECTOR3]: getVarVector3, 40 | [TYPE.TRANSFORM2D]: getVarTransform2d, 41 | [TYPE.PLANE]: getVarPlane, 42 | [TYPE.QUAT]: getVarQuat, 43 | [TYPE.AABB]: getVarAABB, 44 | [TYPE.BASIS]: getVarBasis, 45 | [TYPE.TRANSFORM]: getVarTransform, 46 | [TYPE.COLOR]: getVarColor, 47 | [TYPE.NODE_PATH]: getVarNodePath, 48 | [TYPE.RID]: undefined, 49 | [TYPE.OBJECT]: undefined, 50 | [TYPE.DICTIONARY]: getVarDictionnary, 51 | [TYPE.ARRAY]: getVarArray, 52 | [TYPE.RAW_ARRAY]: getVarRawArray, 53 | [TYPE.INT_32_ARRAY]: getVarInt32Array, 54 | [TYPE.INT_64_ARRAY]: getVarInt64Array, 55 | [TYPE.FLOAT_32_ARRAY]: getVarFloat32Array, 56 | [TYPE.FLOAT_64_ARRAY]: getVarFloat64Array, 57 | [TYPE.STRING_ARRAY]: getVarStringArray, 58 | [TYPE.VECTOR2_ARRAY]: getVarVector2Array, 59 | [TYPE.VECTOR3_ARRAY]: getVarVector3Array, 60 | [TYPE.COLOR_ARRAY]: getVarColorArray, 61 | } 62 | 63 | function decode (buffer, offset = 0) { 64 | const type = buffer.readInt16LE(offset) 65 | const flag = buffer.readInt16LE(offset + 2) 66 | const data = buffer.slice(offset + 4) 67 | 68 | if (decoderList[type] == null) { 69 | throw new Error(`Decode buffer error: Invalid type ${type}`) 70 | } 71 | 72 | return decoderList[type](decode, data, flag) 73 | } 74 | 75 | /** 76 | * Decode Variant 77 | * @param buf {Buffer} 78 | * @returns {{value: *, length: Number}} 79 | */ 80 | export function getVar (buf: Buffer): IGetReturn { 81 | const data = decode(buf) 82 | return { value: data.value, length: data.length + 4 } // +4 cause we don't export type length 83 | } 84 | -------------------------------------------------------------------------------- /src/put/put_var/index.ts: -------------------------------------------------------------------------------- 1 | import {TYPE} from "../../constants"; 2 | import {putVarNull} from "./null"; 3 | import {putVarBool} from "./bool"; 4 | import {putVarInt} from "./integer"; 5 | import {putVarFloat} from "./float"; 6 | import {putVarString} from "./string"; 7 | import {putVarVector2} from "./vector2"; 8 | import {putVarRect2} from "./rect2"; 9 | import {putVarVector3} from "./vector3"; 10 | import {putVarAABB} from "./aabb"; 11 | import {putVarColor} from "./color"; 12 | import {putVarDictionnary} from "./dictionnary"; 13 | import {putVarArray} from "./array"; 14 | import {putVarRawArray} from "./rawArray"; 15 | import {putVarQuat} from "./quat"; 16 | import {putVarPlane} from "./plane"; 17 | import {IEncoderList} from "../../types"; 18 | 19 | const encoderList: IEncoderList = { 20 | [TYPE.NULL]: putVarNull, 21 | [TYPE.BOOL]: putVarBool, 22 | [TYPE.INTEGER]: putVarInt, 23 | [TYPE.FLOAT]: putVarFloat, 24 | [TYPE.STRING]: putVarString, 25 | [TYPE.VECTOR2]: putVarVector2, 26 | [TYPE.RECT2]: putVarRect2, 27 | [TYPE.VECTOR3]: putVarVector3, 28 | [TYPE.TRANSFORM2D]: undefined, 29 | [TYPE.PLANE]: putVarPlane, 30 | [TYPE.QUAT]: putVarQuat, 31 | [TYPE.AABB]: putVarAABB, 32 | [TYPE.BASIS]: undefined, 33 | [TYPE.TRANSFORM]: undefined, 34 | [TYPE.COLOR]: putVarColor, 35 | [TYPE.NODE_PATH]: undefined, 36 | [TYPE.RID]: undefined, 37 | [TYPE.OBJECT]: undefined, 38 | [TYPE.DICTIONARY]: putVarDictionnary, 39 | [TYPE.ARRAY]: putVarArray, 40 | [TYPE.RAW_ARRAY]: putVarRawArray, 41 | [TYPE.INT_32_ARRAY]: undefined, 42 | [TYPE.INT_64_ARRAY]: undefined, 43 | [TYPE.FLOAT_32_ARRAY]: undefined, 44 | [TYPE.FLOAT_64_ARRAY]: undefined, 45 | [TYPE.STRING_ARRAY]: undefined, 46 | [TYPE.VECTOR2_ARRAY]: undefined, 47 | [TYPE.VECTOR3_ARRAY]: undefined, 48 | [TYPE.COLOR_ARRAY]: undefined, 49 | } 50 | 51 | function getType (value: any) { 52 | if (value == null) { 53 | return TYPE.NULL 54 | } 55 | 56 | if (typeof value === "boolean") { 57 | return TYPE.BOOL 58 | } 59 | 60 | if (typeof value === "number") { 61 | if (Number.isInteger(value)) { 62 | return TYPE.INTEGER 63 | } 64 | return TYPE.FLOAT 65 | } 66 | 67 | if (typeof value === "string") { 68 | return TYPE.STRING 69 | } 70 | 71 | if (Array.isArray(value)) { 72 | return TYPE.ARRAY 73 | } 74 | 75 | if (typeof value === 'object') { 76 | if (value instanceof Buffer) { 77 | return TYPE.RAW_ARRAY 78 | } 79 | 80 | return TYPE.DICTIONARY 81 | } 82 | throw new Error(`You should specify type`) 83 | } 84 | 85 | function prepare (value, type?) { 86 | const typeCode = type || getType(value) 87 | const encoder = encoderList[`${typeCode}`] 88 | 89 | if (!encoder) { 90 | throw new Error(`Invalid value: no matching encoder found "${typeCode}"`) 91 | } 92 | 93 | return encoder(prepare, value) 94 | } 95 | 96 | /** 97 | * Encode Variant 98 | * By default it can Number, Array, Object, Null, String for complex type you need to pass the type 99 | * @param {*} value 100 | * @param {TYPE} type 101 | * @returns {*} 102 | */ 103 | export function putVar (value: any, type?: TYPE): Buffer { 104 | return prepare(value, type) 105 | } 106 | -------------------------------------------------------------------------------- /examples/udp/basic-dtls/server/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | 8 | ## Pull Request Process 9 | 10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a 11 | build. 12 | 2. Ensure tests is passed. 13 | 3. Update the README.md with details of changes to the interface, this includes new environment 14 | variables, exposed ports, useful file locations and container parameters. 15 | 4. Increase the version numbers in any files and the README.md to the new version that this 16 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). 17 | 5. You may merge the Pull Request in once you have the sign-off of two other developers, or if you 18 | do not have permission to do that, you may request the second reviewer to merge it for you. 19 | 20 | ## Code of Conduct 21 | 22 | ### Our Pledge 23 | 24 | In the interest of fostering an open and welcoming environment, we as 25 | contributors and maintainers pledge to making participation in our project and 26 | our community a harassment-free experience for everyone, regardless of age, body 27 | size, disability, ethnicity, gender identity and expression, level of experience, 28 | nationality, personal appearance, race, religion, or sexual identity and 29 | orientation. 30 | 31 | ### Our Standards 32 | 33 | Examples of behavior that contributes to creating a positive environment 34 | include: 35 | 36 | * Using welcoming and inclusive language 37 | * Being respectful of differing viewpoints and experiences 38 | * Gracefully accepting constructive criticism 39 | * Focusing on what is best for the community 40 | * Showing empathy towards other community members 41 | 42 | Examples of unacceptable behavior by participants include: 43 | 44 | * The use of sexualized language or imagery and unwelcome sexual attention or 45 | advances 46 | * Trolling, insulting/derogatory comments, and personal or political attacks 47 | * Public or private harassment 48 | * Publishing others' private information, such as a physical or electronic 49 | address, without explicit permission 50 | * Other conduct which could reasonably be considered inappropriate in a 51 | professional setting 52 | 53 | ### Our Responsibilities 54 | 55 | Project maintainers are responsible for clarifying the standards of acceptable 56 | behavior and are expected to take appropriate and fair corrective action in 57 | response to any instances of unacceptable behavior. 58 | 59 | Project maintainers have the right and responsibility to remove, edit, or 60 | reject comments, commits, code, wiki edits, issues, and other contributions 61 | that are not aligned to this Code of Conduct, or to ban temporarily or 62 | permanently any contributor for other behaviors that they deem inappropriate, 63 | threatening, offensive, or harmful. 64 | 65 | ### Scope 66 | 67 | This Code of Conduct applies both within project spaces and in public spaces 68 | when an individual is representing the project or its community. Examples of 69 | representing a project or community include using an official project e-mail 70 | address, posting via an official social media account, or acting as an appointed 71 | representative at an online or offline event. Representation of a project may be 72 | further defined and clarified by project maintainers. 73 | 74 | ### Enforcement 75 | 76 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 77 | reported by contacting the project team. All 78 | complaints will be reviewed and investigated and will result in a response that 79 | is deemed necessary and appropriate to the circumstances. The project team is 80 | obligated to maintain confidentiality with regard to the reporter of an incident. 81 | Further details of specific enforcement policies may be posted separately. 82 | 83 | Project maintainers who do not follow or enforce the Code of Conduct in good 84 | faith may face temporary or permanent repercussions as determined by other 85 | members of the project's leadership. 86 | 87 | ### Attribution 88 | 89 | This Code of Conduct is adapted from the Contributor Covenant, version 1.4, 90 | available at http://contributor-covenant.org/version/1/4 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![GM-Com](./img/logo.png) @gd-com/utils 2 | 3 | Binary serialization helper godot and nodejs ! 4 | 5 | Written with this [api](https://docs.godotengine.org/en/latest/tutorials/misc/binary_serialization_api.html) 6 | 7 | ## Requirements 8 | 9 | - Godot 4.0 or greater 10 | - NodeJS 16 LTS or greater 11 | 12 | For Godot 3 go *[@gd-com/utils v3](https://github.com/gd-com/utils/tree/v3)* 13 | 14 | ## How to install 15 | 16 | `npm install --save @gd-com/utils` 17 | 18 | ## Examples 19 | 20 | ### What is certs-generator ? 21 | This is a Godot project which is just used to generate SSL certificates to test TCP UDP and Websocket in "secure" mode 22 | 23 | ### Basic vs Advanced 24 | 25 | - **Basic** is a simple example who explain how to send variant 26 | - **Advanced** is a more complex example who explain how to send custom packets 27 | 28 | ## Available from gdCom 29 | 30 | ### Helpers 31 | 32 | | Method | Description | Return | 33 | |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------| 34 | | prefixWithLength(buffer) | Prefix the buffer passed in parameter by its size (required only for TCP) | Buffer | 35 | | StreamTcp | To optimize Godot send from time to time several packets in the same packet (only for TCP), to deserialize well it is necessary to use this | Class | 36 | 37 | 38 | ### Encode and Decode 39 | 40 | #### - getX 41 | | Method | Return | 42 | |-------------------------------|------------------------------| 43 | | getVar(buffer, offset = 0) | Object { value, length } | 44 | | get8(buffer, offset = 0) | Object { value, length } | 45 | | get16(buffer, offset = 0) | Object { value, length } | 46 | | get32(buffer, offset = 0) | Object { value, length } | 47 | | get64(buffer, offset = 0) | Object { value, length } | 48 | | getU8(buffer, offset = 0) | Object { value, length } | 49 | | getU16(buffer, offset = 0) | Object { value, length } | 50 | | getU32(buffer, offset = 0) | Object { value, length } | 51 | | getU64(buffer, offset = 0) | Object { value, length } | 52 | | getFloat(buffer, offset = 0) | Object { value, length } | 53 | | getDouble(buffer, offset = 0) | Object { value, length } | 54 | | getString(buffer, offset = 0) | Object { value, length } | 55 | 56 | #### - putX 57 | | Method | Return | 58 | |-------------------------------|------------------------------| 59 | | putVar(value, type) | Buffer | 60 | | put8(value) | Buffer | 61 | | put16(value) | Buffer | 62 | | put32(value) | Buffer | 63 | | put64(value) | Buffer | 64 | | putU8(value) | Buffer | 65 | | putU16(value) | Buffer | 66 | | putU32(value) | Buffer | 67 | | putU64(value) | Buffer | 68 | | putFloat(value) | Buffer | 69 | | putDouble(value) | Buffer | 70 | | putString(value) | Buffer | 71 | 72 | #### TYPE 73 | | Name | Value | 74 | |-------------------------------|------| 75 | | NULL | 0 | 76 | | BOOL | 1 | 77 | | INTEGER | 2 | 78 | | FLOAT | 3 | 79 | | STRING | 4 | 80 | | VECTOR2 | 5 | 81 | | RECT2 | 6 | 82 | | VECTOR3 | 7 | 83 | | TRANSFORM2D | 8 | 84 | | PLANE | 9 | 85 | | QUATERNION | 10 | 86 | | AABB | 11 | 87 | | BASIS | 12 | 88 | | TRANSFORM | 13 | 89 | | COLOR | 14 | 90 | | NODE_PATH | 15 | 91 | | RID // unsupported | 16 | 92 | | OBJECT // unsupported | 17 | 93 | | DICTIONARY | 18 | 94 | | ARRAY | 19 | 95 | | RAW_ARRAY | 20 | 96 | | INT_32_ARRAY | 21 | 97 | | INT_64_ARRAY | 22 | 98 | | FLOAT_32_ARRAY | 23 | 99 | | FLOAT_64_ARRAY | 24 | 100 | | STRING_ARRAY | 25 | 101 | | VECTOR2_ARRAY | 26 | 102 | | VECTOR3_ARRAY | 27 | 103 | | COLOR_ARRAY | 28 | 104 | | MAX | 29 | 105 | 106 | ## Test 107 | ``` 108 | git clone git@github.com:gd-com/utils.git gd-com-utils 109 | cd gd-com-utils 110 | npm install or yarn install 111 | npm run lint && npm run test 112 | ``` 113 | 114 | ## Contributing 115 | Please read [CONTRIBUTING](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us. 116 | 117 | ## TODO & CHANGELOG 118 | [CHANGELOG](CHANGELOG.md) 119 | [TODO](TODO.md) 120 | 121 | ## License 122 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details 123 | 124 | ## Thanks 125 | * Godot 126 | * Godot France 127 | * GDQuest 128 | * IG-Dev 129 | * **Salsa2k** for the [initial work](https://github.com/salsa2k/godotserver) 130 | -------------------------------------------------------------------------------- /img/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/data-01.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "_id": "5a0c662fd97addc9481a3724", 3 | "index": 0, 4 | "guid": "d3be92ce-dfa9-409a-b0f5-6435e6fc0cf4", 5 | "isActive": true, 6 | "balance": "$1,909.99", 7 | "picture": "http://placehold.it/32x32", 8 | "age": 39, 9 | "eyeColor": "brown", 10 | "name": "Luella Webb", 11 | "gender": "female", 12 | "company": "OPPORTECH", 13 | "email": "luellawebb@opportech.com", 14 | "phone": "+1 (833) 580-2061", 15 | "address": "198 Ruby Street, Oneida, Federated States Of Micronesia, 5150", 16 | "about": "Proident eu aliquip consequat cupidatat. Et et duis veniam anim adipisicing occaecat ipsum eiusmod proident do in proident. Culpa sit nisi id sint proident culpa est voluptate ex cupidatat Lorem ad mollit.\r\n", 17 | "registered": "2015-10-27T01:21:31 +04:00", 18 | "tags": [ 19 | "id", 20 | "consectetur", 21 | "do", 22 | "culpa", 23 | "eu", 24 | "culpa", 25 | "irure" 26 | ], 27 | "friends": [ 28 | { 29 | "id": 0, 30 | "name": "Aimee Watts" 31 | }, 32 | { 33 | "id": 1, 34 | "name": "Ann Mays" 35 | }, 36 | { 37 | "id": 2, 38 | "name": "Valerie Johnston" 39 | } 40 | ], 41 | "greeting": "Hello, Luella Webb! You have 4 unread messages.", 42 | "favoriteFruit": "strawberry" 43 | }, 44 | { 45 | "_id": "5a0c662fdec07be7e3033117", 46 | "index": 1, 47 | "guid": "9e722d32-0f76-4e6d-871f-4c43899a7070", 48 | "isActive": true, 49 | "balance": "$1,971.81", 50 | "picture": "http://placehold.it/32x32", 51 | "age": 40, 52 | "eyeColor": "blue", 53 | "name": "Susanna Battle", 54 | "gender": "female", 55 | "company": "ACCIDENCY", 56 | "email": "susannabattle@accidency.com", 57 | "phone": "+1 (973) 428-3275", 58 | "address": "276 Fleet Street, Dunlo, Marshall Islands, 4644", 59 | "about": "Veniam excepteur ullamco esse ullamco commodo consequat pariatur anim non incididunt aliqua minim tempor Lorem. Eiusmod nisi non sit cillum excepteur aliquip proident aute dolor nisi. Aliquip commodo duis fugiat excepteur nisi quis ipsum voluptate sit sint amet nostrud. Dolor commodo sint irure ad do labore do laborum laboris irure. Pariatur incididunt Lorem sunt veniam aute. Velit reprehenderit enim ullamco nostrud irure enim cillum ea proident.\r\n", 60 | "registered": "2017-06-04T12:07:24 +04:00", 61 | "tags": [ 62 | "Lorem", 63 | "ipsum", 64 | "reprehenderit", 65 | "eu", 66 | "eu", 67 | "enim", 68 | "anim" 69 | ], 70 | "friends": [ 71 | { 72 | "id": 0, 73 | "name": "Noreen Day" 74 | }, 75 | { 76 | "id": 1, 77 | "name": "Suzanne Nieves" 78 | }, 79 | { 80 | "id": 2, 81 | "name": "Erickson Fuller" 82 | } 83 | ], 84 | "greeting": "Hello, Susanna Battle! You have 8 unread messages.", 85 | "favoriteFruit": "banana" 86 | }, 87 | { 88 | "_id": "5a0c662fa0c54fd465552c66", 89 | "index": 2, 90 | "guid": "3dd17e8f-57f8-4ef9-9099-1c2435907355", 91 | "isActive": true, 92 | "balance": "$1,652.69", 93 | "picture": "http://placehold.it/32x32", 94 | "age": 30, 95 | "eyeColor": "green", 96 | "name": "Wendy Kennedy", 97 | "gender": "female", 98 | "company": "BYTREX", 99 | "email": "wendykennedy@bytrex.com", 100 | "phone": "+1 (843) 566-3373", 101 | "address": "395 Brightwater Court, Conway, Alabama, 4644", 102 | "about": "Duis anim sint ipsum deserunt sint ad. Nisi ullamco tempor est amet dolor. Cillum sit deserunt proident cillum reprehenderit dolore. Consectetur do magna non dolor.\r\n", 103 | "registered": "2015-07-05T11:06:28 +04:00", 104 | "tags": [ 105 | "excepteur", 106 | "quis", 107 | "enim", 108 | "aute", 109 | "officia", 110 | "excepteur", 111 | "nulla" 112 | ], 113 | "friends": [ 114 | { 115 | "id": 0, 116 | "name": "Clay Burt" 117 | }, 118 | { 119 | "id": 1, 120 | "name": "Elisabeth Palmer" 121 | }, 122 | { 123 | "id": 2, 124 | "name": "Lenora Kelley" 125 | } 126 | ], 127 | "greeting": "Hello, Wendy Kennedy! You have 9 unread messages.", 128 | "favoriteFruit": "strawberry" 129 | }, 130 | { 131 | "_id": "5a0c662f8f17470fe92d3433", 132 | "index": 3, 133 | "guid": "b1409360-9f60-460a-9dc8-d1de258e97c9", 134 | "isActive": true, 135 | "balance": "$1,939.87", 136 | "picture": "http://placehold.it/32x32", 137 | "age": 37, 138 | "eyeColor": "green", 139 | "name": "Alana Wilkins", 140 | "gender": "female", 141 | "company": "DIGIAL", 142 | "email": "alanawilkins@digial.com", 143 | "phone": "+1 (982) 536-3614", 144 | "address": "548 Alabama Avenue, Clinton, North Carolina, 7557", 145 | "about": "Dolore anim eiusmod aliqua excepteur fugiat est ipsum cillum consectetur non amet culpa ipsum eiusmod. Do pariatur voluptate in cupidatat mollit. Ad nostrud aliquip dolore cillum cupidatat est quis. Consectetur sint deserunt magna exercitation mollit deserunt amet. Cillum Lorem irure aute dolor eu ea culpa enim.\r\n", 146 | "registered": "2016-11-18T12:05:42 +05:00", 147 | "tags": [ 148 | "aute", 149 | "proident", 150 | "pariatur", 151 | "mollit", 152 | "fugiat", 153 | "nisi", 154 | "excepteur" 155 | ], 156 | "friends": [ 157 | { 158 | "id": 0, 159 | "name": "Darlene Carr" 160 | }, 161 | { 162 | "id": 1, 163 | "name": "Sandy Good" 164 | }, 165 | { 166 | "id": 2, 167 | "name": "Rice Wiley" 168 | } 169 | ], 170 | "greeting": "Hello, Alana Wilkins! You have 3 unread messages.", 171 | "favoriteFruit": "strawberry" 172 | }, 173 | { 174 | "_id": "5a0c662f0a677c8e6c350a7d", 175 | "index": 4, 176 | "guid": "04732bb8-59da-4934-b6c3-32120257ff2f", 177 | "isActive": false, 178 | "balance": "$2,064.16", 179 | "picture": "http://placehold.it/32x32", 180 | "age": 27, 181 | "eyeColor": "blue", 182 | "name": "Glover Daniel", 183 | "gender": "male", 184 | "company": "DIGITALUS", 185 | "email": "gloverdaniel@digitalus.com", 186 | "phone": "+1 (862) 513-3037", 187 | "address": "547 Highland Place, Canterwood, Palau, 3213", 188 | "about": "Ullamco aute officia culpa pariatur. Dolor ipsum anim laboris commodo commodo adipisicing et. Id anim magna anim laborum deserunt duis. Aliquip eu ad reprehenderit in consectetur veniam nostrud dolore culpa.\r\n", 189 | "registered": "2014-01-04T12:19:28 +05:00", 190 | "tags": [ 191 | "reprehenderit", 192 | "commodo", 193 | "commodo", 194 | "dolor", 195 | "cillum", 196 | "nisi", 197 | "cupidatat" 198 | ], 199 | "friends": [ 200 | { 201 | "id": 0, 202 | "name": "Johnston Elliott" 203 | }, 204 | { 205 | "id": 1, 206 | "name": "Erica Cooley" 207 | }, 208 | { 209 | "id": 2, 210 | "name": "Ramos Fry" 211 | } 212 | ], 213 | "greeting": "Hello, Glover Daniel! You have 6 unread messages.", 214 | "favoriteFruit": "apple" 215 | }, 216 | { 217 | "_id": "5a0c662feb6ae6ed16550877", 218 | "index": 5, 219 | "guid": "1d87caf5-49b9-4516-944c-8bd6d873e265", 220 | "isActive": true, 221 | "balance": "$2,457.47", 222 | "picture": "http://placehold.it/32x32", 223 | "age": 21, 224 | "eyeColor": "brown", 225 | "name": "Mcguire Kaufman", 226 | "gender": "male", 227 | "company": "SIGNITY", 228 | "email": "mcguirekaufman@signity.com", 229 | "phone": "+1 (983) 490-3186", 230 | "address": "450 Irving Street, Hamilton, Texas, 1721", 231 | "about": "Irure dolore deserunt laboris ullamco exercitation nisi consectetur eiusmod. Do id nulla laborum voluptate veniam ex pariatur nostrud sint. Ullamco dolore ut aliqua velit. Qui et id cillum ipsum laborum cillum nulla officia labore consequat nisi laborum tempor. Id nulla consectetur sunt in aute aute do.\r\n", 232 | "registered": "2015-07-28T07:58:22 +04:00", 233 | "tags": [ 234 | "adipisicing", 235 | "ex", 236 | "cillum", 237 | "quis", 238 | "aliqua", 239 | "pariatur", 240 | "magna" 241 | ], 242 | "friends": [ 243 | { 244 | "id": 0, 245 | "name": "Blake Simmons" 246 | }, 247 | { 248 | "id": 1, 249 | "name": "Lea Santana" 250 | }, 251 | { 252 | "id": 2, 253 | "name": "Geneva Neal" 254 | } 255 | ], 256 | "greeting": "Hello, Mcguire Kaufman! You have 6 unread messages.", 257 | "favoriteFruit": "apple" 258 | }, 259 | { 260 | "_id": "5a0c662f7f764391b99c9f4c", 261 | "index": 6, 262 | "guid": "de906c86-a44e-4762-a7f9-b256d0bbd699", 263 | "isActive": false, 264 | "balance": "$2,415.11", 265 | "picture": "http://placehold.it/32x32", 266 | "age": 32, 267 | "eyeColor": "brown", 268 | "name": "Parks Acevedo", 269 | "gender": "male", 270 | "company": "BUZZMAKER", 271 | "email": "parksacevedo@buzzmaker.com", 272 | "phone": "+1 (810) 596-3177", 273 | "address": "364 Cambridge Place, Graball, Tennessee, 4925", 274 | "about": "Veniam eu ut minim id ullamco aute mollit sit laborum ex amet. Ea tempor non velit dolore et tempor excepteur mollit ullamco. Esse sit proident excepteur eiusmod velit enim aliqua mollit aliquip deserunt eiusmod. Magna sit ea sint dolor ullamco incididunt. Anim cupidatat pariatur Lorem quis excepteur consectetur minim ad officia labore ex anim.\r\n", 275 | "registered": "2016-10-01T12:57:09 +04:00", 276 | "tags": [ 277 | "officia", 278 | "eu", 279 | "amet", 280 | "eiusmod", 281 | "reprehenderit", 282 | "voluptate", 283 | "amet" 284 | ], 285 | "friends": [ 286 | { 287 | "id": 0, 288 | "name": "Karla Luna" 289 | }, 290 | { 291 | "id": 1, 292 | "name": "Randi Carney" 293 | }, 294 | { 295 | "id": 2, 296 | "name": "Lyons Curtis" 297 | } 298 | ], 299 | "greeting": "Hello, Parks Acevedo! You have 8 unread messages.", 300 | "favoriteFruit": "banana" 301 | }] --------------------------------------------------------------------------------