├── .gitignore
├── .travis.yml
├── Changelog.md
├── EVENTS.md
├── Gruntfile.js
├── LICENSE
├── README.md
├── examples
├── .gitignore
├── bin
│ ├── crypto-example.js
│ ├── dns-example.js
│ ├── file-transfer-example.js
│ ├── old-groupchats-sync-example.js
│ ├── old
│ │ ├── promises-example.js
│ │ └── sync-example.js
│ ├── packet-simulation.js
│ ├── promises-example.js
│ └── sync-example.js
└── package.json
├── lib
├── consts.js
├── errors.js
├── events.js
├── main.js
├── old
│ ├── consts.js
│ ├── errors.js
│ ├── events.js
│ ├── main.js
│ ├── sync.js
│ ├── tox.js
│ ├── toxav.js
│ ├── toxdns.js
│ ├── toxencryptsave.js
│ └── util.js
├── tox.js
├── tox_old.js
├── toxdns.js
├── toxencryptsave.js
├── toxerror.js
├── toxoptions.js
└── util.js
├── package.json
├── test
├── non-ci
│ └── toxdns.js
├── tox.js
├── toxdns.js
├── toxencryptsave.js
└── util.js
└── typings
└── toxcore.d.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore doc/ directory until more up-to-date
2 | doc/
3 |
4 | node_modules/
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "0.10"
4 | - "0.12"
5 | - "1"
6 | - "2"
7 | - "3.2"
8 | - "4"
9 | # io.js v3+ requires C++11
10 | before_install:
11 | - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
12 | - sudo apt-get update -qq
13 | - sudo apt-get install -qq g++-4.8
14 | - export CXX="g++-4.8"
15 | # This is basically copied from toxcore's .travis.yml, without libcheck
16 | # Unsure of a better way of getting toxcore+deps installed
17 | before_script:
18 | #installing libsodium, needed for Core
19 | - git clone git://github.com/jedisct1/libsodium.git > /dev/null
20 | - cd libsodium
21 | - git checkout tags/1.0.3 > /dev/null
22 | - ./autogen.sh > /dev/null
23 | - ./configure > /dev/null
24 | - make check -j3 > /dev/null
25 | - sudo make install >/dev/null
26 | - cd ..
27 | #installing yasm, needed for compiling vpx
28 | - sudo apt-get install yasm > /dev/null
29 | #installing libconfig, needed for DHT_bootstrap_daemon
30 | - wget http://www.hyperrealm.com/libconfig/libconfig-1.4.9.tar.gz > /dev/null
31 | - tar -xvzf libconfig-1.4.9.tar.gz > /dev/null
32 | - cd libconfig-1.4.9
33 | - ./configure > /dev/null
34 | - make -j3 > /dev/null
35 | - sudo make install > /dev/null
36 | - cd ..
37 | #installing libopus, needed for audio encoding/decoding
38 | - wget http://downloads.xiph.org/releases/opus/opus-1.1.tar.gz > /dev/null
39 | - tar xzf opus-1.1.tar.gz > /dev/null
40 | - cd opus-1.1
41 | - ./configure > /dev/null
42 | - make -j3 > /dev/null
43 | - sudo make install > /dev/null
44 | - cd ..
45 | #installing vpx
46 | - git clone https://chromium.googlesource.com/webm/libvpx.git > /dev/null
47 | - cd libvpx
48 | - git checkout tags/v1.3.0
49 | - ./configure --enable-shared > /dev/null
50 | - make -j3 >/dev/null
51 | - sudo make install > /dev/null
52 | - cd ..
53 | #creating libraries links and updating cache
54 | - sudo ldconfig > /dev/null
55 | #installing check, needed for unit tests
56 | #- sudo apt-get install check > /dev/null
57 | #build/install toxcore
58 | - git clone https://github.com/irungentoo/toxcore.git
59 | - cd toxcore
60 | - autoreconf -i
61 | - CFLAGS="-Ofast -Wall -Wextra" ./configure --enable-daemon --enable-ntox
62 | - make -j3
63 | #- make check
64 | #- make dist
65 | - sudo make install > /dev/null
66 | - cd ..
67 | #re-update cache
68 | - sudo ldconfig > /dev/null
69 |
--------------------------------------------------------------------------------
/Changelog.md:
--------------------------------------------------------------------------------
1 | Changelog
2 | =========
3 |
4 | v1.3.0
5 | ------
6 | - Added ToxDns for libtoxdns.
7 | - Updated dependencies to support node.js v4.
8 |
9 | v1.2.0
10 | ------
11 | - Added ToxEncryptSave for libtoxencryptsave.
12 |
13 | v1.1.4
14 | ------
15 | - Added lossless/lossy packet functionality (credits: [OguzhanE]).
16 | - Use ToxError for errors (credits: [OguzhanE]).
17 |
18 | v1.1.3
19 | ------
20 | - Fixed assert error that occurred when inspecting a Tox object.
21 |
22 | v1.1.2
23 | ------
24 | - Fixed Tox#sendFriendMessageSync() to return message Id (credits: [mensinda]).
25 |
26 | v1.1.1
27 | ------
28 | - Update for toxcore api change ([8e80ced](https://github.com/irungentoo/toxcore/commit/8e80ced)).
29 | - Fixed Tox#getOptions() when proxy_address is NULL.
30 |
31 | v1.1.0
32 | ------
33 | - Added functions, events and consts related to transferring files.
34 | - Added hashing functions Tox#hash(), Tox#hashSync().
35 |
36 | v1.0.2
37 | ------
38 | - Added Tox.load() for asynchronously creating a Tox object.
39 | - Added 'data' option for Tox construction, which specifies the data to load
40 | as either a Buffer or a filepath (string). If given a filepath, this will
41 | read the file synchronously if (new Tox()) is used, and asynchronously if
42 | Tox.load() is used.
43 | - Added Tox#saveToFile(), Tox#saveToFileSync() for saving state to a file.
44 |
45 | v1.0.1
46 | ------
47 | - Updated typescript definitions file.
48 |
49 | v1.0.0
50 | ------
51 | - Dropped support for old api in support of new api.
52 | - toxcore and tox_old (old groupchats) implemented for the most part, except
53 | for file transfer functions (may have missed a few other functions).
54 |
55 | [Arvius]:https://github.com/Arvius
56 | [mensinda]:https://github.com/mensinda
57 | [OguzhanE]:https://github.com/OguzhanE
58 |
--------------------------------------------------------------------------------
/EVENTS.md:
--------------------------------------------------------------------------------
1 | Events
2 | ======
3 |
4 | This file presents the events emitted by instances of Tox objects. They can be
5 | listened for by using `on`, for example: `tox.on('eventName', function(e) { ... });`
6 |
7 | For each event, one event object is passed to the callback function. These event
8 | objects are specified in `lib/events.js`, and have accessor methods for retrieving
9 | information, such as `var friendNumber = e.friend();`
10 |
11 | Tox
12 | ---
13 |
14 | Name | Event object name | Description
15 | ---------------------- | :-------------------------: | ---------------------------------------------------------
16 | fileRecvControl | FileRecvControlEvent | Emitted when a file control is received.
17 | fileChunkRequest | FileChunkRequestEvent | Emitted when a chunk of a file has been requested.
18 | fileRecv | FileRecvEvent | Emitted when someone requests to send a file.
19 | fileRecvChunk | FileRecvChunkEvent | Emitted when a chunk is received during a file transfer.
20 | friendConnectionStatus | FriendConnectionStatusEvent | Emitted when a friend's connection status has changed.
21 | friendMessage | FriendMessageEvent | Emitted when a friend message is received.
22 | friendName | FriendNameEvent | Emitted when a friend's name has changed.
23 | friendReadReceipt | FriendReadReceiptEvent | Emitted when a friend receipt is received.
24 | friendRequest | FriendRequestEvent | Emitted when a friend request is received.
25 | friendStatus | FriendStatusEvent | Emitted when a friend's status has changed.
26 | friendStatusMessage | FriendStatusMessageEvent | Emitted when a friend's status message has changed.
27 | friendTyping | FriendTypingEvent | Emitted when a friend's typing status has changed.
28 | selfConnectionStatus | SelfConnectionStatusEvent | Emitted when our connection status has changed.
29 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 | grunt.initConfig({
3 | shell: {
4 | mocha: {
5 | command: 'mocha --recursive'
6 | }
7 | },
8 | jsdoc: {
9 | dist: {
10 | src: [
11 | 'lib/events.js',
12 | 'lib/tox.js',
13 | 'lib/toxdns.js',
14 | 'lib/toxencryptsave.js',
15 | 'lib/toxoptions.js',
16 | 'lib/tox_old.js'
17 | ],
18 | options: {
19 | destination: 'doc',
20 | private: false,
21 | template : 'node_modules/ink-docstrap/template',
22 | configure : 'node_modules/ink-docstrap/template/jsdoc.conf.json'
23 | }
24 | }
25 | }
26 | });
27 |
28 | grunt.loadNpmTasks('grunt-jsdoc');
29 | grunt.loadNpmTasks('grunt-shell');
30 |
31 | grunt.registerTask('default', ['jsdoc']);
32 | grunt.registerTask('doc', ['jsdoc']);
33 | grunt.registerTask('test', ['shell']);
34 | };
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | node-toxcore [](http://travis-ci.org/saneki/node-toxcore) [](https://www.npmjs.org/package/toxcore) [](https://david-dm.org/saneki/node-toxcore)
2 | ============
3 |
4 | [](https://nodei.co/npm/toxcore/)
5 |
6 | Node.js bindings for [libtoxcore], built off of [node-ffi].
7 |
8 | Note: Installing this package does not install [libtoxcore]. It is expected
9 | that [libtoxcore] is installed prior to using **node-toxcore**.
10 |
11 |
12 | ### New API Progress
13 |
14 | - [x] toxcore
15 | - [ ] toxav
16 | - [x] toxdns
17 | - [x] toxencryptsave
18 | - [x] tox_old.h (old groupchats)
19 | - [ ] Higher level API
20 |
21 |
22 | ### Synchronous Example
23 |
24 | ``` js
25 | var toxcore = require('toxcore');
26 |
27 | // Create a default Tox instance
28 | var tox = new toxcore.Tox();
29 |
30 | // ... or, create a Tox instance using specific paths for toxcore libraries
31 | var toxAtPath = new toxcore.Tox({
32 | path: '/path/to/libtoxcore.so',
33 | crypto: '/path/to/libtoxencryptsave.so'
34 | });
35 |
36 | // ... or, give Tox some data to load
37 | var toxWithData = new toxcore.Tox({
38 | data: '/path/to/toxfile'
39 | });
40 |
41 | // ... if that data is encrypted, include a passphrase
42 | var toxWithEncData = new toxcore.Tox({
43 | data: '/path/to/encrypted/toxfile',
44 | pass: 'myPassphrase'
45 | });
46 |
47 | // Bootstrap from nodes (see a list at: https://wiki.tox.chat/users/nodes)
48 | tox.bootstrapSync('23.226.230.47', 33445, 'A09162D68618E742FFBCA1C2C70385E6679604B2D80EA6E84AD0996A1AC8A074'); // stal
49 | tox.bootstrapSync('104.219.184.206', 443, '8CD087E31C67568103E8C2A28653337E90E6B8EDA0D765D57C6B5172B4F1F04C'); // Jfreegman
50 |
51 | // Set your name and status message
52 | tox.setNameSync('My username');
53 | tox.setStatusMessageSync('Hello world!');
54 |
55 | // Listen for friend requests
56 | tox.on('friendRequest', function(e) {
57 | console.log('Friend request from: ' + e.publicKeyHex());
58 | });
59 |
60 | // Print received friend messages to console
61 | tox.on('friendMessage', function(e) {
62 | var friendName = tox.getFriendNameSync(e.friend());
63 | console.log(friendName + ': ' + e.message());
64 | });
65 |
66 | // Print out your tox address so others can add it
67 | console.log('Address: ' + tox.getAddressHexSync());
68 |
69 | // Start!
70 | tox.start();
71 | ```
72 |
73 | For more examples, see the `examples/` directory.
74 |
75 |
76 | ### Documentation
77 |
78 | Generating the documentation should be as easy as `grunt jsdoc`.
79 |
80 |
81 | [libtoxcore]:https://github.com/irungentoo/toxcore
82 | [node-ffi]:https://github.com/node-ffi/node-ffi
83 |
--------------------------------------------------------------------------------
/examples/.gitignore:
--------------------------------------------------------------------------------
1 | tmp/
2 |
--------------------------------------------------------------------------------
/examples/bin/crypto-example.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var fs = require('fs');
20 | var toxcore = require('toxcore');
21 |
22 | var crypto = new toxcore.ToxEncryptSave();
23 | var passphrase = 'helloWorld';
24 |
25 | /**
26 | * Encrypt some data at write it to a file.
27 | * @param {String} filepath - Path of file to write to
28 | * @param {Buffer} data - Data to encrypt and write
29 | */
30 | var encrypt = function(filepath, data) {
31 | crypto.encryptFile(filepath, data, passphrase, function(err) {
32 | if (!err) {
33 | console.log('Successfully encrypted file!');
34 | } else {
35 | console.error('Unable to encrypt file', err);
36 | }
37 | });
38 | };
39 |
40 | /**
41 | * Decrypt some data and write it to a file.
42 | * @param {String} filepath - Path of file to write to
43 | * @param {Buffer} data - Data to decrypt and write
44 | */
45 | var decrypt = function(filepath, data) {
46 | crypto.decrypt(data, passphrase, function(err, ddata) {
47 | if (!err) {
48 | fs.writeFile(filepath, ddata, function(err) {
49 | if (!err) {
50 | console.log('Successfully decrypted file!');
51 | } else {
52 | console.error('Unable to write decrypted data to the file', err);
53 | }
54 | });
55 | } else {
56 | console.error('Unable to decrypt data with passphrase', err);
57 | }
58 | });
59 | };
60 |
61 | /**
62 | * Given a file, encrypt it (if not yet encrypted) or decrypt it
63 | * (if already encrypted).
64 | * @param {String} filepath - Path of file
65 | */
66 | var performCrypto = function(filepath) {
67 | fs.readFile(filepath, function(err, data) {
68 | if (!err) {
69 | crypto.isDataEncrypted(data, function(err, isEncrypted) {
70 | if (!err) {
71 | if (isEncrypted) {
72 | decrypt(filepath, data);
73 | } else {
74 | encrypt(filepath, data);
75 | }
76 | } else {
77 | console.error('Unable to determine if data is encrypted', err);
78 | }
79 | });
80 | } else {
81 | console.error('Unable to read input file', err);
82 | }
83 | });
84 | };
85 |
86 | var args = process.argv.slice(2);
87 | if (args.length > 0) {
88 | var filepath = args[0];
89 | performCrypto(filepath);
90 | } else {
91 | console.error('usage: node crypto-example.js ');
92 | }
93 |
--------------------------------------------------------------------------------
/examples/bin/dns-example.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var toxcore = require('toxcore');
20 |
21 | var clients = {
22 | 'toxme.io': undefined // toxme.io is the default if no key provided
23 | };
24 |
25 | // Create clients
26 | Object.keys(clients).map(function(value, index) {
27 | clients[value] = new toxcore.ToxDns({ key: clients[value] });
28 | });
29 |
30 | /**
31 | * Gets the domain of a ToxDns address.
32 | * @param {String} dnsaddr - Address (ex. 'user@toxme.io')
33 | * @return {String} domain name, or undefined if none (bad address format)
34 | */
35 | var getAddressDomain = function(dnsaddr) {
36 | var split = dnsaddr.split('@');
37 | if(split.length === 2)
38 | return split[1];
39 | };
40 |
41 | /**
42 | * Get the ToxDns client for a specific address.
43 | * @param {String} dnsaddr - Address (ex. 'user@toxme.io')
44 | * @return {ToxDns} client to use for the given address, or undefined if none
45 | * for the address domain
46 | */
47 | var getClientForAddress = function(dnsaddr) {
48 | var domain = getAddressDomain(dnsaddr);
49 | if(domain !== undefined && clients[domain] !== undefined)
50 | return clients[domain];
51 | };
52 |
53 | // Resolve each ToxDns in argv and output the results
54 | process.argv.slice(2).forEach(function(dnsaddr) {
55 | var client = getClientForAddress(dnsaddr);
56 | client.resolveHex(dnsaddr, function(err, addr) {
57 | if(!err) {
58 | console.log('%s: %s', dnsaddr, addr);
59 | } else {
60 | console.log('%s: Error occurred: %s', dnsaddr, err);
61 | }
62 | });
63 | });
64 |
--------------------------------------------------------------------------------
/examples/bin/file-transfer-example.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | /**
20 | * A tiny tox file transfer example using node-toxcore's file transfer methods.
21 | */
22 |
23 | var fs = require('fs-ext');
24 | var path = require('path');
25 | var mkdirp = require('mkdirp');
26 | var toxcore = require('toxcore');
27 | var util = require('util');
28 | var tox = new toxcore.Tox();
29 | var consts = toxcore.Consts;
30 |
31 | // Map of files: file_number => file_descriptor
32 | var files = {};
33 |
34 | var uploadPath = path.normalize(path.join(__dirname, '..', 'tmp'));
35 |
36 | var sendPath = 'file.txt'; // Test file to send
37 | var sendSize = 0;
38 | var sendFile = undefined; // Opened file
39 |
40 | try {
41 | sendFile = fs.openSync(sendPath, 'r');
42 | var stat = fs.statSync(sendPath);
43 | sendSize = stat.size;
44 | console.log('Initialized file to send (path=%s, size=%d)', sendPath, sendSize);
45 | } catch(e) {
46 | console.error(e);
47 | }
48 |
49 | var CANCEL = consts.TOX_FILE_CONTROL_CANCEL,
50 | PAUSE = consts.TOX_FILE_CONTROL_PAUSE,
51 | RESUME = consts.TOX_FILE_CONTROL_RESUME;
52 |
53 | var DATA = consts.TOX_FILE_KIND_DATA,
54 | AVATAR = consts.TOX_FILE_KIND_AVATAR;
55 |
56 | var SEEK_SET = 0,
57 | SEEK_CUR = 1,
58 | SEEK_END = 2;
59 |
60 | /**
61 | * Fix a filename by replacing all path separators with _.
62 | * @param {String} filename - Filename to fix
63 | * @return {String} Fixed filename
64 | */
65 | var fixRecvFilename = function(filename) {
66 | ['/', '\\'].forEach(function(r) {
67 | filename = filename.replace(r, '_');
68 | });
69 | return filename;
70 | };
71 |
72 | /**
73 | * Bootstrap tox via hardcoded nodes.
74 | * For more nodes, see: https://wiki.tox.chat/users/nodes
75 | */
76 | var nodes = [
77 | { maintainer: 'saneki',
78 | address: '96.31.85.154',
79 | port: 33445,
80 | key: '674153CF49616CD1C4ADF44B004686FC1F6C9DCDD048EF89B117B3F02AA0B778' },
81 | { maintainer: 'Impyy',
82 | address: '178.62.250.138',
83 | port: 33445,
84 | key: '788236D34978D1D5BD822F0A5BEBD2C53C64CC31CD3149350EE27D4D9A2F9B6B' },
85 | { maintainer: 'sonOfRa',
86 | address: '144.76.60.215',
87 | port: 33445,
88 | key: '04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F' }
89 | ];
90 |
91 | // Bootstrap from nodes
92 | nodes.forEach(function(node) {
93 | tox.bootstrapSync(node.address, node.port, node.key);
94 | console.log('Successfully bootstrapped from ' + node.maintainer + ' at ' + node.address + ':' + node.port);
95 | console.log('... with key ' + node.key);
96 | });
97 |
98 | // Auto-accept friend requests
99 | tox.on('friendRequest', function(e) {
100 | tox.addFriendNoRequestSync(e.publicKey());
101 | });
102 |
103 | tox.on('friendMessage', function(e) {
104 | console.log('Received message (friend=%d, message=%s)', e.friend(), e.message());
105 | if(/^send$/i.test(e.message())) {
106 | if(sendFile !== undefined) {
107 | console.log('Beginning send (friend=%d)', e.friend());
108 | tox.sendFileSync(e.friend(), DATA, sendPath, sendSize);
109 | }
110 | }
111 | });
112 |
113 | tox.on('fileRecvControl', function(e) {
114 | console.log('Received file control from %d: %s',
115 | e.friend(),
116 | e.controlName());
117 |
118 | // If cancel, release resources (close file)
119 | if(e.isCancel()) {
120 | var fd = files[e.file()];
121 | if(descriptor !== undefined) {
122 | fs.closeSync(fd);
123 | files[e.file()] = undefined;
124 | }
125 | }
126 | });
127 |
128 | tox.on('fileChunkRequest', function(e) {
129 | if(sendFile) {
130 | var data = new Buffer(e.length()),
131 | bytesRead = 0;
132 |
133 | try {
134 | bytesRead = fs.readSync(sendFile, data, 0, data.length, e.position());
135 | } catch(err) {
136 | // Expected: Out of bounds error
137 | console.log('Position out-of-bounds, sending nothing (friend=%d)', e.friend());
138 | //tox.sendFileChunkSync(e.friend(), e.file(), e.position(), new Buffer(0));
139 | //console.log('DONE (1)');
140 | return;
141 | }
142 |
143 | if(data.length !== bytesRead) {
144 | data = data.slice(0, bytesRead);
145 | }
146 |
147 | console.log('Sending chunk (friend=%d, position=%d, size=%d)', e.friend(), e.position(), data.length);
148 | tox.sendFileChunkSync(e.friend(), e.file(), e.position(), data);
149 | //console.log('DONE (2)');
150 | }
151 | });
152 |
153 | tox.on('fileRecv', function(e) {
154 | if(e.kind() === DATA) {
155 | var filename = fixRecvFilename(e.filename());
156 | if(filename.length > 0) {
157 | // Resulting path should look like:
158 | // {uploadPath}/friend_0/{filename}
159 | var friendDirName = ('friend_' + e.friend()),
160 | filepath = path.join(uploadPath, friendDirName, filename);
161 |
162 | // Make the parent directory
163 | try {
164 | mkdirp.sync(path.dirname(filepath), { mode: 0775 });
165 | } catch(e) { }
166 |
167 | // Open and store in file map
168 | var fd = fs.openSync(filepath, 'w');
169 | files[e.file()] = fd;
170 |
171 | // Tell sender we're ready to start the transfer
172 | tox.controlFileSync(e.friend(), e.file(), 'resume');
173 | } else {
174 | console.log('Fixed filename is empty string (original: %s)', e.filename());
175 | tox.controlFileSync(e.friend(), e.file(), 'cancel');
176 | }
177 | } else {
178 | // If not a data file (avatar), cancel
179 | console.log('File is avatar, ignoring');
180 | tox.controlFileSync(e.friend(), e.file(), 'cancel');
181 | }
182 | });
183 |
184 | tox.on('fileRecvChunk', function(e) {
185 | var fd = files[e.file()];
186 |
187 | if(e.isNull()) {
188 | console.log('NULL pointer for e.data(), ignoring received chunk');
189 | return;
190 | }
191 |
192 | // If length is 0, transfer is finished, release resources
193 | if(e.isFinal()) {
194 | fs.closeSync(fd);
195 | files[e.file()] = undefined;
196 | } else {
197 | fs.seekSync(fd, e.position(), SEEK_SET);
198 | fs.writeSync(fd, e.data(), 0, e.length());
199 | }
200 | });
201 |
202 | tox.setNameSync('File Transfer Bot');
203 | tox.setStatusMessageSync('node-toxcore file transfer bot example');
204 |
205 | console.log('Address: ' + tox.getAddressHexSync());
206 |
207 | // Start the tox_iterate loop
208 | tox.start();
209 |
--------------------------------------------------------------------------------
/examples/bin/old-groupchats-sync-example.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | /**
20 | * Tox bot displaying node-toxcore usage of old groupchats.
21 | */
22 |
23 | var toxcore = require('toxcore');
24 | var tox = new toxcore.Tox({ old: true });
25 | var groupnum = -1;
26 |
27 | // These should be in consts?
28 | var TOX_CHAT_CHANGE_PEER_ADD = 0;
29 | var TOX_CHAT_CHANGE_PEER_DEL = 1;
30 | var TOX_CHAT_CHANGE_PEER_NAME = 2;
31 |
32 | /**
33 | * Bootstrap tox via hardcoded nodes.
34 | * For more nodes, see: https://wiki.tox.chat/users/nodes
35 | */
36 | var nodes = [
37 | { maintainer: 'saneki',
38 | address: '96.31.85.154',
39 | port: 33445,
40 | key: '674153CF49616CD1C4ADF44B004686FC1F6C9DCDD048EF89B117B3F02AA0B778' },
41 | { maintainer: 'Impyy',
42 | address: '178.62.250.138',
43 | port: 33445,
44 | key: '788236D34978D1D5BD822F0A5BEBD2C53C64CC31CD3149350EE27D4D9A2F9B6B' },
45 | { maintainer: 'sonOfRa',
46 | address: '144.76.60.215',
47 | port: 33445,
48 | key: '04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F' }
49 | ];
50 |
51 | // Bootstrap from nodes
52 | nodes.forEach(function(node) {
53 | tox.bootstrapSync(node.address, node.port, node.key);
54 | console.log('Successfully bootstrapped from ' + node.maintainer + ' at ' + node.address + ':' + node.port);
55 | console.log('... with key ' + node.key);
56 | });
57 |
58 | // Init group
59 | groupnum = tox.old().addGroupchatSync();
60 |
61 | tox.on('selfConnectionStatus', function(e) {
62 | console.log(e.isConnected() ? 'Connected' : 'Disconnected');
63 | });
64 |
65 | // Accept all friend requests
66 | tox.on('friendRequest', function(e) {
67 | tox.addFriendNoRequestSync(e.publicKey());
68 | console.log('Received friend request: ' + e.message());
69 | console.log('Accepted friend request from ' + e.publicKeyHex());
70 | });
71 |
72 | tox.on('friendMessage', function(e) {
73 | var name = tox.getFriendNameSync(e.friend());
74 | if(e.message() === 'invite') {
75 | tox.old().inviteSync(e.friend(), groupnum);
76 | console.log('Invited ' + name + ' to group');
77 | }
78 | });
79 |
80 | tox.old().on('groupMessage', function(e) {
81 | var name = tox.old().getGroupchatPeernameSync(e.group(), e.peer());
82 | console.log(name + ': ' + e.message());
83 | });
84 |
85 | tox.old().on('groupAction', function(e) {
86 | var name = tox.old().getGroupchatPeernameSync(e.group(), e.peer());
87 | console.log('** ' + name + ' ' + e.message() + ' **');
88 | });
89 |
90 | tox.old().on('groupNamelistChange', function(e) {
91 | if(e.change() === TOX_CHAT_CHANGE_PEER_ADD) {
92 | // Peername here will always be 'Tox User'
93 | console.log('Peer ' + e.peer() + ' has joined the chat');
94 | } else if(e.change() === TOX_CHAT_CHANGE_PEER_DEL) {
95 | // Trying to get peername here will throw an error
96 | console.log('Peer ' + e.peer() + ' has left the chat');
97 | } else if(e.change() === TOX_CHAT_CHANGE_PEER_NAME) {
98 | var name = tox.old().getGroupchatPeernameSync(e.group(), e.peer());
99 | console.log('Peer ' + e.peer() + ' is now known as ' + name);
100 | } else {
101 | console.log('Unknown change: ' + e.change());
102 | }
103 | });
104 |
105 | tox.old().on('groupTitle', function(e) {
106 | var name = tox.old().getGroupchatPeernameSync(e.group(), e.peer());
107 | console.log(name + ' changed the group title: ' + e.title());
108 | });
109 |
110 | tox.setNameSync('Sync Bot (Old Groupchats)');
111 | tox.setStatusMessageSync('node-toxcore old groupchats sync bot example');
112 |
113 | console.log('Address: ' + tox.getAddressHexSync());
114 |
115 | // Start the tox_iterate loop
116 | tox.start();
117 |
--------------------------------------------------------------------------------
/examples/bin/old/promises-example.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @file promises-example.js - node-toxcore async example with bluebird
3 | * promises.
4 | *
5 | * This file is part of node-toxcore.
6 | *
7 | * node-toxcore is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * node-toxcore is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with node-toxcore. If not, see .
19 | *
20 | */
21 |
22 | var async = require('async');
23 | var Promise = require('bluebird');
24 | var toxcore = require('toxcore');
25 |
26 | Promise.promisifyAll(async);
27 | Promise.promisifyAll(toxcore);
28 |
29 | var tox = new toxcore.Tox();
30 |
31 | var groupchats = {
32 | 'text': -1,
33 | 'av': -1
34 | };
35 |
36 | /**
37 | * Bootstrap tox via hardcoded nodes.
38 | * For more nodes, see: https://wiki.tox.chat/users/nodes
39 | */
40 | var bootstrap = function(callback) {
41 | // Define nodes to bootstrap from
42 | var nodes = [
43 | { maintainer: 'Impyy',
44 | address: '178.62.250.138',
45 | port: 33445,
46 | key: '788236D34978D1D5BD822F0A5BEBD2C53C64CC31CD3149350EE27D4D9A2F9B6B' },
47 | { maintainer: 'sonOfRa',
48 | address: '144.76.60.215',
49 | port: 33445,
50 | key: '04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F' }
51 | ];
52 |
53 | async.mapAsync(nodes, function(node, cb) {
54 | tox.bootstrapFromAddressAsync(node.address, node.port, node.key).then(function() {
55 | console.log('Successfully bootstrapped from ' + node.maintainer + ' at ' + node.address + ':' + node.port);
56 | console.log('... with key ' + node.key);
57 | cb();
58 | }).catch(function(err) {
59 | console.error('Error bootstrapping from ' + node.maintainer + ':', err);
60 | cb(err);
61 | });
62 | }).then(function() {
63 | // Once all nodes have been bootstrapped from, call our callback
64 | callback();
65 | });
66 | };
67 |
68 | /**
69 | * Initialize ourself. Sets name and status message.
70 | * @private
71 | */
72 | var initSelf = function(callback) {
73 | // Asynchronously set our name and status message using promises
74 | Promise.join(
75 | tox.setNameAsync('Bluebird'),
76 | tox.setStatusMessageAsync('Some status message')
77 | ).then(function() {
78 | console.log('Successfully set name and status message!');
79 | callback();
80 | }).catch(function(err) {
81 | console.error('Error (initSelf):', err);
82 | callback(err);
83 | });
84 | };
85 |
86 | /**
87 | * Initialize our callbacks, listening for friend requests and messages.
88 | */
89 | var initCallbacks = function(callback) {
90 | tox.on('friendRequest', function(evt) {
91 | console.log('Accepting friend request from ' + evt.publicKeyHex());
92 | // Automatically accept the request
93 | tox.addFriendNoRequestAsync(evt.publicKey()).then(function() {
94 | console.log('Successfully accepted the friend request!');
95 | }).catch(function(err) {
96 | console.error('Couldn\'t accept the friend request:', err);
97 | });
98 | });
99 |
100 | tox.on('friendMessage', function(evt) {
101 | console.log('Message from friend ' + evt.friend() + ': ' + evt.message());
102 | // Echo message back to friend
103 | tox.sendMessageAsync(evt.friend(), evt.message()).then(function(receipt) {
104 | console.log('Echoed message back to friend, received receipt ' + receipt);
105 | }).catch(function(err) {
106 | console.error('Couldn\'t echo message back to friend:', err);
107 | });
108 | });
109 |
110 | // Setup friendMessage callback to listen for groupchat invite requests
111 | tox.on('friendMessage', function(evt) {
112 | if(evt.message() === 'invite text') {
113 | tox.inviteAsync(evt.friend(), groupchats['text']).then(function() {
114 | console.log('Invited ' + evt.friend() + ' to the text groupchat');
115 | });
116 | } else if(evt.message() === 'invite av') {
117 | tox.inviteAsync(evt.friend(), groupchats['av']).then(function() {
118 | console.log('Invited ' + evt.friend() + ' to the audio/video groupchat');
119 | });
120 | }
121 | });
122 |
123 | callback();
124 | };
125 |
126 | /**
127 | * Initialize the groupchats, and call the callback when finished.
128 | */
129 | var initGroupchats = function(callback) {
130 | async.parallelAsync([
131 | tox.addGroupchat.bind(tox),
132 | tox.getAV().addGroupchat.bind(tox.getAV())
133 | ]).then(function(results) {
134 | groupchats['text'] = results[0];
135 | groupchats['av'] = results[1];
136 | }).finally(callback);
137 | };
138 |
139 | // Initialize everything + bootstrap from nodes, then when everything
140 | // is ready print our address and start
141 | async.parallel([
142 | initSelf, // Initialize name, status message
143 | initCallbacks, // Initialize callbacks
144 | initGroupchats, // Initialize groupchats
145 | bootstrap // Bootstrap
146 | ], function() {
147 | // When everything is ready, print out our tox address
148 | tox.getAddressHexAsync().then(function(addr) {
149 | console.log('------------------------');
150 | console.log('Tox address: ' + addr);
151 | });
152 |
153 | tox.start(); // Start
154 | });
155 |
--------------------------------------------------------------------------------
/examples/bin/old/sync-example.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @file sync-example.js - A tiny tox echo-bot example using node-toxcore's
3 | * synchronous methods.
4 | *
5 | * This file is part of node-toxcore.
6 | *
7 | * node-toxcore is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * node-toxcore is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with node-toxcore. If not, see .
19 | *
20 | */
21 |
22 | var toxcore = require('toxcore');
23 | var tox = new toxcore.Tox();
24 |
25 | /**
26 | * Bootstrap tox via hardcoded nodes.
27 | * For more nodes, see: https://wiki.tox.chat/users/nodes
28 | */
29 | var nodes = [
30 | { maintainer: 'Impyy',
31 | address: '178.62.250.138',
32 | port: 33445,
33 | key: '788236D34978D1D5BD822F0A5BEBD2C53C64CC31CD3149350EE27D4D9A2F9B6B' },
34 | { maintainer: 'sonOfRa',
35 | address: '144.76.60.215',
36 | port: 33445,
37 | key: '04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F' }
38 | ];
39 |
40 | // Groupchat ids, will be updated later
41 | var groupchats = {
42 | 'text': -1,
43 | 'av': -1
44 | };
45 |
46 | // Set our name, status message, user status
47 | tox.setNameSync('Tox Sync Example');
48 | tox.setStatusMessageSync('Whee!');
49 | tox.setUserStatusSync(1); // 1 = away
50 |
51 | // Setup friendRequest callback to auto-accept friend requests
52 | tox.on('friendRequest', function(evt) {
53 | tox.addFriendNoRequestSync(evt.publicKey());
54 | console.log('Accepted friend request from ' + evt.publicKeyHex());
55 | });
56 |
57 | // Setup friendMessage callback to echo messages
58 | tox.on('friendMessage', function(evt) {
59 | tox.sendMessageSync(evt.friend(), evt.message());
60 | console.log('Echoed message from friend ' + evt.friend() + ': ' + evt.message());
61 | });
62 |
63 | // Setup another friendMessage callback to handle groupchat invite requests
64 | tox.on('friendMessage', function(evt) {
65 | if(evt.message() === 'invite text') {
66 | // Invite to text groupchat
67 | tox.inviteSync(evt.friend(), groupchats['text']);
68 | } else if(evt.message() === 'invite av') {
69 | // Invite to a/v groupchat
70 | tox.inviteSync(evt.friend(), groupchats['av']);
71 | }
72 | });
73 |
74 | // Setup groupInvite callback to auto-accept group invites
75 | tox.on('groupInvite', function(evt) {
76 | var groupnum;
77 | if(evt.isChatText()) {
78 | groupnum = tox.joinGroupchatSync(evt.friend(), evt.data());
79 | console.log('Joined text groupchat ' + groupnum);
80 | } else if(evt.isChatAV()) {
81 | groupnum = tox.getAV().joinGroupchatSync(evt.friend(), evt.data());
82 | console.log('Joined audio/video groupchat ' + groupnum);
83 | };
84 | });
85 |
86 | // Bootstrap from nodes
87 | nodes.forEach(function(node) {
88 | tox.bootstrapFromAddressSync(node.address, node.port, node.key);
89 | });
90 |
91 | // Create a new text groupchat and a new AV groupchat
92 | groupchats['text'] = tox.addGroupchatSync();
93 | groupchats['av'] = tox.getAV().addGroupchatSync();
94 |
95 | // Print our tox address
96 | console.log('Address: ' + tox.getAddressHexSync());
97 |
98 | // Start the tox_do loop
99 | tox.start();
100 |
--------------------------------------------------------------------------------
/examples/bin/packet-simulation.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var buffertools = require('buffertools');
20 | var toxcore = require('toxcore');
21 | var tx = new toxcore.Tox(), rx = new toxcore.Tox();
22 |
23 | var LOSSLESS_CHANNEL = 160;
24 | var LOSSY_CHANNEL = 200;
25 |
26 | /*
27 | * Bootstrap tox via hardcoded nodes.
28 | * For more nodes, see: https://wiki.tox.chat/users/nodes
29 | */
30 | var nodes = [
31 | { maintainer: 'saneki',
32 | address: '96.31.85.154',
33 | port: 33445,
34 | key: '674153CF49616CD1C4ADF44B004686FC1F6C9DCDD048EF89B117B3F02AA0B778' },
35 | { maintainer: 'Impyy',
36 | address: '178.62.250.138',
37 | port: 33445,
38 | key: '788236D34978D1D5BD822F0A5BEBD2C53C64CC31CD3149350EE27D4D9A2F9B6B' },
39 | { maintainer: 'sonOfRa',
40 | address: '144.76.60.215',
41 | port: 33445,
42 | key: '04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F' }
43 | ];
44 |
45 |
46 | //
47 | // Setup rx
48 | //
49 |
50 | rx.setNameSync('Packet Bot (recv)');
51 | rx.setStatusMessageSync('Bot for testing lossless/lossy packet tx/rx');
52 |
53 | rx.on('friendRequest', function(e) {
54 | console.log('[rx] Accepting friend request from: %s', e.publicKeyHex().toUpperCase());
55 | rx.addFriendNoRequestSync(e.publicKey());
56 | });
57 |
58 | rx.on('friendConnectionStatus', function(e) {
59 | console.log('[rx] Friend connection status: %s', e.isConnected() ? 'online' : 'offline');
60 | });
61 |
62 | var packetCallback = function(e) {
63 | var packetType = e.isLossless() ? 'lossless' : 'lossy';
64 | console.log('** Received %s packet from [%d] **', packetType, e.friend());
65 | console.log('Id: 0x%s', e.id().toString(16));
66 | console.log('Data: %s', e.data().toString());
67 |
68 | // Respond using the same id
69 | if(e.isLossless()) {
70 | rx.sendLosslessPacketSync(e.friend(), e.id(), new Buffer('lossless-receipt-packet-content'));
71 | } else {
72 | rx.sendLossyPacketSync(e.friend(), e.id(), new Buffer('lossy-receipt-packet-content'));
73 | }
74 | };
75 |
76 | // Event 'friendLosslessPacket': Listen for lossless packets
77 | // e -> FriendPacketEvent
78 | // e.data() -> {Buffer} Data buffer without leading id byte
79 | // e.friend() -> {Number} Friend number
80 | // e.fullData() -> {Buffer} Data buffer including the leading id byte
81 | // e.id() -> {Number} Leading Id byte
82 | // e.isLossless() -> {Boolean} Whether or not the packet was lossless
83 | // e.isLossy() -> {Boolean} Whether or not the packet was lossy
84 | rx.on('friendLosslessPacket', packetCallback);
85 |
86 | // Event: 'friendLossyPacket': Listen for lossy packets
87 | // e -> FriendPacketEvent (same event as used in 'friendLosslessPacket' event)
88 | rx.on('friendLossyPacket', packetCallback);
89 |
90 |
91 | //
92 | // Setup tx
93 | //
94 |
95 | tx.setNameSync('Packet Bot (send)');
96 | tx.setStatusMessageSync('Bot for testing lossless/lossy packet tx/rx');
97 |
98 | tx.on('selfConnectionStatus', function(e) {
99 | if(e.isConnected()) {
100 | console.log('[tx] Adding friend: %s', rx.getAddressHexSync().toUpperCase());
101 | tx.addFriendSync(rx.getAddressSync(), 'Hello');
102 | }
103 | });
104 |
105 | tx.on('friendConnectionStatus', function(e) {
106 | console.log('[tx] Friend connection status: %s', e.isConnected() ? 'online' : 'offline');
107 | if(e.isConnected()) {
108 | console.log('[tx] Sending lossless + lossy packets');
109 | tx.sendLosslessPacketSync(e.friend(), LOSSLESS_CHANNEL, new Buffer('hello-world-lossless'));
110 | tx.sendLossyPacketSync(e.friend(), LOSSY_CHANNEL, new Buffer('hello-world-lossy'));
111 |
112 | var losslessMessage2 = buffertools.concat(
113 | new Buffer([LOSSLESS_CHANNEL + 1]),
114 | new Buffer('lossless-2-param')
115 | );
116 | tx.sendLosslessPacketSync(e.friend(), losslessMessage2);
117 |
118 | var lossyMessage2 = buffertools.concat(
119 | new Buffer([LOSSY_CHANNEL + 1]),
120 | new Buffer('lossy-2-param')
121 | );
122 | tx.sendLossyPacketSync(e.friend(), lossyMessage2);
123 | }
124 | });
125 |
126 | tx.on('friendLosslessPacket', function(e) {
127 | console.log('[tx] Received lossless response: %s', e.data().toString());
128 | });
129 |
130 | tx.on('friendLossyPacket', function(e) {
131 | console.log('[tx] Received lossy response: %s', e.data().toString());
132 | });
133 |
134 |
135 | // Bootstrap and start each
136 | [{ tox: tx, name: 'tx' }, { tox: rx, name: 'rx' }].forEach(function(obj) {
137 | var tox = obj.tox, toxName = obj.name;
138 |
139 | // Bootstrap from nodes
140 | nodes.forEach(function(node) {
141 | tox.bootstrapSync(node.address, node.port, node.key);
142 | console.log('[%s] Successfully bootstrapped from %s at %s:%d', toxName, node.maintainer, node.address, node.port);
143 | console.log('... with key %s', node.key);
144 | });
145 |
146 | tox.on('selfConnectionStatus', function(e) {
147 | console.log('[%s] %s', toxName, e.isConnected() ? 'Connected' : 'Disconnected');
148 | });
149 |
150 | console.log('[%s] Address: %s', toxName, tox.getAddressHexSync().toUpperCase());
151 |
152 | tox.start();
153 | });
154 |
--------------------------------------------------------------------------------
/examples/bin/promises-example.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | /**
20 | * node-toxcore (new_api) async example with bluebird promises.
21 | */
22 |
23 | var async = require('async');
24 | var Promise = require('bluebird');
25 | var toxcore = require('toxcore');
26 |
27 | Promise.promisifyAll(async);
28 | Promise.promisifyAll(toxcore);
29 |
30 | var tox = new toxcore.Tox();
31 |
32 | /**
33 | * Bootstrap tox via hardcoded nodes.
34 | * For more nodes, see: https://wiki.tox.chat/users/nodes
35 | */
36 | var bootstrap = function(callback) {
37 | // Define nodes to bootstrap from
38 | var nodes = [
39 | { maintainer: 'saneki',
40 | address: '96.31.85.154',
41 | port: 33445,
42 | key: '674153CF49616CD1C4ADF44B004686FC1F6C9DCDD048EF89B117B3F02AA0B778' },
43 | { maintainer: 'Impyy',
44 | address: '178.62.250.138',
45 | port: 33445,
46 | key: '788236D34978D1D5BD822F0A5BEBD2C53C64CC31CD3149350EE27D4D9A2F9B6B' },
47 | { maintainer: 'sonOfRa',
48 | address: '144.76.60.215',
49 | port: 33445,
50 | key: '04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F' }
51 | ];
52 |
53 | async.mapAsync(nodes, function(node, cb) {
54 | tox.bootstrapAsync(node.address, node.port, node.key).then(function() {
55 | console.log('Successfully bootstrapped from ' + node.maintainer + ' at ' + node.address + ':' + node.port);
56 | console.log('... with key ' + node.key);
57 | cb();
58 | }).catch(function(err) {
59 | console.error('Error bootstrapping from ' + node.maintainer + ':', err);
60 | cb(err);
61 | });
62 | }).then(function() {
63 | // Once all nodes have been bootstrapped from, call our callback
64 | callback();
65 | });
66 | };
67 |
68 | var initProfile = function(callback) {
69 | var setName = tox.setNameAsync('Promises Bot'),
70 | setStatusMessage = tox.setStatusMessageAsync('node-toxcore promises bot example');
71 | Promise.join(setName, setStatusMessage, callback);
72 | };
73 |
74 | var initCallbacks = function(callback) {
75 | tox.on('selfConnectionStatus', function(e) {
76 | console.log(e.isConnected() ? 'Connected' : 'Disconnected');
77 | });
78 |
79 | tox.on('friendName', function(e) {
80 | console.log('Friend[' + e.friend() + '] changed their name: ' + e.name());
81 | });
82 |
83 | tox.on('friendStatusMessage', function(e) {
84 | console.log('Friend[' + e.friend() + '] changed their status message: ' + e.statusMessage());
85 | });
86 |
87 | tox.on('friendStatus', function(e) {
88 | console.log('Friend[' + e.friend() + '] changed their status: ' + e.status());
89 | });
90 |
91 | tox.on('friendConnectionStatus', function(e) {
92 | console.log('Friend[' + e.friend() + '] is now ' + (e.isConnected() ? 'online' : 'offline'));
93 | });
94 |
95 | tox.on('friendTyping', function(e) {
96 | console.log('Friend[' + e.friend() + '] is ' + (e.isTyping() ? 'typing' : 'not typing'));
97 | });
98 |
99 | tox.on('friendReadReceipt', function(e) {
100 | console.log('Friend[' + e.friend() + '] receipt: ' + e.receipt());
101 | });
102 |
103 | tox.on('friendRequest', function(e) {
104 | tox.addFriendNoRequest(e.publicKey(), function(err, friend) {
105 | console.log('Received friend request: ' + e.message());
106 | console.log('Accepted friend request from ' + e.publicKeyHex());
107 | });
108 | });
109 |
110 | tox.on('friendMessage', function(e) {
111 | if(e.isAction()) {
112 | console.log('** Friend[' + e.friend() + '] ' + e.message() + ' **');
113 | } else {
114 | console.log('Friend[' + e.friend() + ']: ' + e.message());
115 | }
116 | // Echo the message back
117 | tox.sendFriendMessageSync(e.friend(), e.message(), e.messageType());
118 |
119 | if(e.message() === 'typing on') {
120 | tox.setTyping(e.friend(), true, function(err) {
121 | console.log('Started typing to friend[' + e.friend() + ']');
122 | });
123 | } else if(e.message() === 'typing off') {
124 | tox.setTyping(e.friend(), false, function(err) {
125 | console.log('Stopped typing to friend[' + e.friend() + ']');
126 | });
127 | }
128 |
129 | if(e.message() === 'profile') {
130 | var getName = tox.getFriendNameAsync(e.friend()),
131 | getStatusMessage = tox.getFriendStatusMessageAsync(e.friend()),
132 | getStatus = tox.getFriendStatusAsync(e.friend()),
133 | getConnectionStatus = tox.getFriendConnectionStatusAsync(e.friend());
134 |
135 | Promise.join(getName, getStatusMessage, getStatus, getConnectionStatus,
136 | function(name, statusMessage, status, connectionStatus) {
137 | console.log('Friend ' + e.friend() + ' profile:');
138 | console.log(' Name: ' + name);
139 | console.log(' Status message: ' + statusMessage);
140 | console.log(' Status: ' + status);
141 | console.log(' Connection status: ' + connectionStatus);
142 | });
143 | }
144 |
145 | if(e.message() === 'lastonline') {
146 | tox.getFriendLastOnlineAsync(e.friend).then(function(lastOnline) {
147 | console.log('Last online: ' + lastOnline.toString());
148 | });
149 | }
150 |
151 | if(e.message() === 'namelen') {
152 | var getNameSize = tox.getFriendNameSizeAsync(e.friend()),
153 | getStatusMessageSize = tox.getFriendStatusMessageSizeAsync(e.friend());
154 | Promise.join(getNameSize, getStatusMessageSize, function(nameSize, statusMessageSize) {
155 | console.log('Name length: ' + nameSize);
156 | console.log('Status message length: ' + statusMessageSize);
157 | });
158 | }
159 | });
160 |
161 | callback();
162 | };
163 |
164 | // Initialize everything + bootstrap from nodes, then when everything
165 | // is ready, start
166 | async.parallel([
167 | bootstrap, // Bootstrap
168 | initProfile, // Name, status message
169 | initCallbacks // Initialize callbacks
170 | ], function() {
171 | tox.getAddressHex(function(err, address) {
172 | console.log('Address: ' + address);
173 | tox.start(); // Start
174 | });
175 | });
176 |
--------------------------------------------------------------------------------
/examples/bin/sync-example.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | /**
20 | * A tiny tox bot example using node-toxcore's synchronous methods (new_api).
21 | */
22 | var testingMode=false;
23 |
24 | var path = require('path');
25 | var toxcore = !testingMode ? require('toxcore') : require(path.join(__dirname, '..', '..', 'lib', 'main'));
26 | var tox = new toxcore.Tox();
27 |
28 | /**
29 | * Bootstrap tox via hardcoded nodes.
30 | * For more nodes, see: https://wiki.tox.chat/users/nodes
31 | */
32 | var nodes = [
33 | { maintainer: 'saneki',
34 | address: '96.31.85.154',
35 | port: 33445,
36 | key: '674153CF49616CD1C4ADF44B004686FC1F6C9DCDD048EF89B117B3F02AA0B778' },
37 | { maintainer: 'Impyy',
38 | address: '178.62.250.138',
39 | port: 33445,
40 | key: '788236D34978D1D5BD822F0A5BEBD2C53C64CC31CD3149350EE27D4D9A2F9B6B' },
41 | { maintainer: 'sonOfRa',
42 | address: '144.76.60.215',
43 | port: 33445,
44 | key: '04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F' }
45 | ];
46 |
47 | // Bootstrap from nodes
48 | nodes.forEach(function(node) {
49 | tox.bootstrapSync(node.address, node.port, node.key);
50 | console.log('Successfully bootstrapped from ' + node.maintainer + ' at ' + node.address + ':' + node.port);
51 | console.log('... with key ' + node.key);
52 | });
53 |
54 | tox.on('selfConnectionStatus', function(e) {
55 | console.log(e.isConnected() ? 'Connected' : 'Disconnected');
56 | });
57 |
58 | tox.on('friendName', function(e) {
59 | var name = tox.getFriendNameSync(e.friend());
60 | console.log(name + '[' + e.friend() + '] changed their name: ' + e.name());
61 | });
62 |
63 | tox.on('friendStatusMessage', function(e) {
64 | var name = tox.getFriendNameSync(e.friend());
65 | console.log(name + '[' + e.friend() + '] changed their status message: ' + e.statusMessage());
66 | });
67 |
68 | tox.on('friendStatus', function(e) {
69 | var name = tox.getFriendNameSync(e.friend());
70 | console.log(name + '[' + e.friend() + '] changed their status: ' + e.status());
71 | });
72 |
73 | tox.on('friendConnectionStatus', function(e) {
74 | var name = tox.getFriendNameSync(e.friend());
75 | var statusMessage = tox.getFriendStatusMessageSync(e.friend());
76 | console.log(name + '[' + e.friend() + '] is now ' + (e.isConnected() ? 'online' : 'offline') + ': ' + statusMessage);
77 |
78 | });
79 |
80 | tox.on('friendTyping', function(e) {
81 | var name = tox.getFriendNameSync(e.friend());
82 | console.log(name + '[' + e.friend() + '] is ' + (e.isTyping() ? 'typing' : 'not typing'));
83 | });
84 |
85 | tox.on('friendReadReceipt', function(e) {
86 | var name = tox.getFriendNameSync(e.friend());
87 | console.log(name + '[' + e.friend() + '] receipt: ' + e.receipt());
88 | });
89 |
90 | tox.on('friendRequest', function(e) {
91 | tox.addFriendNoRequestSync(e.publicKey());
92 | console.log('Received friend request: ' + e.message());
93 | console.log('Accepted friend request from ' + e.publicKeyHex());
94 | });
95 |
96 | tox.on('friendMessage', function(e) {
97 | var name = tox.getFriendNameSync(e.friend());
98 | if(e.isAction()) {
99 | console.log('** ' + name + '[' + e.friend() + '] ' + e.message() + ' **');
100 | } else {
101 | console.log(name + '[' + e.friend() + ']: ' + e.message());
102 | }
103 | // Echo the message back
104 | tox.sendFriendMessageSync(e.friend(), e.message(), e.messageType());
105 |
106 | if(e.message() === 'typing on') {
107 | tox.setTypingSync(e.friend(), true);
108 | console.log('Started typing to ' + name + '[' + e.friend() + ']');
109 | } else if(e.message() === 'typing off') {
110 | tox.setTypingSync(e.friend(), false);
111 | console.log('Stopped typing to ' + name + '[' + e.friend() + ']');
112 | }
113 |
114 | if(e.message() === 'profile') {
115 | var statusMessage = tox.getFriendStatusMessageSync(e.friend()),
116 | status = tox.getFriendStatusSync(e.friend()),
117 | connectionStatus = tox.getFriendConnectionStatusSync(e.friend());
118 | console.log('Friend ' + e.friend() + ' profile:');
119 | console.log(' Name: ' + name);
120 | console.log(' Status message: ' + statusMessage);
121 | console.log(' Status: ' + status);
122 | console.log(' Connection status: ' + connectionStatus);
123 | }
124 |
125 | if(e.message() === 'lastonline') {
126 | var lastOnline = tox.getFriendLastOnlineSync(e.friend());
127 | console.log(name + ' last online: ' + lastOnline.toString());
128 | }
129 |
130 | if(e.message() === 'namelen') {
131 | console.log('Name length: ' + tox.getFriendNameSizeSync(e.friend()));
132 | console.log('Status message length: ' + tox.getFriendStatusMessageSizeSync(e.friend()));
133 | }
134 | });
135 |
136 | tox.on('friendLosslessPacket', function(e){
137 | var name = tox.getFriendNameSync(e.friend());
138 | console.log('**Received lossless packet from ' + '[' + e.friend() + ']');
139 | console.log(e.data().toString());
140 | tox.sendLosslessPacketSync(e.friend(), new Buffer('lossless-receipt-packet-content'));
141 | });
142 |
143 | tox.setNameSync('Sync Bot');
144 | tox.setStatusMessageSync('node-toxcore sync bot example');
145 |
146 | console.log('Address: ' + tox.getAddressHexSync());
147 |
148 | // Start the tox_iterate loop
149 | tox.start();
150 |
--------------------------------------------------------------------------------
/examples/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "toxcore-examples",
3 | "version": "0.0.0",
4 | "description": "node-toxcore examples",
5 | "dependencies": {
6 | "async": "^0.9.0",
7 | "buffertools": "^2.1.3",
8 | "bluebird": "^2.9.9",
9 | "fs-ext": "^0.4.4",
10 | "mkdirp": "^0.5.0",
11 | "toxcore": "../"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/lib/consts.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | /**
20 | * @file consts.js
21 | * Specifies constants and enum values defined in tox.h. All enum values
22 | * are assumed to start at 0 and increment once per possible value. This
23 | * could be an issue if updated versions of toxcore have new enum values
24 | * inserted, instead of appended.
25 | */
26 |
27 | var consts = {
28 | TOX_KEY_SIZE: 32,
29 | TOX_FRIEND_ADDRESS_SIZE: (32 + 6),
30 |
31 | TOX_PUBLIC_KEY_SIZE: 32,
32 | TOX_SECRET_KEY_SIZE: 32,
33 | TOX_ADDRESS_SIZE: (32 + 6),
34 | TOX_MAX_NAME_LENGTH: 128,
35 | TOX_MAX_STATUS_MESSAGE_LENGTH: 1007,
36 | TOX_MAX_FRIEND_REQUEST_LENGTH: 1016,
37 | TOX_MAX_MESSAGE_LENGTH: 1372,
38 | TOX_MAX_CUSTOM_PACKET_SIZE: 1373,
39 | TOX_HASH_LENGTH: 32,
40 | TOX_FILE_ID_LENGTH: 32,
41 | TOX_MAX_FILENAME_LENGTH: 255,
42 |
43 | TOX_CONNECTION_NONE: 0,
44 | TOX_CONNECTION_TCP: 1,
45 | TOX_CONNECTION_UDP: 2,
46 |
47 | TOX_MESSAGE_TYPE_NORMAL: 0,
48 | TOX_MESSAGE_TYPE_ACTION: 1,
49 |
50 | TOX_USER_STATUS_NONE: 0,
51 | TOX_USER_STATUS_AWAY: 1,
52 | TOX_USER_STATUS_BUSY: 2,
53 |
54 | TOX_ERR_FILE_CONTROL_OK: 0,
55 | TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND: 1,
56 | TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED: 2,
57 | TOX_ERR_FILE_CONTROL_NOT_FOUND: 3,
58 | TOX_ERR_FILE_CONTROL_NOT_PAUSED: 4,
59 | TOX_ERR_FILE_CONTROL_DENIED: 5,
60 | TOX_ERR_FILE_CONTROL_ALREADY_PAUSED: 6,
61 | TOX_ERR_FILE_CONTROL_SENDQ: 7,
62 |
63 | TOX_ERR_FILE_GET_OK: 0,
64 | TOX_ERR_FILE_GET_FRIEND_NOT_FOUND: 1,
65 | TOX_ERR_FILE_GET_NOT_FOUND: 2,
66 |
67 | TOX_ERR_FILE_SEEK_OK: 0,
68 | TOX_ERR_FILE_SEEK_FRIEND_NOT_FOUND: 1,
69 | TOX_ERR_FILE_SEEK_FRIEND_NOT_CONNECTED: 2,
70 | TOX_ERR_FILE_SEEK_NOT_FOUND: 3,
71 | TOX_ERR_FILE_SEEK_DENIED: 4,
72 | TOX_ERR_FILE_SEEK_INVALID_POSITION: 5,
73 | TOX_ERR_FILE_SEEK_SENDQ: 6,
74 |
75 | TOX_ERR_FILE_SEND_OK: 0,
76 | TOX_ERR_FILE_SEND_NULL: 1,
77 | TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND: 2,
78 | TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED: 3,
79 | TOX_ERR_FILE_SEND_NAME_TOO_LONG: 4,
80 | TOX_ERR_FILE_SEND_TOO_MANY: 5,
81 |
82 | TOX_ERR_FILE_SEND_CHUNK_OK: 0,
83 | TOX_ERR_FILE_SEND_CHUNK_NULL: 1,
84 | TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_FOUND: 2,
85 | TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED: 3,
86 | TOX_ERR_FILE_SEND_CHUNK_NOT_FOUND: 4,
87 | TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING: 5,
88 | TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH: 6,
89 | TOX_ERR_FILE_SEND_CHUNK_SENDQ: 7,
90 | TOX_ERR_FILE_SEND_CHUNK_WRONG_POSITION: 8,
91 |
92 | TOX_ERR_FRIEND_ADD_OK: 0,
93 | TOX_ERR_FRIEND_ADD_NULL: 1,
94 | TOX_ERR_FRIEND_ADD_TOO_LONG: 2,
95 | TOX_ERR_FRIEND_ADD_NO_MESSAGE: 3,
96 | TOX_ERR_FRIEND_ADD_OWN_KEY: 4,
97 | TOX_ERR_FRIEND_ADD_ALREADY_SENT: 5,
98 | TOX_ERR_FRIEND_ADD_BAD_CHECKSUM: 6,
99 | TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM: 7,
100 | TOX_ERR_FRIEND_ADD_MALLOC: 8,
101 |
102 | TOX_ERR_FRIEND_CUSTOM_PACKET_OK: 0,
103 | TOX_ERR_FRIEND_CUSTOM_PACKET_NULL: 1,
104 | TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_FOUND: 2,
105 | TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_CONNECTED: 3,
106 | TOX_ERR_FRIEND_CUSTOM_PACKET_INVALID: 4,
107 | TOX_ERR_FRIEND_CUSTOM_PACKET_EMPTY: 5,
108 | TOX_ERR_FRIEND_CUSTOM_PACKET_TOO_LONG: 6,
109 | TOX_ERR_FRIEND_CUSTOM_PACKET_SENDQ: 7,
110 |
111 | TOX_ERR_FRIEND_DELETE_OK: 0,
112 | TOX_ERR_FRIEND_DELETE_FRIEND_NOT_FOUND: 1,
113 |
114 | TOX_ERR_FRIEND_GET_LAST_ONLINE_OK: 0,
115 | TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND: 1,
116 |
117 | TOX_ERR_FRIEND_QUERY_OK: 0,
118 | TOX_ERR_FRIEND_QUERY_NULL: 1,
119 | TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND: 2,
120 |
121 | TOX_ERR_FRIEND_SEND_MESSAGE_OK: 0,
122 | TOX_ERR_FRIEND_SEND_MESSAGE_NULL: 1,
123 | TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_FOUND: 2,
124 | TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_CONNECTED: 3,
125 | TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ: 4,
126 | TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG: 5,
127 | TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY: 6,
128 |
129 | TOX_ERR_NEW_OK: 0,
130 | TOX_ERR_NEW_NULL: 1,
131 | TOX_ERR_NEW_MALLOC: 2,
132 | TOX_ERR_NEW_PORT_ALLOC: 3,
133 | TOX_ERR_NEW_PROXY_TYPE: 4,
134 | TOX_ERR_NEW_PROXY_BAD_HOST: 5,
135 | TOX_ERR_NEW_PROXY_BAD_PORT: 6,
136 | TOX_ERR_NEW_PROXY_NOT_FOUND: 7,
137 | TOX_ERR_NEW_LOAD_ENCRYPTED: 8,
138 | TOX_ERR_NEW_LOAD_DECRYPTION_FAILED: 9,
139 | TOX_ERR_NEW_LOAD_BAD_FORMAT: 10,
140 |
141 | TOX_ERR_OPTIONS_NEW_OK: 0,
142 | TOX_ERR_OPTIONS_NEW_MALLOC: 1,
143 |
144 | TOX_ERR_BOOTSTRAP_OK: 0,
145 | TOX_ERR_BOOTSTRAP_NULL: 1,
146 | TOX_ERR_BOOTSTRAP_BAD_HOST: 2,
147 | TOX_ERR_BOOTSTRAP_BAD_PORT: 3,
148 |
149 | TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK: 0,
150 | TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL: 1,
151 | TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND: 2,
152 |
153 | TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK: 0,
154 | TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND: 1,
155 |
156 | TOX_ERR_GET_PORT_OK: 0,
157 | TOX_ERR_GET_PORT_NOT_BOUND: 1,
158 |
159 | TOX_ERR_SET_INFO_OK: 0,
160 | TOX_ERR_SET_INFO_NULL: 1,
161 | TOX_ERR_SET_INFO_TOO_LONG: 2,
162 |
163 | TOX_ERR_SET_TYPING_OK: 0,
164 | TOX_ERR_SET_TYPING_FRIEND_NOT_FOUND: 1,
165 |
166 | TOX_FILE_KIND_DATA: 0,
167 | TOX_FILE_KIND_AVATAR: 1,
168 |
169 | TOX_FILE_CONTROL_RESUME: 0,
170 | TOX_FILE_CONTROL_PAUSE: 1,
171 | TOX_FILE_CONTROL_CANCEL: 2,
172 |
173 | TOX_PROXY_TYPE_NONE: 0,
174 | TOX_PROXY_TYPE_HTTP: 1,
175 | TOX_PROXY_TYPE_SOCKS5: 2,
176 |
177 | TOX_SAVEDATA_TYPE_NONE: 0,
178 | TOX_SAVEDATA_TYPE_TOX_SAVE: 1,
179 | TOX_SAVEDATA_TYPE_SECRET_KEY: 2,
180 |
181 | TOX_PASS_KEY_LENGTH: 32,
182 | TOX_PASS_SALT_LENGTH: 32,
183 | TOX_PASS_ENCRYPTION_EXTRA_LENGTH: 80,
184 |
185 | TOX_ERR_DECRYPTION_OK: 0,
186 | TOX_ERR_DECRYPTION_NULL: 1,
187 | TOX_ERR_DECRYPTION_INVALID_LENGTH: 2,
188 | TOX_ERR_DECRYPTION_BAD_FORMAT: 3,
189 | TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED: 4,
190 | TOX_ERR_DECRYPTION_FAILED: 5,
191 |
192 | TOX_ERR_ENCRYPTION_OK: 0,
193 | TOX_ERR_ENCRYPTION_NULL: 1,
194 | TOX_ERR_ENCRYPTION_KEY_DERIVATION_FAILED: 2,
195 | TOX_ERR_ENCRYPTION_FAILED: 3,
196 |
197 | TOX_ERR_KEY_DERIVATION_OK: 0,
198 | TOX_ERR_KEY_DERIVATION_NULL: 1,
199 | TOX_ERR_KEY_DERIVATION_FAILED: 2,
200 |
201 | TOXDNS_MAX_RECOMMENDED_NAME_LENGTH: 32
202 | };
203 |
204 | module.exports = consts;
205 |
--------------------------------------------------------------------------------
/lib/errors.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | /**
20 | * @file errors.js - Provides functions for handling errors and error values.
21 | * @todo Remove check* function, rename almost all
22 | */
23 |
24 | var path = require('path');
25 | var consts = require(path.join(__dirname, 'consts'));
26 | var ToxError = require(path.join(__dirname, 'toxerror'));
27 |
28 | module.exports = {
29 | /**
30 | * Check the error value that may have been set by tox_new, and throw
31 | * the corresponding error (if any).
32 | * @private
33 | * @param {Number} val - Error value to check
34 | * @todo Get an Error instead of throw
35 | */
36 | checkToxNewError: function(val) {
37 | if(val !== consts.TOX_ERR_NEW_OK) {
38 | throw (new ToxError('TOX_ERR_NEW', val));
39 | }
40 | },
41 |
42 | /**
43 | * Get an Error from a TOX_ERR_BOOTSTRAP value. If none,
44 | * will return undefined.
45 | * @private
46 | * @param {Number} val - TOX_ERR_BOOTSTRAP value
47 | * @return {ToxError} Error, if any
48 | */
49 | bootstrap: function(val) {
50 | if(val !== consts.TOX_ERR_BOOTSTRAP_OK) {
51 | return (new ToxError('TOX_ERR_BOOTSTRAP', val));
52 | }
53 | },
54 |
55 | /**
56 | * Get an Error from a TOX_ERR_DECRYPTION value.
57 | * @private
58 | */
59 | decryption: function(val) {
60 | if(val !== consts.TOX_ERR_DECRYPTION_OK) {
61 | return (new ToxError('TOX_ERR_DECRYPTION', val));
62 | }
63 | },
64 |
65 | /**
66 | * Get an Error from a TOX_ERR_ENCRYPTION value.
67 | * @private
68 | */
69 | encryption: function(val) {
70 | if(val !== consts.TOX_ERR_ENCRYPTION_OK) {
71 | return (new ToxError('TOX_ERR_ENCRYPTION', val));
72 | }
73 | },
74 |
75 | /**
76 | * Get an Error from a TOX_ERR_FILE_CONTROL value.
77 | * @private
78 | */
79 | fileControl: function(val) {
80 | if(val !== consts.TOX_ERR_FILE_CONTROL_OK) {
81 | return (new ToxError('TOX_ERR_FILE_CONTROL', val));
82 | }
83 | },
84 |
85 | /**
86 | * Get an Error from a TOX_ERR_FILE_SEEK value.
87 | * @private
88 | */
89 | fileSeek: function(val) {
90 | if(val !== consts.TOX_ERR_FILE_SEEK_OK) {
91 | return (new ToxError('TOX_ERR_FILE_SEEK', val));
92 | }
93 | },
94 |
95 | /**
96 | * Get an Error from a TOX_ERR_FILE_GET value.
97 | * @private
98 | */
99 | fileGet: function(val) {
100 | if(val !== consts.TOX_ERR_FILE_GET_OK) {
101 | return (new ToxError('TOX_ERR_FILE_GET', val));
102 | }
103 | },
104 |
105 | /**
106 | * Get an Error from a TOX_ERR_FILE_SEND value.
107 | * @private
108 | */
109 | fileSend: function(val) {
110 | if(val !== consts.TOX_ERR_FILE_SEND_OK) {
111 | return (new ToxError('TOX_ERR_FILE_SEND', val));
112 | }
113 | },
114 |
115 | /**
116 | * Get an Error from a TOX_ERR_FILE_SEND_CHUNK value.
117 | * @private
118 | */
119 | fileSendChunk: function(val) {
120 | if(val !== consts.TOX_ERR_FILE_SEND_CHUNK_OK) {
121 | return (new ToxError('TOX_ERR_FILE_SEND_CHUNK', val));
122 | }
123 | },
124 |
125 | /**
126 | * Get an Error from a TOX_ERR_FRIEND_ADD value.
127 | * If none, will return undefined.
128 | * @private
129 | * @param {Number} val - TOX_ERR_FRIEND_ADD value
130 | * @return {ToxError} Error, if any
131 | */
132 | friendAdd: function(val) {
133 | if(val !== consts.TOX_ERR_FRIEND_ADD_OK) {
134 | return (new ToxError('TOX_ERR_FRIEND_ADD', val));
135 | }
136 | },
137 |
138 | /**
139 | * Get an Error from a TOX_ERR_FRIEND_BY_PUBLIC_KEY value.
140 | * If none, will return undefined.
141 | * @private
142 | * @param {Number} val - TOX_ERR_FRIEND_BY_PUBLIC_KEY value
143 | * @return {ToxError} Error, if any
144 | */
145 | friendByPublicKey: function(val) {
146 | if(val !== consts.TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK) {
147 | return (new ToxError('TOX_ERR_FRIEND_BY_PUBLIC_KEY', val));
148 | }
149 | },
150 |
151 | /**
152 | * Get an Error from a TOX_ERR_FRIEND_DELETE value.
153 | * @private
154 | */
155 | friendDelete: function(val) {
156 | if(val !== consts.TOX_ERR_FRIEND_DELETE_OK) {
157 | return (new ToxError('TOX_ERR_FRIEND_DELETE', val));
158 | }
159 | },
160 |
161 | /**
162 | * Get an Error from a TOX_ERR_FRIEND_GET_LAST_ONLINE
163 | * value.
164 | * @private
165 | */
166 | friendGetLastOnline: function(val) {
167 | if(val !== consts.TOX_ERR_FRIEND_GET_LAST_ONLINE_OK) {
168 | return (new ToxError('TOX_ERR_FRIEND_GET_LAST_ONLINE', val));
169 | }
170 | },
171 |
172 | /**
173 | * Get an Error from a TOX_ERR_FRIEND_GET_PUBLIC_KEY value.
174 | * If none, will return undefined.
175 | * @private
176 | * @param {Number} val - TOX_ERR_FRIEND_GET_PUBLIC_KEY value
177 | * @return {ToxError} Error, if any
178 | */
179 | friendGetPublicKey: function(val) {
180 | if(val !== consts.TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK) {
181 | return (new ToxError('TOX_ERR_FRIEND_GET_PUBLIC_KEY', val));
182 | }
183 | },
184 |
185 | /**
186 | * Get an Error from a TOX_ERR_FRIEND_CUSTOM_PACKET value.
187 | * If none, will return undefined.
188 | * @private
189 | * @param {Number} val - TOX_ERR_FRIEND_CUSTOM_PACKET value
190 | * @return {ToxError} Error, if any
191 | */
192 | friendCustomPacket: function(val) {
193 | if(val !== consts.TOX_ERR_FRIEND_CUSTOM_PACKET_OK) {
194 | return (new ToxError('TOX_ERR_FRIEND_CUSTOM_PACKET', val));
195 | }
196 | },
197 |
198 | /**
199 | * Get an Error from a TOX_ERR_FRIEND_QUERY value.
200 | * If none, will return undefined.
201 | * @private
202 | * @param {Number} val - TOX_ERR_FRIEND_QUERY value
203 | * @return {ToxError} Error, if any
204 | */
205 | friendQuery: function(val) {
206 | if(val !== consts.TOX_ERR_FRIEND_QUERY_OK) {
207 | return (new ToxError('TOX_ERR_FRIEND_QUERY', val));
208 | }
209 | },
210 |
211 | /**
212 | * Get an Error from a TOX_ERR_FRIEND_SEND_MESSAGE value.
213 | * If none, will return undefined.
214 | * @private
215 | * @param {Number} val - TOX_ERR_FRIEND_SEND_MESSAGE value
216 | * @return {ToxError} Error, if any
217 | */
218 | friendSendMessage: function(val) {
219 | if(val !== consts.TOX_ERR_FRIEND_SEND_MESSAGE_OK) {
220 | return (new ToxError('TOX_ERR_FRIEND_SEND_MESSAGE', val));
221 | }
222 | },
223 |
224 | /**
225 | * Get an Error from a TOX_ERR_GET_PORT value. If none,
226 | * will return undefined.
227 | * @private
228 | * @param {Number} val - TOX_ERR_GET_PORT value
229 | * @return {ToxError} Error, if any
230 | */
231 | getPort: function(val) {
232 | if(val !== consts.TOX_ERR_GET_PORT_OK) {
233 | return (new ToxError('TOX_ERR_GET_PORT', val));
234 | }
235 | },
236 |
237 | /**
238 | * Get an Error from a TOX_ERR_KEY_DERIVATION value.
239 | * @private
240 | */
241 | keyDerivation: function(val) {
242 | if(val !== consts.TOX_ERR_KEY_DERIVATION_OK) {
243 | return (new ToxError('TOX_ERR_KEY_DERIVATION', val));
244 | }
245 | },
246 |
247 | /**
248 | * Get an Error from a TOX_ERR_SET_INFO value. If none,
249 | * will return undefined.
250 | * @private
251 | * @param {Number} val - TOX_ERR_SET_INFO value
252 | * @return {ToxError} Error, if any
253 | */
254 | setInfo: function(val) {
255 | if(val !== consts.TOX_ERR_SET_INFO_OK) {
256 | return (new ToxError('TOX_ERR_SET_INFO', val));
257 | }
258 | },
259 |
260 | /**
261 | * Get an Error from a TOX_ERR_SET_TYPING value. If none,
262 | * will return undefined.
263 | * @private
264 | * @param {Number} val - TOX_ERR_SET_TYPING value
265 | * @return {ToxError} Error, if any
266 | */
267 | setTyping: function(val) {
268 | if(val !== consts.TOX_ERR_SET_TYPING_OK) {
269 | return (new ToxError('TOX_ERR_SET_TYPING', val));
270 | }
271 | },
272 |
273 | /**
274 | * Get an error for when a function returns unsuccessful, but
275 | * its error value indicates success.
276 | * @private
277 | * @return {ToxError} Error
278 | */
279 | unsuccessful: function() {
280 | return new ToxError('TOX_FUNC_RETURNED_UNSUCCESSFUL', 0, 'api function returned unsuccessful, but error value indicates success');
281 | }
282 | };
283 |
--------------------------------------------------------------------------------
/lib/events.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var buffertools = require('buffertools');
20 | var path = require('path');
21 | var consts = require(path.join(__dirname, 'consts'));
22 |
23 | buffertools.extend();
24 |
25 | /**
26 | * Event object fired by {@class Tox}.
27 | * Corresponds to tox_callback_self_connection_status(3).
28 | * @class
29 | * @param {Number} connectionStatus Connection status
30 | */
31 | var SelfConnectionStatusEvent = function(connectionStatus) {
32 | this.type = 'SelfConnectionStatusEvent';
33 | this._connectionStatus = connectionStatus;
34 | };
35 |
36 | /**
37 | * Get the connection status.
38 | * @return {Number} Connection status value
39 | */
40 | SelfConnectionStatusEvent.prototype.connectionStatus = function() {
41 | return this._connectionStatus;
42 | };
43 |
44 | /**
45 | * Get whether or not the connection status indicates we are connected.
46 | * @return {Boolean} true if connected, false if not
47 | */
48 | SelfConnectionStatusEvent.prototype.isConnected = function() {
49 | return this.connectionStatus() !== consts.TOX_CONNECTION_NONE;
50 | };
51 |
52 | /**
53 | * Event object fired by {@class Tox}.
54 | * Corresponds to tox_callback_friend_name(3).
55 | * @class
56 | * @param {Number} friendnum Friend number
57 | * @param {String} name New name
58 | */
59 | var FriendNameEvent = function(friendnum, name) {
60 | this.type = 'FriendNameEvent';
61 | this._friendnum = friendnum;
62 | this._name = name;
63 | };
64 |
65 | /**
66 | * Get the friend number.
67 | * @return {Number} Friend number
68 | */
69 | FriendNameEvent.prototype.friend = function() {
70 | return this._friendnum;
71 | };
72 |
73 | /**
74 | * Get the new name.
75 | * @return {String} New name
76 | */
77 | FriendNameEvent.prototype.name = function() {
78 | return this._name;
79 | };
80 |
81 | /**
82 | * Event object fired by {@class Tox}.
83 | * Corresponds to tox_callback_friend_status_message(3).
84 | * @class
85 | * @param {Number} friendnum Friend number
86 | * @param {String} statusMessage New status message
87 | */
88 | var FriendStatusMessageEvent = function(friendnum, statusMessage) {
89 | this.type = 'FriendStatusMessageEvent';
90 | this._friendnum = friendnum;
91 | this._statusMessage = statusMessage;
92 | };
93 |
94 | /**
95 | * Get the friend number.
96 | * @return {Number} Friend number
97 | */
98 | FriendStatusMessageEvent.prototype.friend = function() {
99 | return this._friendnum;
100 | };
101 |
102 | /**
103 | * Get the new status message.
104 | * @return {String} New status message
105 | */
106 | FriendStatusMessageEvent.prototype.statusMessage = function() {
107 | return this._statusMessage;
108 | };
109 |
110 | /**
111 | * Event object fired by {@class Tox}.
112 | * Corresponds to tox_callback_friend_status(3).
113 | * @class
114 | * @param {Number} friendnum Friend number
115 | * @param {Number} status New status
116 | */
117 | var FriendStatusEvent = function(friendnum, status) {
118 | this.type = 'FriendStatusEvent';
119 | this._friendnum = friendnum;
120 | this._status = status;
121 | };
122 |
123 | /**
124 | * Get the friend number.
125 | * @return {Number} Friend number
126 | */
127 | FriendStatusEvent.prototype.friend = function() {
128 | return this._friendnum;
129 | };
130 |
131 | /**
132 | * Get the new status.
133 | * @return {Number} New status
134 | */
135 | FriendStatusEvent.prototype.status = function() {
136 | return this._status;
137 | };
138 |
139 | /**
140 | * Event object fired by {@class Tox}.
141 | * Corresponds to tox_callback_friend_connection_status(3).
142 | * @class
143 | * @param {Number} friendnum Friend number
144 | * @param {Number} connectionStatus New connection status
145 | */
146 | var FriendConnectionStatusEvent = function(friendnum, connectionStatus) {
147 | this.type = 'FriendConnectionStatusEvent';
148 | this._friendnum = friendnum;
149 | this._connectionStatus = connectionStatus;
150 | };
151 |
152 | /**
153 | * Get the friend number.
154 | * @return {Number} Friend number
155 | */
156 | FriendConnectionStatusEvent.prototype.friend = function() {
157 | return this._friendnum;
158 | };
159 |
160 | /**
161 | * Get the new connection status value.
162 | * @return {Number} New connection status value
163 | */
164 | FriendConnectionStatusEvent.prototype.connectionStatus = function() {
165 | return this._connectionStatus;
166 | };
167 |
168 | /**
169 | * Get whether or not this friend has connected.
170 | * @return {Boolean} true if connected, false if not
171 | */
172 | FriendConnectionStatusEvent.prototype.isConnected = function() {
173 | return this.connectionStatus() !== consts.TOX_CONNECTION_NONE;
174 | };
175 |
176 | /**
177 | * Event object fired by {@class Tox}.
178 | * Corresponds to tox_callback_friend_typing(3).
179 | * @class
180 | * @param {Number} friendnum Friend number
181 | * @param {Boolean} typing Typing
182 | */
183 | var FriendTypingEvent = function(friendnum, typing) {
184 | this.type = 'FriendTypingEvent';
185 | this._friendnum = friendnum;
186 | this._typing = typing;
187 | };
188 |
189 | /**
190 | * Get the friend number.
191 | * @return {Number} Friend number
192 | */
193 | FriendTypingEvent.prototype.friend = function() {
194 | return this._friendnum;
195 | };
196 |
197 | /**
198 | * Get whether or not this friend is typing.
199 | * @return {Boolean} true if typing, false if not
200 | */
201 | FriendTypingEvent.prototype.isTyping = function() {
202 | return this._typing;
203 | };
204 |
205 | /**
206 | * Event object fired by {@class Tox}.
207 | * Corresponds to tox_callback_friend_read_receipt(3).
208 | * @class
209 | * @param {Number} friendnum Friend number
210 | * @param {Number} receipt Receipt
211 | */
212 | var FriendReadReceiptEvent = function(friendnum, receipt) {
213 | this.type = 'FriendReadReceiptEvent';
214 | this._friendnum = friendnum;
215 | this._receipt = receipt;
216 | };
217 |
218 | /**
219 | * Get the friend number.
220 | * @return {Number} Friend number
221 | */
222 | FriendReadReceiptEvent.prototype.friend = function() {
223 | return this._friendnum;
224 | };
225 |
226 | /**
227 | * Get the receipt.
228 | * @return {Number} Receipt
229 | */
230 | FriendReadReceiptEvent.prototype.receipt = function() {
231 | return this._receipt;
232 | };
233 |
234 | /**
235 | * Event object fired by {@class Tox}.
236 | * Corresponds to tox_callback_friend_request(3).
237 | * @class
238 | * @param {Buffer} publicKey Public key of requester
239 | * @param {String} message Message sent along with the request
240 | */
241 | var FriendRequestEvent = function(publicKey, message) {
242 | this.type = 'FriendRequestEvent';
243 | this._publicKey = publicKey;
244 | this._message = message;
245 | };
246 |
247 | /**
248 | * Get the public key.
249 | * @return {Buffer} Public key
250 | */
251 | FriendRequestEvent.prototype.publicKey = function() {
252 | return this._publicKey;
253 | };
254 |
255 | /**
256 | * Get the public key as a hex String.
257 | * @return {String} Public key as a hex String
258 | */
259 | FriendRequestEvent.prototype.publicKeyHex = function() {
260 | return this._publicKey.toHex().toString();
261 | };
262 |
263 | /**
264 | * Get the message.
265 | * @return {String} Message
266 | */
267 | FriendRequestEvent.prototype.message = function() {
268 | return this._message;
269 | };
270 |
271 | /**
272 | * Event object fired by {@class Tox}.
273 | * Corresponds to tox_callback_friend_message(3).
274 | * @class
275 | * @param {Number} friendnum Friend number
276 | * @param {Number} type Message type
277 | * @param {String} message Message
278 | */
279 | var FriendMessageEvent = function(friendnum, type, message) {
280 | this.type = 'FriendMessageEvent';
281 | this._friendnum = friendnum;
282 | this._message = message;
283 | this._messageType = type;
284 | };
285 |
286 | /**
287 | * Get the friend number.
288 | * @return {Number} Friend number
289 | */
290 | FriendMessageEvent.prototype.friend = function() {
291 | return this._friendnum;
292 | };
293 |
294 | /**
295 | * Get the message.
296 | * @return {String} Message
297 | */
298 | FriendMessageEvent.prototype.message = function() {
299 | return this._message;
300 | };
301 |
302 | /**
303 | * Get the message type.
304 | * @return {Number} Message type
305 | */
306 | FriendMessageEvent.prototype.messageType = function() {
307 | return this._messageType;
308 | };
309 |
310 | /**
311 | * Whether or not the message was normal.
312 | * @return {Boolean} true if normal, false if not
313 | */
314 | FriendMessageEvent.prototype.isNormal = function() {
315 | return this.messageType() === consts.TOX_MESSAGE_TYPE_NORMAL;
316 | };
317 |
318 | /**
319 | * Whether or not the message was an action.
320 | * @return {Boolean} true if action, false if not
321 | */
322 | FriendMessageEvent.prototype.isAction = function() {
323 | return this.messageType() === consts.TOX_MESSAGE_TYPE_ACTION;
324 | };
325 |
326 | /**
327 | * Event object fired by {@class Tox}.
328 | * Corresponds to tox_callback_file_recv_control(3).
329 | * @class
330 | * @param {Number} friendnum - Friend number
331 | * @param {Number} filenum - File number
332 | * @param {Number} control - TOX_FILE_CONTROL type
333 | */
334 | var FileRecvControlEvent = function(friendnum, filenum, control) {
335 | this.type = 'FileRecvControlEvent';
336 | this._friendnum = friendnum;
337 | this._filenum = filenum;
338 | this._control = control;
339 | };
340 |
341 | /**
342 | * Get the friend number.
343 | * @return {Number} Friend number
344 | */
345 | FileRecvControlEvent.prototype.friend = function() {
346 | return this._friendnum;
347 | };
348 |
349 | /**
350 | * Get the file number.
351 | * @return {Number} File number
352 | */
353 | FileRecvControlEvent.prototype.file = function() {
354 | return this._filenum;
355 | };
356 |
357 | /**
358 | * Get the control type.
359 | * @return {Number} Control
360 | */
361 | FileRecvControlEvent.prototype.control = function() {
362 | return this._control;
363 | };
364 |
365 | /**
366 | * Get the control type name as a string.
367 | * @return {String} Control name, or 'unknown' if unknown
368 | */
369 | FileRecvControlEvent.prototype.controlName = function() {
370 | var c = this._control;
371 | if(c === consts.TOX_FILE_CONTROL_CANCEL) {
372 | return 'cancel';
373 | } else if(c === consts.TOX_FILE_CONTROL_PAUSE) {
374 | return 'pause';
375 | } else if(c === consts.TOX_FILE_CONTROL_RESUME) {
376 | return 'resume';
377 | } else {
378 | return 'unknown';
379 | }
380 | };
381 |
382 | /**
383 | * Whether or not this is a 'cancel' control.
384 | * @return {Boolean} true if cancel, false if not
385 | */
386 | FileRecvControlEvent.prototype.isCancel = function() {
387 | return this._control === consts.TOX_FILE_CONTROL_CANCEL;
388 | };
389 |
390 | /**
391 | * Whether or not this is a 'pause' control.
392 | * @return {Boolean} true if pause, false if not
393 | */
394 | FileRecvControlEvent.prototype.isPause = function() {
395 | return this._control === consts.TOX_FILE_CONTROL_PAUSE;
396 | };
397 |
398 | /**
399 | * Whether or not this is a 'resume' control.
400 | * @return {Boolean} true if resume, false if not
401 | */
402 | FileRecvControlEvent.prototype.isResume = function() {
403 | return this._control === consts.TOX_FILE_CONTROL_RESUME;
404 | };
405 |
406 | /**
407 | * Event object fired by {@class Tox}.
408 | * Corresponds to tox_callback_file_chunk_request(3).
409 | * @class
410 | * @param {Number} friendnum - Friend number
411 | * @param {Number} filenum - File number
412 | * @param {Number} position - Position
413 | * @param {Number} length - Chunk size
414 | * @note position is a uint64_t, length is a size_t
415 | */
416 | var FileChunkRequestEvent = function(friendnum, filenum, position, length) {
417 | this.type = 'FileChunkRequestEvent';
418 | this._friendnum = friendnum;
419 | this._filenum = filenum;
420 | this._position = position;
421 | this._length = length;
422 | };
423 |
424 | /**
425 | * Get the friend number.
426 | * @return {Number} Friend number
427 | */
428 | FileChunkRequestEvent.prototype.friend = function() {
429 | return this._friendnum;
430 | };
431 |
432 | /**
433 | * Get the file number.
434 | * @return {Number} File number
435 | */
436 | FileChunkRequestEvent.prototype.file = function() {
437 | return this._filenum;
438 | };
439 |
440 | /**
441 | * Get the position.
442 | * @return {Number} Position
443 | */
444 | FileChunkRequestEvent.prototype.position = function() {
445 | return this._position;
446 | };
447 |
448 | /**
449 | * Get the length (chunk size).
450 | * @return {Number} Length
451 | */
452 | FileChunkRequestEvent.prototype.length = function() {
453 | return this._length;
454 | };
455 |
456 | /**
457 | * Event object fired by {@class Tox}.
458 | * Corresponds to tox_callback_file_recv(3).
459 | * @class
460 | * @param {Number} friendnum - Friend number
461 | * @param {Number} filenum - File number
462 | * @param {Number} kind - File kind
463 | * @param {Number} size - File size
464 | * @param {String} filename - Filename
465 | * @note size is a uint64_t
466 | */
467 | var FileRecvEvent = function(friendnum, filenum, kind, size, filename) {
468 | this.type = 'FileRecvEvent';
469 | this._friendnum = friendnum;
470 | this._filenum = filenum;
471 | this._kind = kind;
472 | this._size = size;
473 | this._filename = filename;
474 | };
475 |
476 | /**
477 | * Get the friend number.
478 | * @return {Number} Friend number
479 | */
480 | FileRecvEvent.prototype.friend = function() {
481 | return this._friendnum;
482 | };
483 |
484 | /**
485 | * Get the file number.
486 | * @return {Number} File number
487 | */
488 | FileRecvEvent.prototype.file = function() {
489 | return this._filenum;
490 | };
491 |
492 | /**
493 | * Get the file kind.
494 | * @return {Number} Kind
495 | */
496 | FileRecvEvent.prototype.kind = function() {
497 | return this._kind;
498 | };
499 |
500 | /**
501 | * Get the file size.
502 | * @return {Number} Size
503 | */
504 | FileRecvEvent.prototype.size = function() {
505 | return this._size;
506 | };
507 |
508 | /**
509 | * Get the filename. May be undefined if file kind is non-DATA.
510 | * @return {Number} Filename
511 | */
512 | FileRecvEvent.prototype.filename = function() {
513 | return this._filename;
514 | };
515 |
516 | /**
517 | * Event object fired by {@class Tox}.
518 | * Corresponds to tox_callback_file_recv_chunk(3).
519 | * @class
520 | * @param {Number} friendnum - Friend number
521 | * @param {Number} filenum - File number
522 | * @param {Number} position - Position
523 | * @param {Buffer} data - Chunk data
524 | * @note size is a uint64_t
525 | */
526 | var FileRecvChunkEvent = function(friendnum, filenum, position, data) {
527 | this.type = 'FileRecvChunkEvent';
528 | this._friendnum = friendnum;
529 | this._filenum = filenum;
530 | this._position = position;
531 | this._data = data;
532 | };
533 |
534 | /**
535 | * Get the friend number.
536 | * @return {Number} Friend number
537 | */
538 | FileRecvChunkEvent.prototype.friend = function() {
539 | return this._friendnum;
540 | };
541 |
542 | /**
543 | * Get the file number.
544 | * @return {Number} File number
545 | */
546 | FileRecvChunkEvent.prototype.file = function() {
547 | return this._filenum;
548 | };
549 |
550 | /**
551 | * Get the position.
552 | * @return {Number} Position
553 | */
554 | FileRecvChunkEvent.prototype.position = function() {
555 | return this._position;
556 | };
557 |
558 | /**
559 | * Get the chunk data.
560 | * @return {Buffer} Data
561 | */
562 | FileRecvChunkEvent.prototype.data = function() {
563 | return this._data;
564 | };
565 |
566 | /**
567 | * Get the chunk length. If no received chunk (NULL), will return 0.
568 | * @return {Number} Chunk length
569 | */
570 | FileRecvChunkEvent.prototype.length = function() {
571 | return (this.isNull() ? 0 : this.data().length);
572 | };
573 |
574 | /**
575 | * Checks if this is the final chunk (if length is 0).
576 | * @return {Boolean} true if final chunk, false if not
577 | */
578 | FileRecvChunkEvent.prototype.isFinal = function() {
579 | return this.length() === 0;
580 | };
581 |
582 | /**
583 | * Whether or not the data buffer is undefined, which means the Buffer
584 | * from the tox callback pointed to 0 (NULL). This should only happen
585 | * on the final chunk with a length of 0?
586 | * @return {Boolean} true if null, false if not
587 | */
588 | FileRecvChunkEvent.prototype.isNull = function() {
589 | return this.data() === undefined;
590 | };
591 |
592 | /**
593 | * Event object fired by {@class Tox}.
594 | * Corresponds to tox_callback_friend_lossless_packet(3)
595 | * and tox_callback_friend_lossy_packet(3).
596 | * @class
597 | * @param {Number} friendnum - Friend number
598 | * @param {Buffer} data - Received data
599 | * @param {Boolean} lossless - true if lossless, false if lossy
600 | */
601 | var FriendPacketEvent = function(friendnum, data, lossless) {
602 | this.type = 'FriendPacketEvent';
603 | this._friendnum = friendnum;
604 | this._fullData = data;
605 | this._data = data.slice(1);
606 | this._id = data[0];
607 | this._lossless = lossless;
608 | };
609 |
610 | /**
611 | * Get the friend number.
612 | * @return {Number} Friend number
613 | */
614 | FriendPacketEvent.prototype.friend = function() {
615 | return this._friendnum;
616 | };
617 |
618 | /**
619 | * Get the packet data.
620 | * @return {Buffer} Data
621 | */
622 | FriendPacketEvent.prototype.fullData = function() {
623 | return this._fullData;
624 | };
625 |
626 | /**
627 | * Get the packet data without the leading byte Id.
628 | * @return {Buffer} Data
629 | */
630 | FriendPacketEvent.prototype.data = function() {
631 | return this._data;
632 | };
633 |
634 | /**
635 | * Get the data length. If no received data (NULL), will return 0.
636 | * @return {Number} Data length (excluding leading byte Id)
637 | */
638 | FriendPacketEvent.prototype.length = function(){
639 | return (!this._data ? 0 : this.data().length);
640 | };
641 |
642 | /**
643 | * Get the leading byte Id.
644 | * @return {Number} Id
645 | */
646 | FriendPacketEvent.prototype.id = function() {
647 | return this._id;
648 | };
649 |
650 | /**
651 | * Whether or not the received packet was lossless.
652 | * @return {Boolean} true if lossless, false if lossy
653 | */
654 | FriendPacketEvent.prototype.isLossless = function() {
655 | return this._lossless;
656 | };
657 |
658 | /**
659 | * Whether or not the received packet was lossy.
660 | * @return {Boolean} true if lossy, false if lossless
661 | */
662 | FriendPacketEvent.prototype.isLossy = function() {
663 | return !this._lossless;
664 | };
665 |
666 | module.exports = {
667 | SelfConnectionStatusEvent: SelfConnectionStatusEvent,
668 | FriendNameEvent: FriendNameEvent,
669 | FriendStatusMessageEvent: FriendStatusMessageEvent,
670 | FriendStatusEvent: FriendStatusEvent,
671 | FriendConnectionStatusEvent: FriendConnectionStatusEvent,
672 | FriendTypingEvent: FriendTypingEvent,
673 | FriendReadReceiptEvent: FriendReadReceiptEvent,
674 | FriendRequestEvent: FriendRequestEvent,
675 | FriendMessageEvent: FriendMessageEvent,
676 | FileRecvControlEvent: FileRecvControlEvent,
677 | FileChunkRequestEvent: FileChunkRequestEvent,
678 | FileRecvEvent: FileRecvEvent,
679 | FileRecvChunkEvent: FileRecvChunkEvent,
680 | FriendPacketEvent: FriendPacketEvent
681 | };
682 |
--------------------------------------------------------------------------------
/lib/main.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var path = require('path');
20 | var tox = require(path.join(__dirname, 'tox'));
21 | var toxdns = require(path.join(__dirname, 'toxdns'));
22 | var toxencryptsave = require(path.join(__dirname, 'toxencryptsave'));
23 | var consts = require(path.join(__dirname, 'consts'));
24 |
25 | module.exports = {
26 | Tox: tox,
27 | ToxDns: toxdns,
28 | ToxEncryptSave: toxencryptsave,
29 | Consts: consts
30 | };
31 |
--------------------------------------------------------------------------------
/lib/old/consts.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var _ = require('underscore');
20 | var consts = {
21 | TOX_KEY_SIZE: 32,
22 | TOX_FRIEND_ADDRESS_SIZE: (32 + 6),
23 | TOX_MAX_NAME_LENGTH: 128,
24 | TOX_MAX_STATUS_MESSAGE_LENGTH: 1007,
25 | TOX_MAX_MESSAGE_LENGTH: 1368,
26 | TOX_HASH_LENGTH: 32,
27 | TOX_AVATAR_MAX_DATA_LENGTH: 16384,
28 | TOX_GROUPCHAT_TYPE_TEXT: 0,
29 | TOX_GROUPCHAT_TYPE_AV: 1,
30 | TOX_PROXY_NONE: 0,
31 | TOX_PROXY_SOCKS5: 1,
32 | TOX_PROXY_HTTP: 2,
33 | TOX_SALT_LENGTH: 32,
34 | TOXDNS_MAX_RECOMMENDED_NAME_LENGTH: 32
35 | };
36 |
37 | /**
38 | * Make TOX_* consts global.
39 | */
40 | consts.globalify = function() {
41 | _.each(consts, function(value, key, list) {
42 | if(key.match(/^TOX/)) {
43 | global[key] = value;
44 | }
45 | });
46 | };
47 |
48 | module.exports = consts;
49 |
--------------------------------------------------------------------------------
/lib/old/errors.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | /**
20 | * Create an Error for when library functions return negative
21 | * value unexpectedly.
22 | * @param {String} fname Function name
23 | * @param {Number} val Return value
24 | * @return {Error} Error object
25 | */
26 | var createNegativeReturnError = function(fname, val) {
27 | var err = new Error('Negative return value for ' + fname);
28 | err.tox = { name: fname, returned: val };
29 | return err;
30 | };
31 |
32 | /**
33 | * Create an Error for when library functions return non-one values
34 | * unexpectedly.
35 | * @param {String} fname Function name
36 | * @param {Number} val Return value
37 | * @return {Error} Error object
38 | */
39 | var createNonOneReturnError = function(fname, val) {
40 | var error = new Error('Non-one return value for ' + fname);
41 | error.tox = { name: fname, returned: val };
42 | return error;
43 | };
44 |
45 | /**
46 | * Create an Error for when library functions return non-positive
47 | * value unexpectedly.
48 | * @param {String} fname Function name
49 | * @param {Number} val Return value
50 | * @return {Error} Error object
51 | */
52 | var createNonPositiveReturnError = function(fname, val) {
53 | var err = new Error('Non-positive return value for ' + fname);
54 | err.tox = { name: fname, returned: val };
55 | return err;
56 | };
57 |
58 | /**
59 | * Create an Error for when library functions return non-zero values
60 | * unexpectedly.
61 | * @param {String} fname Function name
62 | * @param {Number} val Return value
63 | * @return {Error} Error object
64 | */
65 | var createNonZeroReturnError = function(fname, val) {
66 | var error = new Error('Non-zero return value for ' + fname);
67 | error.tox = { name: fname, returned: val };
68 | return error;
69 | };
70 |
71 | /**
72 | * Create an Error for when library functions return unexpected values.
73 | * @param {String} fname Function name
74 | * @param {Number} val Return value
75 | * @param {Number} expected Expected value
76 | * @return {Error} Error object
77 | */
78 | var createReturnError = function(fname, val, expected) {
79 | var error = new Error('Unexpected return value for ' + fname);
80 | error.tox = { name: fname, returned: val, expected: expected };
81 | return error;
82 | };
83 |
84 | /**
85 | * Create an error for when a Tox object is missing a handle.
86 | * @return {Error} Error object
87 | */
88 | var createToxNoHandleError = function() {
89 | return new Error('Tox object has no handle');
90 | };
91 |
92 | /**
93 | * Create an error for when some input is not a valid tox address.
94 | * @param {Object} badAddr - Bad address input
95 | * @return {Error} Error object
96 | */
97 | var createInvalidToxAddressError = function(badAddr) {
98 | var error = new Error('Not a valid tox address: ' + badAddr);
99 | error.tox = { badAddr: badAddr };
100 | return error;
101 | };
102 |
103 | module.exports = {
104 | createInvalidToxAddressError: createInvalidToxAddressError,
105 | createNegativeReturnError: createNegativeReturnError,
106 | createNonOneReturnError: createNonOneReturnError,
107 | createNonPositiveReturnError: createNonPositiveReturnError,
108 | createNonZeroReturnError: createNonZeroReturnError,
109 | createReturnError: createReturnError,
110 | createToxNoHandleError: createToxNoHandleError
111 | };
112 |
--------------------------------------------------------------------------------
/lib/old/events.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var buffertools = require('buffertools');
20 | buffertools.extend();
21 |
22 | var TOX_GROUPCHAT_TYPE_TEXT = 0;
23 | var TOX_GROUPCHAT_TYPE_AV = 1;
24 |
25 | /**
26 | * Event object fired by {@class Tox}.
27 | * Corresponds to tox_callback_friend_request(3).
28 | * @class
29 | * @param {Buffer} publicKey Public key of requester
30 | * @param {Buffer} data Data required to accept the request
31 | */
32 | var FriendRequestEvent = function(publicKey, data) {
33 | this.type = 'FriendRequestEvent';
34 | this._publicKey = publicKey;
35 | this._data = data;
36 | };
37 |
38 | /**
39 | * Get the public key.
40 | * @return {Buffer} Public key
41 | */
42 | FriendRequestEvent.prototype.publicKey = function() {
43 | return this._publicKey;
44 | };
45 |
46 | /**
47 | * Get the public key as a hex String.
48 | * @return {String} Public key as a hex String
49 | */
50 | FriendRequestEvent.prototype.publicKeyHex = function() {
51 | return this._publicKey.toHex().toString();
52 | };
53 |
54 | /**
55 | * Get the data.
56 | * @return {Buffer} Data
57 | */
58 | FriendRequestEvent.prototype.data = function() {
59 | return this._data;
60 | };
61 |
62 | /**
63 | * Event object fired by {@class Tox}.
64 | * Corresponds to tox_callback_friend_message(3).
65 | * @class
66 | * @param {Number} friendnum Friend number
67 | * @param {String} message Message
68 | */
69 | var FriendMessageEvent = function(friendnum, message) {
70 | this.type = 'FriendMessageEvent';
71 | this._friendnum = friendnum;
72 | this._message = message;
73 | };
74 |
75 | /**
76 | * Get the friend number.
77 | * @return {Number} Friend number
78 | */
79 | FriendMessageEvent.prototype.friend = function() {
80 | return this._friendnum;
81 | };
82 |
83 | /**
84 | * Get the message.
85 | * @return {String} Message
86 | */
87 | FriendMessageEvent.prototype.message = function() {
88 | return this._message;
89 | };
90 |
91 | /**
92 | * Event object fired by {@class Tox}.
93 | * Corresponds to tox_callback_friend_action(3).
94 | * @class
95 | * @param {Number} friendnum Friend number
96 | * @param {String} action Action
97 | */
98 | var FriendActionEvent = function(friendnum, action) {
99 | this.type = 'FriendActionEvent';
100 | this._friendnum = friendnum;
101 | this._action = action;
102 | };
103 |
104 | /**
105 | * Get the friend number.
106 | * @return {Number} Friend number
107 | */
108 | FriendActionEvent.prototype.friend = function() {
109 | return this._friendnum;
110 | };
111 |
112 | /**
113 | * Get the action.
114 | * @return {String} Action
115 | */
116 | FriendActionEvent.prototype.action = function() {
117 | return this._action;
118 | };
119 |
120 | /**
121 | * Event object fired by {@class Tox}.
122 | * Corresponds to tox_callback_name_change(3).
123 | * @class
124 | * @param {Number} friendnum Friend number
125 | * @param {String} name New name
126 | */
127 | var NameChangeEvent = function(friendnum, name) {
128 | this.type = 'NameChangeEvent';
129 | this._friendnum = friendnum;
130 | this._name = name;
131 | };
132 |
133 | /**
134 | * Get the friend number.
135 | * @return {Number} Friend number
136 | */
137 | NameChangeEvent.prototype.friend = function() {
138 | return this._friendnum;
139 | };
140 |
141 | /**
142 | * Get the new name.
143 | * @return {String} New name
144 | */
145 | NameChangeEvent.prototype.name = function() {
146 | return this._name;
147 | };
148 |
149 | /**
150 | * Event object fired by {@class Tox}.
151 | * Corresponds to tox_callback_status_message(3).
152 | * @class
153 | * @param {Number} friendnum Friend number
154 | * @param {String} message Status message
155 | */
156 | var StatusMessageEvent = function(friendnum, message) {
157 | this.type = 'StatusMessageEvent';
158 | this._friendnum = friendnum;
159 | this._message = message;
160 | };
161 |
162 | /**
163 | * Get the friend number.
164 | * @return {Number} Friend number
165 | */
166 | StatusMessageEvent.prototype.friend = function() {
167 | return this._friendnum;
168 | };
169 |
170 | /**
171 | * Get the status message.
172 | * @return {String} Status message
173 | */
174 | StatusMessageEvent.prototype.statusMessage = function() {
175 | return this._message;
176 | };
177 |
178 | /**
179 | * Event object fired by {@class Tox}.
180 | * Corresponds to tox_callback_user_status(3).
181 | * @class
182 | * @param {Number} friendnum Friend number
183 | * @param {Number} status User status
184 | */
185 | var UserStatusEvent = function(friendnum, status) {
186 | this.type = 'UserStatusEvent';
187 | this._friendnum = friendnum;
188 | this._status = status;
189 | };
190 |
191 | /**
192 | * Get the friend number.
193 | * @return {Number} Friend number
194 | */
195 | UserStatusEvent.prototype.friend = function() {
196 | return this._friendnum;
197 | };
198 |
199 | /**
200 | * Get the user status.
201 | * @return {Number} User status
202 | */
203 | UserStatusEvent.prototype.status = function() {
204 | return this._status;
205 | };
206 |
207 | /**
208 | * Event object fired by {@class Tox}.
209 | * Corresponds to tox_callback_typing_change(3).
210 | * @class
211 | * @param {Number} friendnum Friend number
212 | * @param {Boolean} typing Whether or not the friend is typing
213 | */
214 | var TypingChangeEvent = function(friendnum, typing) {
215 | this.type = 'TypingChangeEvent';
216 | this._friendnum = friendnum;
217 | this._typing = (typing === true || typing === 1);
218 | };
219 |
220 | /**
221 | * Get the friend number.
222 | * @return {Number} Friend number
223 | */
224 | TypingChangeEvent.prototype.friend = function() {
225 | return this._friendnum;
226 | };
227 |
228 | /**
229 | * Whether or not the friend is typing.
230 | * @return {Boolean} true if typing, false if not typing
231 | */
232 | TypingChangeEvent.prototype.typing = function() {
233 | return this._typing;
234 | };
235 |
236 | /**
237 | * Event object fired by {@class Tox}.
238 | * Corresponds to tox_callback_read_receipt(3).
239 | * @class
240 | * @param {Number} friendnum Friend number
241 | * @param {Number} receipt Receipt
242 | */
243 | var ReadReceiptEvent = function(friendnum, receipt) {
244 | this.type = 'ReadReceiptEvent';
245 | this._friendnum = friendnum;
246 | this._receipt = receipt;
247 | };
248 |
249 | /**
250 | * Get the friend number.
251 | * @return {Number} Friend number
252 | */
253 | ReadReceiptEvent.prototype.friend = function() {
254 | return this._friendnum;
255 | };
256 |
257 | /**
258 | * Get the receipt.
259 | * @return {Number} Receipt
260 | */
261 | ReadReceiptEvent.prototype.receipt = function() {
262 | return this._receipt;
263 | };
264 |
265 | /**
266 | * Event object fired by {@class Tox}.
267 | * Corresponds to tox_callback_connection_status(3).
268 | * @class
269 | * @param {Number} friendnum Friend number
270 | * @param {Number} status Connection status (0 = went offline after previously online, 1 = went online)
271 | */
272 | var ConnectionStatusEvent = function(friendnum, status) {
273 | this.type = 'ConnectionStatusEvent';
274 | this._friendnum = friendnum;
275 | this._status = status;
276 | };
277 |
278 | /**
279 | * Get the friend number.
280 | * @return {Number} Friend number
281 | */
282 | ConnectionStatusEvent.prototype.friend = function() {
283 | return this._friendnum;
284 | };
285 |
286 | /**
287 | * Get the connection status identifier.
288 | * @return {Number} Connection status identifier
289 | */
290 | ConnectionStatusEvent.prototype.status = function() {
291 | return this._status;
292 | };
293 |
294 | /**
295 | * Get the connection status as a String.
296 | * @return {String} 'online' if online, 'offline' if offline
297 | */
298 | ConnectionStatusEvent.prototype.statusString = function() {
299 | return (this.status() === 1 ? 'online' : 'offline');
300 | };
301 |
302 | /**
303 | * Whether or not the friend is connected.
304 | * @return {Boolean} true if connected, false if not
305 | */
306 | ConnectionStatusEvent.prototype.isConnected = function() {
307 | return (this.status() === 1);
308 | };
309 |
310 | /**
311 | * Event object fired by {@class Tox}.
312 | * Corresponds to tox_callback_avatar_info(3).
313 | * @class
314 | * @param {Number} friendnum Friend number
315 | * @param {Number} format Format identifier, corresponds to TOX_AVATAR_FORMAT
316 | * @param {Buffer} hash Hash (length is always TOX_HASH_LENGTH)
317 | */
318 | var AvatarInfoEvent = function(friendnum, format, hash) {
319 | this.type = 'AvatarInfoEvent';
320 | this._friendnum = friendnum;
321 | this._format = format;
322 | this._hash = hash;
323 | };
324 |
325 | /**
326 | * Get the friend number.
327 | * @return {Number} Friend number
328 | */
329 | AvatarInfoEvent.prototype.friend = function() {
330 | return this._friendnum;
331 | };
332 |
333 | /**
334 | * Get the format identifier.
335 | * @return {Number} Format identifier
336 | */
337 | AvatarInfoEvent.prototype.format = function() {
338 | return this._format;
339 | };
340 |
341 | /**
342 | * Get the hash.
343 | * @return {Buffer} Hash
344 | */
345 | AvatarInfoEvent.prototype.hash = function() {
346 | return this._hash;
347 | };
348 |
349 | /**
350 | * Get the hash as a hex String.
351 | * @return {String} Hash as a hex String
352 | */
353 | AvatarInfoEvent.prototype.hashHex = function() {
354 | return this._hash.toHex().toString();
355 | };
356 |
357 | /**
358 | * Checks whether or not the avatar appears valid. For now,
359 | * just checks that the format isn't TOX_AVATAR_FORMAT_NONE (0).
360 | * @return {Boolean} true if seemingly valid, false if not
361 | */
362 | AvatarInfoEvent.prototype.isValid = function() {
363 | return this.format() !== 0;
364 | };
365 |
366 | /**
367 | * Event object fired by {@class Tox}.
368 | * Corresponds to tox_callback_avatar_data(3).
369 | * @class
370 | * @param {Number} friendnum Friend number
371 | * @param {Number} format Format identifier, corresponds to TOX_AVATAR_FORMAT
372 | * @param {Buffer} hash Hash (length is always TOX_HASH_LENGTH)
373 | * @param {Buffer} data Data
374 | */
375 | var AvatarDataEvent = function(friendnum, format, hash, data) {
376 | this.type = 'AvatarDataEvent';
377 | this._friendnum = friendnum;
378 | this._format = format;
379 | this._hash = hash;
380 | this._data = data;
381 | };
382 |
383 | /**
384 | * Get the friend number.
385 | * @return {Number} Friend number
386 | */
387 | AvatarDataEvent.prototype.friend = function() {
388 | return this._friendnum;
389 | };
390 |
391 | /**
392 | * Get the format identifier.
393 | * @return {Number} Format identifier
394 | */
395 | AvatarDataEvent.prototype.format = function() {
396 | return this._format;
397 | };
398 |
399 | /**
400 | * Get the hash.
401 | * @return {Buffer} Hash
402 | */
403 | AvatarDataEvent.prototype.hash = function() {
404 | return this._hash;
405 | };
406 |
407 | /**
408 | * Get the hash as a hex String.
409 | * @return {String} Hash as a hex String
410 | */
411 | AvatarDataEvent.prototype.hashHex = function() {
412 | return this._hash.toHex().toString();
413 | };
414 |
415 | /**
416 | * Get the data.
417 | * @return {Buffer} Data
418 | */
419 | AvatarDataEvent.prototype.data = function() {
420 | return this._data;
421 | };
422 |
423 | /**
424 | * Checks whether or not the avatar appears valid. For now,
425 | * just checks that the format isn't TOX_AVATAR_FORMAT_NONE (0).
426 | * @return {Boolean} true if seemingly valid, false if not
427 | */
428 | AvatarDataEvent.prototype.isValid = function() {
429 | return this.format() !== 0;
430 | };
431 |
432 | /**
433 | * Event object fired by {@class Tox}.
434 | * Corresponds to tox_callback_group_invite(3).
435 | * @class
436 | * @param {Number} friendnum Friend number
437 | * @param {Number} chatType Chat type, corresponds to TOX_GROUPCHAT_TYPE_*
438 | * @param {Buffer} data Data required for accepting the invite
439 | */
440 | var GroupInviteEvent = function(friendnum, chatType, data) {
441 | this.type = 'GroupInviteEvent';
442 | this._friendnum = friendnum;
443 | this._chatType = chatType;
444 | this._data = data;
445 | };
446 |
447 | /**
448 | * Get the friend number.
449 | * @return {Number} Friend number
450 | */
451 | GroupInviteEvent.prototype.friend = function() {
452 | return this._friendnum;
453 | };
454 |
455 | /**
456 | * Get the invite chat type.
457 | * @return {Number} Invite chat type
458 | */
459 | GroupInviteEvent.prototype.chatType = function() {
460 | return this._chatType;
461 | };
462 |
463 | /**
464 | * Whether or not this is an invite to a text chat.
465 | * @return true if text chat invite, false if not
466 | */
467 | GroupInviteEvent.prototype.isChatText = function() {
468 | return this.chatType() === TOX_GROUPCHAT_TYPE_TEXT;
469 | };
470 |
471 | /**
472 | * Whether or not this is an invite to an audio/video chat.
473 | * @return true if audio/video chat invite, false if not
474 | */
475 | GroupInviteEvent.prototype.isChatAV = function() {
476 | return this.chatType() === TOX_GROUPCHAT_TYPE_AV;
477 | };
478 |
479 | /**
480 | * Get the data.
481 | * @return {Buffer} Data
482 | */
483 | GroupInviteEvent.prototype.data = function() {
484 | return this._data;
485 | };
486 |
487 | /**
488 | * Event object fired by {@class Tox}.
489 | * Corresponds to tox_callback_group_message(3).
490 | * @class
491 | * @param {Number} groupnum Group number
492 | * @param {Number} peernum Peer number
493 | * @param {String} message Message
494 | */
495 | var GroupMessageEvent = function(groupnum, peernum, message) {
496 | this.type = 'GroupMessageEvent';
497 | this._groupnum = groupnum;
498 | this._peernum = peernum;
499 | this._message = message;
500 | };
501 |
502 | /**
503 | * Get the group number.
504 | * @return {Number} Group number
505 | */
506 | GroupMessageEvent.prototype.group = function() {
507 | return this._groupnum;
508 | };
509 |
510 | /**
511 | * Get the peer number.
512 | * @return {Number} Peer number
513 | */
514 | GroupMessageEvent.prototype.peer = function() {
515 | return this._peernum;
516 | };
517 |
518 | /**
519 | * Get the message.
520 | * @return {String} Message
521 | */
522 | GroupMessageEvent.prototype.message = function() {
523 | return this._message;
524 | };
525 |
526 | /**
527 | * Event object fired by {@class Tox}.
528 | * Corresponds to tox_callback_group_action(3).
529 | * @class
530 | * @param {Number} groupnum Group number
531 | * @param {Number} peernum Peer number
532 | * @param {String} action Action
533 | */
534 | var GroupActionEvent = function(groupnum, peernum, action) {
535 | this.type = 'GroupActionEvent';
536 | this._groupnum = groupnum;
537 | this._peernum = peernum;
538 | this._action = action;
539 | };
540 |
541 | /**
542 | * Get the group number.
543 | * @return {Number} Group number
544 | */
545 | GroupActionEvent.prototype.group = function() {
546 | return this._groupnum;
547 | };
548 |
549 | /**
550 | * Get the peer number.
551 | * @return {Number} Peer number
552 | */
553 | GroupActionEvent.prototype.peer = function() {
554 | return this._peernum;
555 | };
556 |
557 | /**
558 | * Get the action.
559 | * @return {String} Action
560 | */
561 | GroupActionEvent.prototype.action = function() {
562 | return this._action;
563 | };
564 |
565 | /**
566 | * Event object fired by {@class Tox}.
567 | * Corresponds to tox_callback_group_namelist_change(3).
568 | * @class
569 | * @param {Number} groupnum Group number
570 | * @param {Number} peernum Peer number
571 | * @param {Number} change Change identifier, corresponds to TOX_CHAT_CHANGE
572 | */
573 | var GroupNamelistChangeEvent = function(groupnum, peernum, change) {
574 | this.type = 'GroupNamelistChangeEvent';
575 | this._groupnum = groupnum;
576 | this._peernum = peernum;
577 | this._change = change;
578 | };
579 |
580 | /**
581 | * Get the group number.
582 | * @return {Number} Group number
583 | */
584 | GroupNamelistChangeEvent.prototype.group = function() {
585 | return this._groupnum;
586 | };
587 |
588 | /**
589 | * Get the peer number.
590 | * @return {Number} Peer number
591 | */
592 | GroupNamelistChangeEvent.prototype.peer = function() {
593 | return this._peernum;
594 | };
595 |
596 | /**
597 | * Get the change identifier.
598 | * @return {Number} Change identifier
599 | */
600 | GroupNamelistChangeEvent.prototype.change = function() {
601 | return this._change;
602 | };
603 |
604 | /**
605 | * Event object fired by {@class Tox}.
606 | * Corresponds to tox_callback_group_title(3).
607 | * @class
608 | * @param {Number} groupnum Group number
609 | * @param {Number} peernum Peer number
610 | * @param {String} title New title
611 | */
612 | var GroupTitleEvent = function(groupnum, peernum, title) {
613 | this.type = 'GroupTitleEvent';
614 | this._groupnum = groupnum;
615 | this._peernum = peernum;
616 | this._title = title;
617 | };
618 |
619 | /**
620 | * Get the group number.
621 | * @return {Number} Group number
622 | */
623 | GroupTitleEvent.prototype.group = function() {
624 | return this._groupnum;
625 | };
626 |
627 | /**
628 | * Get the peer number.
629 | * @return {Number} Peer number
630 | */
631 | GroupTitleEvent.prototype.peer = function() {
632 | return this._peernum;
633 | };
634 |
635 | /**
636 | * Get the title.
637 | * @return {String} Title
638 | */
639 | GroupTitleEvent.prototype.title = function() {
640 | return this._title;
641 | };
642 |
643 | /**
644 | * Event object fired by {@class Tox}.
645 | * Corresponds to tox_callback_file_send_request(3).
646 | * @class
647 | * @param {Number} friendnum Friend number
648 | * @param {Number} filenum File number
649 | * @param {Number} filesize Size of file
650 | * @param {String} filename Filename
651 | */
652 | var FileSendRequestEvent = function(friendnum, filenum, filesize, filename) {
653 | this.type = 'FileSendRequestEvent';
654 | this._friendnum = friendnum;
655 | this._filenum = filenum;
656 | this._filesize = filesize;
657 | this._filename = filename;
658 | };
659 |
660 | /**
661 | * Get the friend number.
662 | * @return {Number} Friend number
663 | */
664 | FileSendRequestEvent.prototype.friend = function() {
665 | return this._friendnum;
666 | };
667 |
668 | /**
669 | * Get the file number.
670 | * @return {Number} File number
671 | */
672 | FileSendRequestEvent.prototype.fileNumber = function() {
673 | return this._filenum;
674 | };
675 |
676 | /**
677 | * Get the file size.
678 | * @return {Number} File size
679 | */
680 | FileSendRequestEvent.prototype.fileSize = function() {
681 | return this._filesize;
682 | };
683 |
684 | /**
685 | * Get the filename.
686 | * @return {String} Filename
687 | */
688 | FileSendRequestEvent.prototype.fileName = function() {
689 | return this._filename;
690 | };
691 |
692 | /**
693 | * Event object fired by {@class Tox}.
694 | * Corresponds to tox_callback_file_control(3).
695 | * @class
696 | * @param {Number} friendnum Friend number
697 | * @param {Number} receiveSend Receive or send indicator
698 | * @param {Number} filenum File number
699 | * @param {Number} controlType Control type indicator
700 | * @param {Buffer} data File data
701 | */
702 | var FileControlEvent = function(friendnum, receiveSend, filenum, controlType, data) {
703 | this.type = 'FileControlEvent';
704 | this._friendnum = friendnum;
705 | this._receiveSend = receiveSend;
706 | this._filenum = filenum;
707 | this._controlType = controlType;
708 | this._data = data;
709 | };
710 |
711 | /**
712 | * Get the friend number.
713 | * @return {Number} Friend number
714 | */
715 | FileControlEvent.prototype.friend = function() {
716 | return this._friendnum;
717 | };
718 |
719 | /**
720 | * Get the receive-send indicator.
721 | * @return {Number} Receive-send indicator
722 | */
723 | FileControlEvent.prototype.receiveSend = function() {
724 | return this._receiveSend;
725 | };
726 |
727 | /**
728 | * Get the file number.
729 | * @return {Number} File number
730 | */
731 | FileControlEvent.prototype.fileNumber = function() {
732 | return this._filenum;
733 | };
734 |
735 | /**
736 | * Get the control type.
737 | * @return {Number} Control type
738 | */
739 | FileControlEvent.prototype.controlType = function() {
740 | return this._controlType;
741 | };
742 |
743 | /**
744 | * Get the file data.
745 | * @return {Buffer} File data
746 | */
747 | FileControlEvent.prototype.data = function() {
748 | return this._data;
749 | };
750 |
751 | /**
752 | * Whether or not this event is for a slot on which we
753 | * are sending a file.
754 | * @return {Boolean} true if receiving, false if not
755 | */
756 | FileControlEvent.prototype.isReceive = function() {
757 | return this._receiveSend === 0;
758 | };
759 |
760 | /**
761 | * Whether or not this event is for a slot on which we
762 | * are sending a file.
763 | * @return {Boolean} true if sending, false if not
764 | */
765 | FileControlEvent.prototype.isSend = function() {
766 | return this._receiveSend === 1;
767 | };
768 |
769 | /**
770 | * Event object fired by {@class Tox}.
771 | * Corresponds to tox_callback_file_data(3).
772 | * @class
773 | * @param {Number} friendnum Friend number
774 | * @param {Number} filenum File number
775 | * @param {Buffer} data File data
776 | */
777 | var FileDataEvent = function(friendnum, filenum, data) {
778 | this.type = 'FileDataEvent';
779 | this._friendnum = friendnum;
780 | this._filenum = filenum;
781 | this._data = data;
782 | };
783 |
784 | /**
785 | * Get the friend number.
786 | * @return {Number} Friend number
787 | */
788 | FileDataEvent.prototype.friend = function() {
789 | return this._friendnum;
790 | };
791 |
792 | /**
793 | * Get the file number.
794 | * @return {Number} File number
795 | */
796 | FileDataEvent.prototype.fileNumber = function() {
797 | return this._filenum;
798 | };
799 |
800 | /**
801 | * Get the file data.
802 | * @return {Buffer} File data
803 | */
804 | FileDataEvent.prototype.data = function() {
805 | return this._data;
806 | };
807 |
808 | module.exports = {
809 | AvatarDataEvent: AvatarDataEvent,
810 | AvatarInfoEvent: AvatarInfoEvent,
811 | ConnectionStatusEvent: ConnectionStatusEvent,
812 | FileControlEvent: FileControlEvent,
813 | FileDataEvent: FileDataEvent,
814 | FileSendRequestEvent: FileSendRequestEvent,
815 | FriendActionEvent: FriendActionEvent,
816 | FriendMessageEvent: FriendMessageEvent,
817 | FriendRequestEvent: FriendRequestEvent,
818 | GroupActionEvent: GroupActionEvent,
819 | GroupInviteEvent: GroupInviteEvent,
820 | GroupMessageEvent: GroupMessageEvent,
821 | GroupNamelistChangeEvent: GroupNamelistChangeEvent,
822 | GroupTitleEvent: GroupTitleEvent,
823 | NameChangeEvent: NameChangeEvent,
824 | ReadReceiptEvent: ReadReceiptEvent,
825 | StatusMessageEvent: StatusMessageEvent,
826 | TypingChangeEvent: TypingChangeEvent,
827 | UserStatusEvent: UserStatusEvent
828 | };
829 |
--------------------------------------------------------------------------------
/lib/old/main.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var path = require('path');
20 | var tox = require(path.join(__dirname, 'tox'));
21 | var toxav = require(path.join(__dirname, 'toxav'));
22 | var toxdns = require(path.join(__dirname, 'toxdns'));
23 | var toxencryptsave = require(path.join(__dirname, 'toxencryptsave'));
24 | var consts = require(path.join(__dirname, 'consts'));
25 |
26 | var newApi = {
27 | Tox: require(path.join(__dirname, 'new', 'tox')),
28 | Consts: require(path.join(__dirname, 'new', 'consts'))
29 | };
30 |
31 | module.exports = {
32 | Tox: tox,
33 | ToxAV: toxav,
34 | ToxDns: toxdns,
35 | ToxEncryptSave: toxencryptsave,
36 | Consts: consts,
37 | new: newApi,
38 | NewApiConsts: newApi.Consts,
39 | NewApiTox: newApi.Tox
40 | };
41 |
--------------------------------------------------------------------------------
/lib/old/sync.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var _ = require('underscore');
20 |
21 | /**
22 | * Checks if the passed Arguments have a callback (in other words,
23 | * if the last argument is a Function).
24 | * @param {Arguments} args Arguments to check
25 | * @return {Boolean} true if last argument is a Function, false if not
26 | * (or if invalid args)
27 | */
28 | var hasCallback = function(args) {
29 | if(!args || args.length === 0) {
30 | return false;
31 | }
32 |
33 | var last = _.last(args);
34 | return _.isFunction(last);
35 | };
36 |
37 | module.exports = {
38 | hasCallback: hasCallback
39 | };
40 |
--------------------------------------------------------------------------------
/lib/old/toxav.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var ffi = require('ffi');
20 | var path = require('path');
21 | var ref = require('ref');
22 | var errors = require(path.join(__dirname, 'errors'));
23 |
24 | var _UInt8Ptr = ref.refType('uint8');
25 | var _Tox = ref.types.void;
26 | var _ToxPtr = ref.refType(_Tox);
27 | var _ToxAV = ref.types.void;
28 | var _ToxAVPtr = ref.refType(_ToxAV);
29 |
30 | // Uhhh.. *pcm may cause issues?
31 | var _AVGroupCallback = ffi.Function('void', [ _ToxPtr, 'int', 'int', 'pointer', 'uint', 'uint8', 'uint', 'pointer' ]);
32 |
33 | var createNegativeReturnError = errors.createNegativeReturnError;
34 | var createToxNoHandleError = errors.createToxNoHandleError;
35 |
36 | /**
37 | * Construct a new ToxAV.
38 | * @class
39 | * @param {Tox} tox - Tox instance
40 | * @param {Object} [opts] - Options
41 | * @param {String} [opts.path] toxav library path, will use the
42 | * default if not specified
43 | */
44 | var ToxAV = function(tox, opts) {
45 | if(!opts) opts = {};
46 | var libpath = opts['path'];
47 |
48 | this._tox = tox;
49 | this._toxav = this.createLibrary(libpath);
50 | };
51 |
52 | /**
53 | * Check if _tox exists and has a handle.
54 | * @param [callback] - Callback to pass Error object to if _tox or
55 | * its handle is missing
56 | * @return true if _tox exists and has handle, false if not
57 | */
58 | ToxAV.prototype._checkToxHandle = function(callback) {
59 | if(!this._tox || !this._tox.hasHandle()) {
60 | if(callback) {
61 | callback(createToxNoHandleError());
62 | }
63 | return false;
64 | }
65 | return true;
66 | };
67 |
68 | /**
69 | * Check if _tox exists and has a handle.
70 | * @throws Error if no _tox or no handle.
71 | */
72 | ToxAV.prototype._checkToxHandleSync = function() {
73 | if(!this._tox || !this._tox.hasHandle()) {
74 | throw createToxNoHandleError();
75 | }
76 | };
77 |
78 | /**
79 | * Get the Tox object.
80 | * @return {Tox} Tox
81 | */
82 | ToxAV.prototype.getTox = function() {
83 | return this._tox;
84 | };
85 |
86 | /**
87 | * Create the toxav ffi Library object.
88 | * @param {String} [libpath='libtoxav'] - Path to libtoxav
89 | */
90 | ToxAV.prototype.createLibrary = function(libpath) {
91 | libpath = libpath || 'libtoxav';
92 | return ffi.Library(libpath, {
93 | 'toxav_add_av_groupchat': [ 'int', [ _ToxPtr, _AVGroupCallback, 'pointer' ] ],
94 | 'toxav_join_av_groupchat': [ 'int', [ _ToxPtr, 'int32', _UInt8Ptr, 'uint16', _AVGroupCallback, 'pointer' ] ],
95 | 'toxav_do': [ 'void', [ _ToxAVPtr ] ],
96 | 'toxav_do_interval': [ 'uint32', [ _ToxAVPtr ] ],
97 | 'toxav_get_tox': [ _ToxPtr, [ _ToxAVPtr ] ],
98 | 'toxav_kill': [ 'void', [ _ToxAVPtr ] ],
99 | 'toxav_new': [ _ToxAVPtr, [ _ToxPtr, 'int32' ] ]
100 | });
101 | };
102 |
103 | /**
104 | * Get the ffi library object.
105 | * @return toxav library object
106 | */
107 | ToxAV.prototype.getLibrary = function() {
108 | return this._toxav;
109 | };
110 |
111 | /**
112 | * Asynchronous toxav_add_av_groupchat(3).
113 | * @todo audio_callback support
114 | */
115 | ToxAV.prototype.addGroupchat = function(callback) {
116 | if(!this._checkToxHandle(callback)) {
117 | return;
118 | }
119 |
120 | this.getLibrary().toxav_add_av_groupchat.async(
121 | this.getTox().getHandle(), ref.NULL, ref.NULL, function(err, res) {
122 | if(!err && res < 0) {
123 | err = createNegativeReturnError('toxav_add_av_groupchat', res);
124 | }
125 |
126 | if(callback) {
127 | callback(err, res);
128 | }
129 | });
130 | };
131 |
132 | /**
133 | * Synchronous toxav_add_av_groupchat(3).
134 | * @return {Number} Group number
135 | * @throws Error if toxav_add_av_groupchat returns a negative value
136 | * @todo audio_callback support
137 | */
138 | ToxAV.prototype.addGroupchatSync = function() {
139 | this._checkToxHandleSync();
140 |
141 | var groupnum = this.getLibrary().toxav_add_av_groupchat(this.getTox().getHandle(), ref.NULL, ref.NULL);
142 | if(groupnum < 0) {
143 | throw createNegativeReturnError('toxav_add_av_groupchat', res);
144 | }
145 |
146 | return groupnum;
147 | };
148 |
149 | /**
150 | * Asynchronous toxav_join_av_groupchat(3).
151 | * @param {Number} friendnum
152 | * @param {Buffer} data
153 | * @todo audio_callback support
154 | */
155 | ToxAV.prototype.joinGroupchat = function(friendnum, data, callback) {
156 | if(!this._checkToxHandle(callback)) {
157 | return;
158 | }
159 |
160 | this.getLibrary().toxav_join_av_groupchat.async(
161 | this.getTox().getHandle(), friendnum, data, data.length, ref.NULL, ref.NULL, function(err, res) {
162 | if(!err && res < 0) {
163 | err = createNegativeReturnError('toxav_join_av_groupchat', res);
164 | }
165 |
166 | if(callback) {
167 | callback(err, res);
168 | }
169 | });
170 | };
171 |
172 | /**
173 | * Synchronous toxav_join_av_groupchat(3).
174 | * @param {Number} friendnum
175 | * @param {Buffer} data
176 | * @return {Number} Group number
177 | * @throws Error if toxav_join_av_groupchat returns a negative value
178 | * @todo audio_callback support
179 | */
180 | ToxAV.prototype.joinGroupchatSync = function(friendnum, data) {
181 | this._checkToxHandleSync();
182 |
183 | var groupnum = this.getLibrary().toxav_join_av_groupchat(
184 | this.getTox().getHandle(), friendnum, data, data.length, ref.NULL, ref.NULL);
185 |
186 | if(groupnum < 0) {
187 | throw createNegativeReturnError('toxav_join_av_groupchat', groupnum);
188 | }
189 |
190 | return groupnum;
191 | };
192 |
193 | module.exports = ToxAV;
194 |
--------------------------------------------------------------------------------
/lib/old/toxdns.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var buffertools = require('buffertools');
20 | var events = require('events');
21 | var fs = require('fs');
22 | var ref = require('ref');
23 | var ffi = require('ffi');
24 | var path = require('path');
25 | var _ = require('underscore');
26 | var RefStruct = require('ref-struct');
27 | var RefArray = require('ref-array');
28 | var consts = require(path.join(__dirname, 'consts'));
29 | var errors = require(path.join(__dirname, 'errors'));
30 |
31 | buffertools.extend();
32 |
33 | var TOX_FRIEND_ADDRESS_SIZE = consts.TOX_FRIEND_ADDRESS_SIZE;
34 | var TOXDNS_MAX_RECOMMENDED_NAME_LENGTH = consts.TOXDNS_MAX_RECOMMENDED_NAME_LENGTH;
35 |
36 | var createNegativeReturnError = errors.createNegativeReturnError;
37 | var createNonZeroReturnError = errors.createNonZeroReturnError;
38 |
39 | // Public keys
40 | var TOXDNS_PUBKEY_TOXME_SE = '57AA48BB8CB1CC9FC67837964A28DB0184137E37BB158B5409815382F9257FBF';
41 |
42 | var _UInt8Ptr = ref.refType('uint8');
43 | var _UInt32Ptr = ref.refType('uint32');
44 | var _VoidPtr = ref.refType('void');
45 |
46 | var ToxDns = function(opts) {
47 | if(!opts) opts = {};
48 | var libpath = opts['path'];
49 | var key = opts['key'];
50 |
51 | this.toxdns = this.createLibrary(libpath);
52 | this.initKey(key);
53 | this.initHandle(this.key);
54 | };
55 |
56 | /**
57 | * Create the library instance (libtoxdns).
58 | * @param {String} [libpath='libtoxdns'] - Path to libtoxdns
59 | * @return {Object}
60 | */
61 | ToxDns.prototype.createLibrary = function(libpath) {
62 | libpath = libpath || 'libtoxdns';
63 | return ffi.Library(libpath, {
64 | 'tox_dns3_new': [ _VoidPtr, [ _UInt8Ptr ] ],
65 | 'tox_dns3_kill': [ 'void', [ _VoidPtr ] ],
66 | 'tox_generate_dns3_string': [ 'int', [ _VoidPtr, _UInt8Ptr, 'uint16', _UInt32Ptr, _UInt8Ptr, 'uint8' ] ],
67 | 'tox_decrypt_dns3_TXT': [ 'int', [ _VoidPtr, _UInt8Ptr, _UInt8Ptr, 'uint32', 'uint32' ] ]
68 | });
69 | };
70 |
71 | /**
72 | * Initialize the public key.
73 | * @param {(Buffer|String)} key Public key
74 | */
75 | ToxDns.prototype.initKey = function(key) {
76 | if(!key) {
77 | key = TOXDNS_PUBKEY_TOXME_SE; // Use toxme.se public key by default
78 | }
79 |
80 | // If key is a String, assume a hex String
81 | if(_.isString(key)) {
82 | key = new Buffer(key).fromHex();
83 | }
84 |
85 | this.key = key;
86 | };
87 |
88 | /**
89 | * Check if this ToxDns instance has a handle.
90 | * @return {Boolean} true if it has a handle, false if not
91 | */
92 | ToxDns.prototype.hasHandle = function() {
93 | return (this.handle !== undefined && this.handle !== null);
94 | };
95 |
96 | /**
97 | * Synchronous tox_dns3_new(3).
98 | * Initializes the handle for this ToxDns instance.
99 | * @param {Buffer} buffer Server's public key
100 | */
101 | ToxDns.prototype.initHandle = function(buffer) {
102 | if(buffer) {
103 | this.handle = this.toxdns.tox_dns3_new(buffer);
104 | }
105 | };
106 |
107 | /**
108 | * Asynchronous tox_dns3_kill(3).
109 | */
110 | ToxDns.prototype.kill = function(callback) {
111 | var toxdns = this;
112 | this.toxdns.tox_dns3_kill.async(this.handle, function(err) {
113 | if(!err) {
114 | toxdns.handle = undefined;
115 | }
116 |
117 | if(callback) {
118 | callback(err);
119 | }
120 | });
121 | };
122 |
123 | /**
124 | * Synchronous tox_dns3_kill(3).
125 | */
126 | ToxDns.prototype.killSync = function() {
127 | this.toxdns.tox_dns3_kill(this.handle);
128 | this.handle = undefined;
129 | };
130 |
131 | /**
132 | * Asynchronous tox_generate_dns3_string(3).
133 | * @param {String} name
134 | */
135 | ToxDns.prototype.generateString = function(name, callback) {
136 | var namebuf = new Buffer(name),
137 | outbuf = new Buffer(64),
138 | requestId = ref.alloc(ref.refType('uint32'));
139 |
140 | this.toxdns.tox_generate_dns3_string.async(
141 | this.handle, outbuf, outbuf.length, requestId, namebuf, namebuf.length, function(err, res) {
142 | if(!err && res < 0) {
143 | err = createNegativeReturnError('tox_generate_dns3_string', res);
144 | }
145 |
146 | var str, id;
147 | if(!err) {
148 | str = outbuf.slice(0, res).toString();
149 | id = requestId.deref();
150 | }
151 |
152 | if(callback) {
153 | callback(err, str, id);
154 | }
155 | });
156 | };
157 |
158 | /**
159 | * Asynchronous tox_decrypt_dns3_TXT(3).
160 | * @param {String} record
161 | * @param {Number} requestId
162 | */
163 | ToxDns.prototype.decrypt = function(record, requestId, callback) {
164 | var toxId = new Buffer(TOX_FRIEND_ADDRESS_SIZE),
165 | recordBuffer = new Buffer(record);
166 |
167 | this.toxdns.tox_decrypt_dns3_TXT.async(
168 | this.handle, toxId, recordBuffer, recordBuffer.length, requestId, function(err, res) {
169 | if(!err && res !== 0) {
170 | err = createNonZeroReturnError('tox_decrypt_dns3_TXT', res);
171 | }
172 |
173 | if(callback) {
174 | callback(err, toxId);
175 | }
176 | });
177 | };
178 |
179 | module.exports = ToxDns;
180 |
--------------------------------------------------------------------------------
/lib/old/util.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var buffertools = require('buffertools');
20 | var path = require('path');
21 | var _ = require('underscore');
22 | var consts = require(path.join(__dirname, 'consts'));
23 | buffertools.extend();
24 |
25 | /**
26 | * Get a hex String from a Buffer.
27 | * @param {Buffer} buffer Buffer
28 | * @return {String} Hex String
29 | */
30 | var toHex = function(buffer) {
31 | return buffer.toHex().toString();
32 | };
33 |
34 | /**
35 | * Get a Buffer from a hex String.
36 | * @param {String} str Hex String
37 | * @return {Buffer} Buffer
38 | */
39 | var fromHex = function(str) {
40 | return (new Buffer(str)).fromHex();
41 | };
42 |
43 | /**
44 | * Whether or not some Buffer or String might represent a Tox address. Will return
45 | * false if not a Buffer or String.
46 | * @param {(Buffer|String)} addr
47 | * @return {Boolean} true if possible Tox address, false if not
48 | */
49 | var isToxAddress = function(addr) {
50 | if(_.isString(addr)) {
51 | return addr.length === (consts.TOX_FRIEND_ADDRESS_SIZE * 2)
52 | && /^[0-9a-f]+$/i.test(addr);
53 | }
54 | else if(addr instanceof Buffer) {
55 | return addr.length === (consts.TOX_FRIEND_ADDRESS_SIZE);
56 | }
57 | return false;
58 | };
59 |
60 | /**
61 | * Try to parse an address:port string.
62 | * @return {Object} Object with address and port if successful,
63 | * undefined if not.
64 | */
65 | var parseAddress = function(str) {
66 | var ex = /^[^:]+:(\\d+)$/;
67 | if(ex.test(str)) {
68 | var res = ex.exec(str);
69 | return {
70 | address: res[1],
71 | port: res[2]
72 | };
73 | }
74 | };
75 |
76 | /**
77 | * Try to parse a Tox proxy string.
78 | * @return {Object} Proxy object if successful, undefined if not
79 | */
80 | var parseProxy = function(str) {
81 | var type;
82 | if(str.indexOf('http://') === 0) {
83 | str = str.slice('http://'.length);
84 | type = 'http';
85 | } else if(str.indexOf('socks://') === 0) {
86 | str = str.slice('socks://'.length);
87 | type = 'socks';
88 | } else if(str.indexOf('socks5://') === 0) {
89 | str = str.slice('socks5://'.length);
90 | type = 'socks';
91 | }
92 |
93 | var proxy = parseAddress(str);
94 | if(proxy) {
95 | proxy.type = type;
96 | return proxy;
97 | }
98 | };
99 |
100 | module.exports = {
101 | fromHex: fromHex,
102 | isToxAddress: isToxAddress,
103 | parseAddress: parseAddress,
104 | parseProxy: parseProxy,
105 | toHex: toHex
106 | };
107 |
--------------------------------------------------------------------------------
/lib/toxdns.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var buffertools = require('buffertools');
20 | var dns = require('dns');
21 | var ref = require('ref');
22 | var ffi = require('ffi');
23 | var path = require('path');
24 | var util = require('util');
25 | var _ = require('underscore');
26 | var consts = require(path.join(__dirname, 'consts'));
27 | var errors = require(path.join(__dirname, 'errors'));
28 | var _util = require(path.join(__dirname, 'util'));
29 |
30 | buffertools.extend();
31 |
32 | // No idea if there's actually a max size, this should be good enough
33 | var TOXDNS3_RECORD_SIZE_MAX = 256;
34 |
35 | // Public keys
36 | var TOXDNS_PUBKEY_TOXME_IO = '1A39E7A5D5FA9CF155C751570A32E625698A60A55F6D88028F949F66144F4F25';
37 |
38 | // Common types
39 | var UInt8Ptr = ref.refType('uint8');
40 | var UInt32Ptr = ref.refType('uint32');
41 | var VoidPtr = ref.refType('void');
42 |
43 | /**
44 | * Creates a ToxDns instance.
45 | * @class
46 | * @param {Object} [opts] Options
47 | * @param {String} [opts.path] Path to libtoxdns.so
48 | * @param {(Buffer|String)} [opts.key] Public key of ToxDns3 service
49 | */
50 | var ToxDns = function(opts) {
51 | if(!opts) opts = {};
52 | var libpath = opts['path'];
53 | var key = opts['key'];
54 |
55 | this._library = this._createLibrary(libpath);
56 | this._initKey(key);
57 | this._initHandle(this._key);
58 | };
59 |
60 | /**
61 | * Get the internal Library instance.
62 | * @return {ffi.Library}
63 | */
64 | ToxDns.prototype.getLibrary = function() {
65 | return this._library;
66 | }
67 |
68 | /**
69 | * Create the libtoxdns Library instance (libtoxdns).
70 | * @private
71 | * @param {String} [libpath='libtoxdns'] - Path to libtoxdns
72 | * @return {ffi.Library}
73 | */
74 | ToxDns.prototype._createLibrary = function(libpath) {
75 | libpath = libpath || 'libtoxdns';
76 | return ffi.Library(libpath, {
77 | 'tox_dns3_new': [ VoidPtr, [ UInt8Ptr ] ],
78 | 'tox_dns3_kill': [ 'void', [ VoidPtr ] ],
79 | 'tox_generate_dns3_string': [ 'int', [ VoidPtr, UInt8Ptr, 'uint16', UInt32Ptr, UInt8Ptr, 'uint8' ] ],
80 | 'tox_decrypt_dns3_TXT': [ 'int', [ VoidPtr, UInt8Ptr, UInt8Ptr, 'uint32', 'uint32' ] ]
81 | });
82 | };
83 |
84 | /**
85 | * Format the string which is sent in the TXT request.
86 | * @private
87 | * @param {String} generated - Generated output
88 | * @param {String} domain - Domain from the ToxDns address
89 | * @return {String} Formatted string to send
90 | */
91 | ToxDns.prototype._format = function(generated, domain) {
92 | return util.format('_%s._tox.%s', generated, domain);
93 | };
94 |
95 | /**
96 | * Parse a ToxDns address, returning an object with two properties: 'name'
97 | * (before @) and 'domain' (after @). If not recognized as an address,
98 | * undefined is returned.
99 | * @private
100 | * @param {String} address - Address string to parse
101 | * @return {Object} Object with a 'name' and a 'domain', or undefined if not
102 | * the given address could not be parsed
103 | */
104 | ToxDns.prototype._parse = function(address) {
105 | if(address.indexOf('@') !== -1) {
106 | var split = address.split('@');
107 | return { name: split[0], domain: split[1] };
108 | }
109 | //} else if(this.hasDomain()) {
110 | // return { name: address, domain: this.getDomain() };
111 | //}
112 | };
113 |
114 | /**
115 | * Resolves a toxdns address using toxdns v3. Assumes the domain name in the
116 | * given address uses the public key set in the ToxDns constructor.
117 | * @param {String} address - ToxDns address
118 | * @param {ToxDns~dataCallback} [callback]
119 | */
120 | ToxDns.prototype.resolve = function(address, callback) {
121 | var toxdns = this,
122 | format = ToxDns.prototype._format.bind(this),
123 | addr = this._parse(address);
124 |
125 | if(!addr) {
126 | if(callback) {
127 | callback(new Error('Not a toxdns address'));
128 | }
129 | return;
130 | }
131 |
132 | this.generate(addr.name, function(err, info) {
133 | if(!err) {
134 | var full = format(info.record, addr.domain);
135 | dns.resolveTxt(full, function(err, txts) {
136 | if(!err) {
137 | var result = txts[0][0],
138 | id = result.match(/(^|;)id=([a-zA-Z0-9]+)/)[2];
139 | toxdns.decrypt(id, info.id, function(err, addr) {
140 | if(!err) {
141 | if(callback) {
142 | callback(undefined, addr);
143 | }
144 | } else if(callback) {
145 | callback(err);
146 | }
147 | });
148 | } else if(callback) {
149 | callback(err);
150 | }
151 | });
152 | } else if(callback) {
153 | callback(err);
154 | }
155 | });
156 | };
157 |
158 | /**
159 | * Same as ToxDns#resolve(), but returns the Tox address
160 | * as a hex string via the callback.
161 | * @param {String} address - ToxDns address
162 | * @param {ToxDns~stringCallback} [callback]
163 | */
164 | ToxDns.prototype.resolveHex = function(address, callback) {
165 | _util.hexify(this.resolve.bind(this, address), callback);
166 | };
167 |
168 | /**
169 | * Get the public key.
170 | * @return {Buffer} Public key
171 | */
172 | ToxDns.prototype.getKey = function() {
173 | return this._key;
174 | };
175 |
176 | /**
177 | * Get the public key as a hex string.
178 | * @return {String} Public key as a hex string
179 | */
180 | ToxDns.prototype.getKeyHex = function() {
181 | return this._key.toHex().toString().toUpperCase();
182 | };
183 |
184 | /**
185 | * Initialize the public key.
186 | * @private
187 | * @param {(Buffer|String)} key - Public key
188 | */
189 | ToxDns.prototype._initKey = function(key) {
190 | if(!key) key = TOXDNS_PUBKEY_TOXME_IO; // Use toxme.io public key by default
191 | // If key is a String, assume a hex String
192 | if(_.isString(key)) key = new Buffer(key).fromHex();
193 | this._key = key;
194 | };
195 |
196 | /**
197 | * Get the handle object.
198 | * @return {Object}
199 | */
200 | ToxDns.prototype.getHandle = function() {
201 | return this._handle;
202 | }
203 |
204 | /**
205 | * Whether or not this ToxDns instance has a handle.
206 | * @return {Boolean} true if handle, false if not
207 | */
208 | ToxDns.prototype.hasHandle = function() {
209 | return !!this.getHandle();
210 | };
211 |
212 | /**
213 | * Synchronous tox_dns3_new(3).
214 | * Initializes the handle for this ToxDns instance.
215 | * @private
216 | * @param {Buffer} buffer - Server's public key
217 | */
218 | ToxDns.prototype._initHandle = function(buffer) {
219 | if(buffer) {
220 | this._handle = this.getLibrary().tox_dns3_new(buffer);
221 | }
222 | };
223 |
224 | /**
225 | * Asynchronous tox_dns3_kill(3).
226 | * @param {ToxDns~errorCallback} [callback]
227 | */
228 | ToxDns.prototype.kill = function(callback) {
229 | var toxdns = this;
230 | this.getLibrary().tox_dns3_kill.async(this.getHandle(), function(err) {
231 | if(!err) {
232 | toxdns._handle = undefined;
233 | }
234 |
235 | if(callback) {
236 | callback(err);
237 | }
238 | });
239 | };
240 |
241 | /**
242 | * Synchronous tox_dns3_kill(3).
243 | */
244 | ToxDns.prototype.killSync = function() {
245 | this.getLibrary().tox_dns3_kill(this.getHandle());
246 | this._handle = undefined;
247 | };
248 |
249 | /**
250 | * Asynchronous tox_generate_dns3_string(3).
251 | * @param {String} name - Name to generate a request string for
252 | * @param {ToxDns~generateCallback} [callback]
253 | */
254 | ToxDns.prototype.generate = function(name, callback) {
255 | var namebuf = new Buffer(name),
256 | outbuf = new Buffer(TOXDNS3_RECORD_SIZE_MAX),
257 | requestId = ref.alloc('uint32');
258 |
259 | this.getLibrary().tox_generate_dns3_string.async(
260 | this.getHandle(), outbuf, outbuf.length, requestId, namebuf, namebuf.length, function(err, res) {
261 | if(!err && res < 0) {
262 | //err = createNegativeReturnError('tox_generate_dns3_string', res);
263 | // TODO: Better errors
264 | err = new Error('tox_generate_dns3_string returned ' + res);
265 | }
266 |
267 | var str, id;
268 | if(!err) {
269 | str = outbuf.slice(0, res).toString();
270 | id = Number(requestId.deref());
271 | }
272 |
273 | if(callback) {
274 | callback(err, { record: str, id: id });
275 | }
276 | });
277 | };
278 |
279 | /**
280 | * Synchronous tox_generate_dns3_string(3).
281 | * @param {String} name - Name to generate a request string for
282 | * @return {Object} Object containing an 'id' (Number) and a generated
283 | * 'record' (String)
284 | */
285 | ToxDns.prototype.generateSync = function(name) {
286 | var namebuf = new Buffer(name),
287 | outbuf = new Buffer(TOXDNS3_RECORD_SIZE_MAX),
288 | requestId = ref.alloc('uint32'),
289 | length = this.getLibrary().tox_generate_dns3_string(
290 | this.getHandle(), outbuf, outbuf.length, requestId, namebuf, namebuf.length);
291 | if(length < 0) throw new Error('tox_generate_dns3_string returned ' + length);
292 | var str = outbuf.slice(0, length).toString(),
293 | id = Number(requestId.deref());
294 | return { record: str, id: id };
295 | };
296 |
297 | /**
298 | * Asynchronous tox_decrypt_dns3_TXT(3).
299 | * @param {String} record
300 | * @param {Number} requestId
301 | * @param {ToxDns~dataCallback} [callback]
302 | */
303 | ToxDns.prototype.decrypt = function(record, requestId, callback) {
304 | var toxId = new Buffer(consts.TOX_FRIEND_ADDRESS_SIZE),
305 | recordBuffer = new Buffer(record);
306 |
307 | this.getLibrary().tox_decrypt_dns3_TXT.async(
308 | this.getHandle(), toxId, recordBuffer, recordBuffer.length, requestId, function(err, res) {
309 | if(!err && res !== 0) {
310 | //err = createNonZeroReturnError('tox_decrypt_dns3_TXT', res);
311 | err = new Error('tox_decrypt_dns3_TXT returned ' + res);
312 | }
313 |
314 | if(callback) {
315 | callback(err, toxId);
316 | }
317 | });
318 | };
319 |
320 | /**
321 | * Asynchronous tox_decrypt_dns3_TXT(3).
322 | * @param {String} record
323 | * @param {Number} requestId
324 | * @return {Buffer} Tox address
325 | */
326 | ToxDns.prototype.decryptSync = function(record, requestId) {
327 | var toxId = new Buffer(consts.TOX_FRIEND_ADDRESS_SIZE),
328 | recordBuffer = new Buffer(record),
329 | success = this.getLibrary().tox_decrypt_dns3_TXT(
330 | this.getHandle(), toxId, recordBuffer, recordBuffer.length, requestId);
331 | if(success !== 0) throw new Error('tox_decrypt_dns3_TXT returned ' + success);
332 | return toxId;
333 | };
334 |
335 | /**
336 | * Callback that returns some error, if any.
337 | * @callback ToxDns~errorCallback
338 | * @param {Error} error - error, if any
339 | */
340 |
341 | /**
342 | * Callback that returns some data in a Buffer.
343 | * @callback ToxDns~dataCallback
344 | * @param {Error} error - error, if any
345 | * @param {Buffer} data
346 | */
347 |
348 | /**
349 | * Callback that returns an Object with a record and id.
350 | * @callback ToxDns~generateCallback
351 | * @param {Error} error - error, if any
352 | * @param {Object} object - Generate object
353 | * @param {String} object.record - String sent in the DNS TXT request
354 | * @param {Number} object.id - Id required when decrypting results
355 | */
356 |
357 | /**
358 | * Callback that returns some string.
359 | * @callback ToxDns~stringCallback
360 | * @param {Error} error - error, if any
361 | * @param {String} value
362 | */
363 |
364 | module.exports = ToxDns;
365 |
--------------------------------------------------------------------------------
/lib/toxencryptsave.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var ffi = require('ffi');
20 | var fs = require('fs');
21 | var path = require('path');
22 | var ref = require('ref');
23 | var RefArray = require('ref-array');
24 | var RefStruct = require('ref-struct');
25 | var _ = require('underscore');
26 |
27 | var consts = require(path.join(__dirname, 'consts'));
28 | var errors = require(path.join(__dirname, 'errors'));
29 |
30 | var ToxPassKey = RefStruct({
31 | 'salt': RefArray('uint8', consts.TOX_PASS_SALT_LENGTH),
32 | 'key': RefArray('uint8', consts.TOX_PASS_KEY_LENGTH)
33 | });
34 |
35 | // Common types
36 | var UInt8Ptr = ref.refType('uint8');
37 |
38 | // Tox enums and error types
39 | var CEnum = 'int32';
40 | var TOX_ERR_DECRYPTION = CEnum;
41 | var TOX_ERR_ENCRYPTION = CEnum;
42 | var TOX_ERR_KEY_DERIVATION = CEnum;
43 |
44 | /**
45 | * Creates a ToxEncryptSave instance.
46 | * @class
47 | * @param {(Object|String)} [opts] Options
48 | */
49 | var ToxEncryptSave = function(opts) {
50 | // If opts is a string, assume libpath
51 | if(_.isString(opts)) {
52 | opts = { path: opts }
53 | }
54 |
55 | if(!opts) opts = {};
56 | var libpath = opts['path'];
57 |
58 | this._library = this._createLibrary(libpath);
59 | };
60 |
61 | /**
62 | * @private
63 | */
64 | ToxEncryptSave.prototype._createLibrary = function(libpath) {
65 | libpath = libpath || 'libtoxencryptsave';
66 | return ffi.Library(libpath, {
67 | 'tox_derive_key_from_pass': [ 'bool', [ UInt8Ptr, 'size_t', ref.refType(ToxPassKey), ref.refType(TOX_ERR_KEY_DERIVATION) ] ],
68 | 'tox_derive_key_with_salt': [ 'bool', [ UInt8Ptr, 'size_t', UInt8Ptr, ref.refType(ToxPassKey), ref.refType(TOX_ERR_KEY_DERIVATION) ] ],
69 | 'tox_get_salt': [ 'bool', [ UInt8Ptr, UInt8Ptr ] ],
70 | 'tox_is_data_encrypted': [ 'bool', [ UInt8Ptr ] ],
71 | 'tox_pass_decrypt': [ 'bool', [ UInt8Ptr, 'size_t', UInt8Ptr, 'size_t', UInt8Ptr, ref.refType(TOX_ERR_DECRYPTION) ] ],
72 | 'tox_pass_encrypt': [ 'bool', [ UInt8Ptr, 'size_t', UInt8Ptr, 'size_t', UInt8Ptr, ref.refType(TOX_ERR_ENCRYPTION) ] ],
73 | 'tox_pass_key_decrypt': [ 'bool', [ UInt8Ptr, 'size_t', ref.refType(ToxPassKey), UInt8Ptr, ref.refType(TOX_ERR_DECRYPTION) ] ],
74 | 'tox_pass_key_encrypt': [ 'bool', [ UInt8Ptr, 'size_t', ref.refType(ToxPassKey), UInt8Ptr, ref.refType(TOX_ERR_ENCRYPTION) ] ]
75 | });
76 | };
77 |
78 | /**
79 | * Asynchronous tox_pass_decrypt(3).
80 | * @param {Buffer} data - Data to decrypt
81 | * @param {(Buffer|String)} pass - Password to decrypt with
82 | * @param {ToxEncryptSave~dataCallback} [callback]
83 | */
84 | ToxEncryptSave.prototype.decrypt = function(data, pass, callback) {
85 | if(_.isString(pass)) pass = new Buffer(pass);
86 | var eptr = ref.alloc(TOX_ERR_DECRYPTION),
87 | out = new Buffer(data.length - consts.TOX_PASS_ENCRYPTION_EXTRA_LENGTH);
88 | this.getLibrary().tox_pass_decrypt.async(data, data.length, pass, pass.length, out, eptr, function(err, success) {
89 | var terr = errors.decryption(eptr.deref());
90 | if(!err && terr) err = terr;
91 | if(!err && !success) err = errors.unsuccessful();
92 | if(callback) {
93 | callback(err, out);
94 | }
95 | });
96 | };
97 |
98 | /**
99 | * Synchronous tox_pass_decrypt(3).
100 | * @param {Buffer} data - Data to decrypt
101 | * @param {(Buffer|String)} pass - Password to decrypt with
102 | * @return {Buffer} Decrypted data
103 | */
104 | ToxEncryptSave.prototype.decryptSync = function(data, pass) {
105 | if(_.isString(pass)) pass = new Buffer(pass);
106 | var eptr = ref.alloc(TOX_ERR_DECRYPTION),
107 | out = new Buffer(data.length - consts.TOX_PASS_ENCRYPTION_EXTRA_LENGTH),
108 | success = this.getLibrary().tox_pass_decrypt(data, data.length, pass, pass.length, out, eptr);
109 | var err = errors.decryption(eptr.deref());
110 | if(err) throw err;
111 | else if(!success) throw errors.unsuccessful();
112 | return out;
113 | };
114 |
115 | /**
116 | * Asynchronous tox_pass_encrypt(3).
117 | * @param {Buffer} data - Data to encrypt
118 | * @param {(Buffer|String)} pass - Password to encrypt with
119 | * @param {ToxEncryptSave~dataCallback} [callback]
120 | */
121 | ToxEncryptSave.prototype.encrypt = function(data, pass, callback) {
122 | if(_.isString(pass)) pass = new Buffer(pass);
123 | var eptr = ref.alloc(TOX_ERR_ENCRYPTION),
124 | out = new Buffer(data.length + consts.TOX_PASS_ENCRYPTION_EXTRA_LENGTH);
125 | this.getLibrary().tox_pass_encrypt.async(data, data.length, pass, pass.length, out, eptr, function(err, success) {
126 | var terr = errors.encryption(eptr.deref());
127 | if(!err && terr) err = terr;
128 | if(!err && !success) err = errors.unsuccessful();
129 | if(callback) {
130 | callback(err, out);
131 | }
132 | });
133 | };
134 |
135 | /**
136 | * Synchronous tox_pass_encrypt(3).
137 | * @param {Buffer} data - Data to encrypt
138 | * @param {(Buffer|String)} pass - Password to encrypt with
139 | * @return {Buffer} Encrypted data
140 | */
141 | ToxEncryptSave.prototype.encryptSync = function(data, pass) {
142 | if(_.isString(pass)) pass = new Buffer(pass);
143 | var eptr = ref.alloc(TOX_ERR_ENCRYPTION),
144 | out = new Buffer(data.length + consts.TOX_PASS_ENCRYPTION_EXTRA_LENGTH),
145 | success = this.getLibrary().tox_pass_encrypt(data, data.length, pass, pass.length, out, eptr);
146 | var err = errors.encryption(eptr.deref());
147 | if(err) throw err;
148 | else if(!success) throw errors.unsuccessful();
149 | return out;
150 | };
151 |
152 | /**
153 | * Asynchronous tox_get_salt(3).
154 | * @param {Buffer} data - Data to get salt from
155 | * @param {ToxEncryptSave~dataCallback} [callback]
156 | */
157 | ToxEncryptSave.prototype.getSalt = function(data, callback) {
158 | var salt = new Buffer(consts.TOX_PASS_SALT_LENGTH);
159 | this.getLibrary().tox_get_salt.async(data, salt, function(err, success) {
160 | if(!err && !success) err = errors.unsuccessful();
161 | if(callback) {
162 | callback(err, salt);
163 | }
164 | });
165 | };
166 |
167 | /**
168 | * Synchronous tox_get_salt(3).
169 | * @param {Buffer} data - Data to get salt from
170 | * @return {Buffer} Salt
171 | */
172 | ToxEncryptSave.prototype.getSaltSync = function(data) {
173 | var salt = new Buffer(consts.TOX_PASS_SALT_LENGTH),
174 | success = this.getLibrary().tox_get_salt(data, salt);
175 | if(!success) throw errors.unsuccessful();
176 | return salt;
177 | };
178 |
179 | /**
180 | * Asynchronous tox_is_data_encrypted(3).
181 | * @param {Buffer} data - Data to check
182 | * @param {ToxEncryptSave~booleanCallback} [callback]
183 | */
184 | ToxEncryptSave.prototype.isDataEncrypted = function(data, callback) {
185 | this.getLibrary().tox_is_data_encrypted.async(data, function(err, val) {
186 | if(callback) {
187 | callback(err, val);
188 | }
189 | });
190 | };
191 |
192 | /**
193 | * Synchronous tox_is_data_encrypted(3).
194 | * @param {Buffer} data - Data to check
195 | * @return {Boolean} true if data is encrypted, false if not
196 | */
197 | ToxEncryptSave.prototype.isDataEncryptedSync = function(data) {
198 | return this.getLibrary().tox_is_data_encrypted(data);
199 | };
200 |
201 | /**
202 | * Asynchronous tox_derive_key_from_pass(3).
203 | * @param {(Buffer|String)} pass - Password to derive key from
204 | * @param {ToxEncryptSave~passKeyCallback} [callback]
205 | */
206 | ToxEncryptSave.prototype.deriveKeyFromPass = function(pass, callback) {
207 | this._performDerive({
208 | api: this.getLibrary().tox_derive_key_from_pass.async,
209 | pass: pass,
210 | useSalt: false,
211 | async: true, callback: callback
212 | });
213 | };
214 |
215 | /**
216 | * Synchronous tox_derive_key_from_pass(3).
217 | * @param {(Buffer|String)} pass - Password to derive key from
218 | * @return {ToxPassKey} Object containing a key and a salt
219 | */
220 | ToxEncryptSave.prototype.deriveKeyFromPassSync = function(pass) {
221 | return this._performDerive({
222 | api: this.getLibrary().tox_derive_key_from_pass,
223 | pass: pass,
224 | useSalt: false,
225 | async: false
226 | });
227 | };
228 |
229 | /**
230 | * Asynchronous tox_derive_key_with_salt(3).
231 | * @param {(Buffer|String)} pass - Password to derive key from
232 | * @param {Buffer} salt - Salt to use
233 | * @param {ToxEncryptSave~passKeyCallback} [callback]
234 | */
235 | ToxEncryptSave.prototype.deriveKeyWithSalt = function(pass, salt, callback) {
236 | this._performDerive({
237 | api: this.getLibrary().tox_derive_key_with_salt.async,
238 | pass: pass,
239 | salt: salt, useSalt: true,
240 | async: true, callback: callback
241 | });
242 | };
243 |
244 | /**
245 | * Synchronous tox_derive_key_with_salt(3).
246 | * @param {(Buffer|String)} pass - Password to derive key from
247 | * @param {Buffer} salt - Salt to use
248 | * @return {PassKeyObject} Object containing a key and a salt
249 | */
250 | ToxEncryptSave.prototype.deriveKeyWithSaltSync = function(pass, salt) {
251 | return this._performDerive({
252 | api: this.getLibrary().tox_derive_key_with_salt,
253 | pass: pass,
254 | salt: salt, useSalt: true,
255 | async: false
256 | });
257 | };
258 |
259 | /**
260 | * Asynchronous tox_pass_key_encrypt(3).
261 | * @param {Buffer} data - Data to encrypt
262 | * @param {ToxPassKey} passKey
263 | * @param {ToxEncryptSave~dataCallback} [callback]
264 | */
265 | ToxEncryptSave.prototype.encryptPassKey = function(data, passKey, callback) {
266 | var out = new Buffer(data.length + consts.TOX_PASS_ENCRYPTION_EXTRA_LENGTH),
267 | eptr = ref.alloc(TOX_ERR_ENCRYPTION);
268 | this.getLibrary().tox_pass_key_encrypt.async(data, data.length, passKey.ref(), out, eptr, function(err, success) {
269 | var terr = errors.encryption(eptr.deref());
270 | if(!err && terr) err = terr;
271 | if(!err && !success) err = errors.unsuccessful();
272 | if(callback) {
273 | callback(err, out);
274 | }
275 | });
276 | };
277 |
278 | /**
279 | * Synchronous tox_pass_key_encrypt(3).
280 | * @param {Buffer} data - Data to encrypt
281 | * @param {ToxPassKey} passKey
282 | * @return {Buffer} Encrypted data
283 | */
284 | ToxEncryptSave.prototype.encryptPassKeySync = function(data, passKey) {
285 | var out = new Buffer(data.length + consts.TOX_PASS_ENCRYPTION_EXTRA_LENGTH),
286 | eptr = ref.alloc(TOX_ERR_ENCRYPTION),
287 | success = this.getLibrary().tox_pass_key_encrypt(data, data.length, passKey.ref(), out, eptr);
288 | var err = errors.encryption(eptr.deref());
289 | if(err) throw err;
290 | else if(!success) throw errors.unsuccessful();
291 | return out;
292 | };
293 |
294 | /**
295 | * Asynchronous tox_pass_key_decrypt(3).
296 | * @param {Buffer} data - Data to decrypt
297 | * @param {ToxPassKey} passKey
298 | * @param {ToxEncryptSave~dataCallback} [callback]
299 | */
300 | ToxEncryptSave.prototype.decryptPassKey = function(data, passKey, callback) {
301 | var out = new Buffer(data.length - consts.TOX_PASS_ENCRYPTION_EXTRA_LENGTH),
302 | eptr = ref.alloc(TOX_ERR_DECRYPTION);
303 | this.getLibrary().tox_pass_key_decrypt.async(data, data.length, passKey.ref(), out, eptr, function(err, success) {
304 | var terr = errors.decryption(eptr.deref());
305 | if(!err && terr) err = terr;
306 | if(!err && !success) err = errors.unsuccessful();
307 | if(callback) {
308 | callback(err, out);
309 | }
310 | });
311 | };
312 |
313 | /**
314 | * Synchronous tox_pass_key_decrypt(3).
315 | * @param {Buffer} data - Data to decrypt
316 | * @param {ToxPassKey} passKey
317 | * @return {Buffer} Decrypted data
318 | */
319 | ToxEncryptSave.prototype.decryptPassKeySync = function(data, passKey) {
320 | var out = new Buffer(data.length - consts.TOX_PASS_ENCRYPTION_EXTRA_LENGTH),
321 | eptr = ref.alloc(TOX_ERR_DECRYPTION),
322 | success = this.getLibrary().tox_pass_key_decrypt(data, data.length, passKey.ref(), out, eptr);
323 | var err = errors.decryption(eptr.deref());
324 | if(err) throw err;
325 | else if(!success) throw errors.unsuccessful();
326 | return out;
327 | };
328 |
329 | /**
330 | * Asynchronously write data encrypted with a passphrase to a file.
331 | * @param {String} filepath - Filepath
332 | * @param {Buffer} data - Data to encrypt and write
333 | * @param {(Buffer|String)} pass - Passphrase
334 | * @param {ToxEncryptSave~errCallback} [callback]
335 | */
336 | ToxEncryptSave.prototype.encryptFile = function(filepath, data, pass, callback) {
337 | this.encrypt(data, pass, function(err, edata) {
338 | if(!err) {
339 | fs.writeFile(filepath, edata, callback);
340 | } else if(callback) {
341 | callback(err);
342 | }
343 | });
344 | };
345 |
346 | /**
347 | * Synchronously write data encrypted with a passphrase to a file.
348 | * @param {String} filepath - Filepath
349 | * @param {Buffer} data - Data to encrypt and write
350 | * @param {(Buffer|String)} pass - Passphrase
351 | */
352 | ToxEncryptSave.prototype.encryptFileSync = function(filepath, data, pass) {
353 | var edata = this.encryptSync(data, pass);
354 | fs.writeFileSync(filepath, edata);
355 | };
356 |
357 | /**
358 | * Asynchronously decrypt a file with a passphrase.
359 | * @param {String} filepath - Filepath
360 | * @param {(Buffer|String)} pass - Passphrase
361 | * @param {ToxEncryptSave~dataCallback} [callback]
362 | */
363 | ToxEncryptSave.prototype.decryptFile = function(filepath, pass, callback) {
364 | var crypto = this;
365 | fs.readFile(filepath, function(err, data) {
366 | if(!err) {
367 | crypto.decrypt(data, pass, callback);
368 | } else if(callback){
369 | callback(err);
370 | }
371 | });
372 | };
373 |
374 | /**
375 | * Synchronously decrypt a file with a passphrase.
376 | * @param {String} filepath - Filepath
377 | * @param {(Buffer|String)} pass - Passphrase
378 | * @return {Buffer} Decrypted file data
379 | */
380 | ToxEncryptSave.prototype.decryptFileSync = function(filepath, pass) {
381 | var data = fs.readFileSync(filepath);
382 | return this.decryptSync(data, pass);
383 | };
384 |
385 | /**
386 | * Get the internal Library instance.
387 | * @return {ffi.Library}
388 | */
389 | ToxEncryptSave.prototype.getLibrary = function() {
390 | return this._library;
391 | };
392 |
393 | /**
394 | * Helper wrapper function for key derivation functions.
395 | * @private
396 | */
397 | ToxEncryptSave.prototype._performDerive = function(opts) {
398 | var api = opts['api'],
399 | pass = opts['pass'],
400 | salt = opts['salt'], useSalt = opts['useSalt'],
401 | async = opts['async'], callback = opts['callback'];
402 |
403 | if(_.isString(pass)) pass = new Buffer(pass);
404 | var out = ref.alloc(ToxPassKey),
405 | eptr = ref.alloc(TOX_ERR_KEY_DERIVATION);
406 |
407 | if(useSalt) {
408 | api = api.bind(undefined, pass, pass.length, salt, out, eptr);
409 | } else {
410 | api = api.bind(undefined, pass, pass.length, out, eptr);
411 | }
412 |
413 | if(async) {
414 | api(function(err, success) {
415 | var terr = errors.keyDerivation(eptr.deref());
416 | if(!err && terr) err = terr;
417 | if(!err && !success) err = errors.unsuccessful();
418 | if(callback) {
419 | if(!err) {
420 | callback(err, out.deref());
421 | } else {
422 | callback(err);
423 | }
424 | }
425 | });
426 | } else {
427 | var success = api(),
428 | err = errors.keyDerivation(eptr.deref());
429 | if(err) throw err;
430 | else if(!success) throw errors.unsuccessful();
431 | return out.deref();
432 | }
433 | };
434 |
435 | /**
436 | * Callback that returns some boolean.
437 | * @callback ToxEncryptSave~booleanCallback
438 | * @param {Error} error - error, if any
439 | * @param {Boolean} value
440 | */
441 |
442 | /**
443 | * Callback that returns some data in a Buffer.
444 | * @callback ToxEncryptSave~dataCallback
445 | * @param {Error} error - error, if any
446 | * @param {Buffer} data
447 | */
448 |
449 | /**
450 | * Callback that returns a ToxPassKey struct (containing a key and a salt).
451 | * @callback ToxEncryptSave~passKeyCallback
452 | * @param {Error} error - error, if any
453 | * @param {ToxPassKey} passKey - ToxPassKey struct to use in other ToxEncryptSave methods
454 | */
455 |
456 | module.exports = ToxEncryptSave;
457 |
--------------------------------------------------------------------------------
/lib/toxerror.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | "use strict";
20 |
21 | var util = require('util');
22 |
23 | /**
24 | * Creates a ToxError instance
25 | * @class
26 | * @param {String} type of error
27 | * @param {Number} code of type
28 | * @param {String} message of error
29 | */
30 | function ToxError(type, code, message) {
31 | this.name = "ToxError";
32 | this.type = ( type || "ToxError" );
33 | this.code = ( code || 0 ); // 0 = unsuccessful
34 | this.message = ( message || (this.type + ": " + this.code) );
35 | Error.captureStackTrace(this, ToxError);
36 | }
37 |
38 | util.inherits(ToxError, Error);
39 |
40 | exports = module.exports = ToxError;
41 |
--------------------------------------------------------------------------------
/lib/toxoptions.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var ref = require('ref');
20 | var RefStruct = require('ref-struct');
21 |
22 | var CEnum = 'int32';
23 |
24 | var ToxOptions = RefStruct({
25 | 'ipv6_enabled': 'uint8',
26 | 'udp_enabled': 'uint8',
27 | '_padding1': 'uint16',
28 | 'proxy_type': CEnum,
29 | 'proxy_address': ref.refType('char'),
30 | 'proxy_port': 'uint16',
31 | 'start_port': 'uint16',
32 | 'end_port': 'uint16',
33 | 'savedata_type': CEnum,
34 | 'savedata_data': ref.refType('uint8'),
35 | 'savedata_length': 'size_t'
36 | });
37 |
38 | module.exports = ToxOptions;
39 |
--------------------------------------------------------------------------------
/lib/util.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var buffertools = require('buffertools');
20 | var os = require('os');
21 | var ref = require('ref');
22 | var _ = require('underscore');
23 |
24 | buffertools.extend();
25 |
26 | /**
27 | * Convert a hex string to a Buffer. If not a string, will just
28 | * return what's passed to it.
29 | * @param {String} hex - Hex string
30 | * @return {Buffer} data
31 | */
32 | var fromHex = function(hex) {
33 | if(_.isString(hex)) {
34 | return (new Buffer(hex)).fromHex();
35 | }
36 | return hex;
37 | };
38 |
39 | /**
40 | * Try to parse an address:port string.
41 | * @return {Object} Object with address and port if successful,
42 | * undefined if not.
43 | */
44 | var parseAddress = function(str) {
45 | var ex = /^[^:]+:(\\d+)$/;
46 | if(ex.test(str)) {
47 | var res = ex.exec(str);
48 | return {
49 | address: res[1],
50 | port: res[2]
51 | };
52 | }
53 | };
54 |
55 | /**
56 | * Try to parse a Tox proxy string.
57 | * @return {Object} Proxy object if successful, undefined if not
58 | */
59 | var parseProxy = function(str) {
60 | var type;
61 | if(str.indexOf('http://') === 0) {
62 | str = str.slice('http://'.length);
63 | type = 'http';
64 | } else if(str.indexOf('socks://') === 0) {
65 | str = str.slice('socks://'.length);
66 | type = 'socks';
67 | } else if(str.indexOf('socks5://') === 0) {
68 | str = str.slice('socks5://'.length);
69 | type = 'socks';
70 | }
71 |
72 | var proxy = parseAddress(str);
73 | if(proxy) {
74 | proxy.type = type;
75 | return proxy;
76 | }
77 | };
78 |
79 | /**
80 | * Get a "size_t type" (Buffer) from a Number.
81 | * @param {Number} value
82 | * @return {String} size_t
83 | */
84 | var size_t = function(value) {
85 | return value.toString();
86 | /*
87 | if(isNaN(value)) {
88 | // @todo: Throw error
89 | } else if(value < 0) {
90 | // @todo: Throw error
91 | }
92 |
93 | var size = ref.alloc('size_t'),
94 | e = os.endianness();
95 |
96 | size.fill(0);
97 |
98 | // @todo: Fix for 64-bit integers?
99 | if(size.length === 8) {
100 | if(e === 'BE') {
101 | size.writeUInt32BE(value, 4);
102 | } else {
103 | size.writeUInt32LE(value, 0);
104 | }
105 | } else if(size.length === 4) {
106 | if(e === 'BE') {
107 | size.writeUInt32BE(value, 0);
108 | } else {
109 | size.writeUInt32LE(value, 0);
110 | }
111 | } else if (size.length === 2) {
112 | if(e === 'BE') {
113 | size.writeUInt16BE(value, 0);
114 | } else {
115 | size.writeUInt16LE(value, 0);
116 | }
117 | } else if (size.length === 1) {
118 | size.writeUInt8(value, 0);
119 | } else {
120 | // @todo: Throw
121 | }
122 |
123 | return size;
124 | */
125 | };
126 |
127 | /**
128 | * Helper for async functions that pass data through a callback in
129 | * the form of (Error, Buffer). Will translate the Buffer to a hex
130 | * String and pass that instead.
131 | * @param {Function} asyncFunc Asynchronous function to call
132 | * @param {Callback} callback
133 | */
134 | var hexify = function(asyncFunc, callback) {
135 | asyncFunc(function(err, buffer) {
136 | if(callback) {
137 | callback(err, buffer.toHex().toString());
138 | }
139 | });
140 | };
141 |
142 | /**
143 | * Helper for sync functions that return a Buffer. Will translate
144 | * the Buffer to a hex String and return that instead.
145 | * @param {Function} syncFunction Synchronous function to get Buffer from
146 | */
147 | var hexifySync = function(syncFunction) {
148 | var addr = syncFunction();
149 | return addr.toHex().toString();
150 | };
151 |
152 | /**
153 | * Get a Date object from some UInt64. Expects the UInt64 to be represented
154 | * as either a Number or String.
155 | * @param {(Number|String)} timeval
156 | * @return Date object, if timeval is less than 1 or a String this will be (new Date(NaN))
157 | */
158 | var getDateFromUInt64 = function(timeval) {
159 | // According to tox.h, timeval will be a unix-time timestamp,
160 | // so seconds -> milliseconds
161 | var date = new Date(NaN);
162 | if(_.isNumber(timeval) && timeval >= 1) {
163 | date = new Date(timeval * 1000);
164 | }
165 | return date;
166 | };
167 |
168 | module.exports = {
169 | fromHex: fromHex,
170 | getDateFromUInt64: getDateFromUInt64,
171 | hexify: hexify,
172 | hexifySync: hexifySync,
173 | parseProxy: parseProxy,
174 | size_t: size_t
175 | };
176 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "toxcore",
3 | "version": "1.3.0",
4 | "description": "Node bindings for libtoxcore",
5 | "keywords": ["im", "libtoxcore", "node-toxcore", "skype", "tox", "toxcore"],
6 | "license": "GPL-3.0",
7 | "author": {
8 | "name": "saneki",
9 | "email": "s@neki.me"
10 | },
11 | "main": "./lib/main.js",
12 | "files": ["lib", "typings"],
13 | "directories": {
14 | "lib": "./lib"
15 | },
16 | "repository": {
17 | "type": "git",
18 | "url": "https://github.com/saneki/node-toxcore.git"
19 | },
20 | "scripts": {
21 | "test": "mocha"
22 | },
23 | "dependencies": {
24 | "buffertools": "2",
25 | "ffi": "2",
26 | "ref": "^1.2",
27 | "ref-struct": "1",
28 | "ref-array": "1",
29 | "underscore": "1"
30 | },
31 | "devDependencies": {
32 | "async": "1",
33 | "grunt": "0.4",
34 | "grunt-jsdoc": "1",
35 | "grunt-shell": "1",
36 | "ink-docstrap": "0.5",
37 | "jsdoc": "3",
38 | "mktemp": "0.4",
39 | "mocha": "2",
40 | "should": "7"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/test/non-ci/toxdns.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var assert = require('assert');
20 | var buffertools = require('buffertools');
21 | var dns = require('dns');
22 | var path = require('path');
23 | var should = require('should');
24 | var util = require('util');
25 | var ToxDns = require(path.join(__dirname, '..', '..', 'lib', 'toxdns'));
26 |
27 | buffertools.extend(); // Extend Buffer.prototype
28 |
29 | describe('ToxDns (non-CI)', function() {
30 | var toxdns = new ToxDns();
31 |
32 | // This may fail if not resolved within 2 seconds
33 | // These tests seem to always fail on travis-ci, specifically
34 | // finding the id from txts[0][0]
35 | describe('generating and decrypting', function() {
36 | it('should do stuff right (manually)', function(done) {
37 | var info = toxdns.generateSync('saneki'),
38 | full = util.format('_%s._tox.%s', info.record, 'toxme.io');
39 | dns.resolveTxt(full, function(err, txts) {
40 | if(!err) {
41 | var result = txts[0][0],
42 | id = result.match(/(^|;)id=([a-zA-Z0-9]+)/)[2],
43 | addr = toxdns.decryptSync(id, info.id);
44 | addr.should.be.a.Buffer;
45 | done();
46 | } else done(err);
47 | });
48 | });
49 |
50 | it('should do stuff right (manually, async)', function(done) {
51 | toxdns.generate('saneki', function(err, info) {
52 | if(!err) {
53 | var full = util.format('_%s._tox.%s', info.record, 'toxme.io');
54 | dns.resolveTxt(full, function(err, txts) {
55 | if(!err) {
56 | var result = txts[0][0],
57 | id = result.match(/(^|;)id=([a-zA-Z0-9]+)/)[2];
58 | toxdns.decrypt(id, info.id, function(err, addr) {
59 | if(!err) {
60 | addr.should.be.a.Buffer;
61 | done();
62 | } else done(err);
63 | });
64 | } else done(err);
65 | });
66 | } else done(err);
67 | });
68 | });
69 |
70 | it('should do stuff right', function(done) {
71 | toxdns.resolve('saneki@toxme.io', function(err, address) {
72 | if(!err) {
73 | address.should.be.a.Buffer;
74 | done();
75 | } else done(err);
76 | });
77 | });
78 |
79 | it('should do stuff right (hex)', function(done) {
80 | toxdns.resolveHex('saneki@toxme.io', function(err, address) {
81 | if(!err) {
82 | address.should.be.a.string;
83 | done();
84 | } else done(err);
85 | });
86 | });
87 | });
88 | });
89 |
--------------------------------------------------------------------------------
/test/toxdns.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var assert = require('assert');
20 | var should = require('should');
21 | var path = require('path');
22 | var ToxDns = require(path.join(__dirname, '..', 'lib', 'toxdns'));
23 |
24 | describe('ToxDns', function() {
25 | var toxdns = new ToxDns(),
26 | toxdnsKilled = new ToxDns();
27 | toxdnsKilled.killSync();
28 |
29 | describe('#hasHandle()', function() {
30 | it('should return true when handle', function() {
31 | toxdns.hasHandle().should.be.true;
32 | });
33 |
34 | it('should return false when killed', function() {
35 | toxdnsKilled.hasHandle().should.be.false;
36 | });
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/test/toxencryptsave.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var assert = require('assert');
20 | var buffertools = require('buffertools');
21 | var fs = require('fs');
22 | var mktemp = require('mktemp');
23 | var path = require('path');
24 | var should = require('should');
25 |
26 | var ToxEncryptSave = require(path.join(__dirname, '..', 'lib', 'toxencryptsave'));
27 | var consts = require(path.join(__dirname, '..', 'lib', 'consts'));
28 |
29 | buffertools.extend();
30 |
31 | // Helper mktemp functions
32 | var mktempToxSync = mktemp.createFileSync.bind(undefined, 'XXXXX.tox');
33 |
34 | var toxPassKeyToObject = function(passKey) {
35 | return { key: new Buffer(passKey.key), salt: new Buffer(passKey.salt) };
36 | };
37 |
38 | describe('ToxEncryptSave', function() {
39 | var crypto = new ToxEncryptSave();
40 |
41 | describe('encryption and decryption', function() {
42 | it('should detect encrypted data', function() {
43 | var data = new Buffer('hello world'),
44 | edata = crypto.encryptSync(data, 'somePassphrase');
45 | crypto.isDataEncryptedSync(edata).should.be.true;
46 | });
47 |
48 | it('should detect encrypted data (async)', function(done) {
49 | var data = new Buffer('hello async world');
50 | crypto.encrypt(data, 'someAsyncPassphrase', function(err, edata) {
51 | if(!err) {
52 | crypto.isDataEncrypted(edata, function(err, isEnc) {
53 | if(!err) {
54 | isEnc.should.be.true;
55 | done();
56 | } else done(err);
57 | });
58 | } else done(err);
59 | });
60 | });
61 |
62 | it('should be able to decrypt encrypted data', function() {
63 | var data = new Buffer('some encrypted data'),
64 | passphrase = 'somePassphrase',
65 | edata = crypto.encryptSync(data, passphrase);
66 |
67 | // Encrypted data should differ from original
68 | edata.should.be.a.Buffer;
69 | (edata.equals(data)).should.be.false;
70 |
71 | var ddata = crypto.decryptSync(edata, passphrase);
72 |
73 | (ddata.equals(data)).should.be.true;
74 | });
75 |
76 | it('should be able to decrypt encrypted data (async)', function(done) {
77 | var data = new Buffer('some encrypted data'),
78 | passphrase = 'somePassphrase';
79 | crypto.encrypt(data, passphrase, function(err, edata) {
80 | if(!err) {
81 | // Encrypted data should differ from original
82 | edata.should.be.a.Buffer;
83 | (edata.equals(data)).should.be.false;
84 |
85 | crypto.decrypt(edata, passphrase, function(err, ddata) {
86 | (ddata.equals(data)).should.be.true;
87 | done(err);
88 | });
89 | } else done(err);
90 | });
91 | });
92 |
93 | it('should be able to decrypt encrypted data from pass key', function() {
94 | var passKey = crypto.deriveKeyFromPassSync('passphrase'),
95 | data = new Buffer('encrypt me with a pass key struct'),
96 | edata = crypto.encryptPassKeySync(data, passKey);
97 |
98 | (edata.equals(data)).should.be.false;
99 |
100 | var ddata = crypto.decryptPassKeySync(edata, passKey);
101 |
102 | (ddata.equals(data)).should.be.true;
103 | });
104 |
105 | it('should be able to decrypt encrypted data from pass key (async)', function(done) {
106 | var data = new Buffer('encrypt me with a pass key struct async');
107 | crypto.deriveKeyFromPass('somePass', function(err, passKey) {
108 | if(!err) {
109 | crypto.encryptPassKey(data, passKey, function(err, edata) {
110 | if(!err) {
111 | (edata.equals(data)).should.be.false;
112 | crypto.decryptPassKey(edata, passKey, function(err, ddata) {
113 | if(!err) {
114 | (ddata.equals(data)).should.be.true;
115 | done();
116 | } else done(err);
117 | });
118 | } else done(err);
119 | });
120 | } else done(err);
121 | });
122 | });
123 |
124 | it('should get the salt from encrypted data', function() {
125 | var pass = 'somePassword',
126 | data = new Buffer('some data'),
127 | edata = crypto.encryptSync(data, pass),
128 | salt = crypto.getSaltSync(edata);
129 | salt.should.be.a.Buffer;
130 | salt.length.should.equal(consts.TOX_PASS_SALT_LENGTH);
131 | });
132 |
133 | it('should get the salt from encrypted data (async)', function(done) {
134 | var pass = 'somePassphrase',
135 | data = new Buffer('encrypt me');
136 | crypto.encrypt(data, pass, function(err, edata) {
137 | if(!err) {
138 | crypto.getSalt(edata, function(err, salt) {
139 | if(!err) {
140 | salt.should.be.a.Buffer;
141 | salt.length.should.equal(consts.TOX_PASS_SALT_LENGTH);
142 | done();
143 | } else done(err);
144 | });
145 | } else done(err);
146 | });
147 | });
148 | });
149 |
150 | describe('encryption and decryption (file helpers)', function() {
151 | it('should encrypt and decrypt to/from files', function() {
152 | var data = new Buffer('encrypt me to a file'),
153 | pass = 'somePassword',
154 | temp = mktempToxSync();
155 | crypto.encryptFileSync(temp, data, pass);
156 | var ddata = crypto.decryptFileSync(temp, pass);
157 | (ddata.equals(data)).should.be.true;
158 | fs.unlinkSync(temp);
159 | });
160 |
161 | it('should encrypt and decrypt to/from files (async)', function(done) {
162 | var data = new Buffer('encrypt me to a file async'),
163 | pass = 'somePassphrase',
164 | temp = mktempToxSync();
165 | crypto.encryptFile(temp, data, pass, function(err) {
166 | if(!err) {
167 | crypto.decryptFile(temp, pass, function(err, ddata) {
168 | if(!err) {
169 | (ddata.equals(data)).should.be.true;
170 | fs.unlinkSync(temp);
171 | done();
172 | } else {
173 | fs.unlinkSync(temp);
174 | done(err);
175 | }
176 | });
177 | } else {
178 | fs.unlinkSync(temp);
179 | done(err);
180 | }
181 | });
182 | });
183 | });
184 |
185 | describe('key derivation', function() {
186 | it('should derive a key with a random salt', function() {
187 | var obj = toxPassKeyToObject(crypto.deriveKeyFromPassSync('somePassword'));
188 | obj.key.should.be.a.Buffer;
189 | obj.key.length.should.equal(consts.TOX_PASS_KEY_LENGTH);
190 | obj.salt.should.be.a.Buffer;
191 | obj.salt.length.should.equal(consts.TOX_PASS_SALT_LENGTH);
192 | });
193 |
194 | it('should derive a key with a random salt (async)', function(done) {
195 | crypto.deriveKeyFromPass('somePassphrase', function(err, obj) {
196 | if(!err) {
197 | obj = toxPassKeyToObject(obj);
198 | obj.key.should.be.a.Buffer;
199 | obj.key.length.should.equal(consts.TOX_PASS_KEY_LENGTH);
200 | obj.salt.should.be.a.Buffer;
201 | obj.salt.length.should.equal(consts.TOX_PASS_SALT_LENGTH);
202 | done();
203 | } else done(err);
204 | });
205 | });
206 |
207 | it('should derive a key with a given salt', function() {
208 | var pass = 'somePassphrase',
209 | obj = toxPassKeyToObject(crypto.deriveKeyFromPassSync(pass)),
210 | otherObj = toxPassKeyToObject(crypto.deriveKeyWithSaltSync(pass, obj.salt));
211 | (obj.salt.equals(otherObj.salt)).should.be.true;
212 | (obj.key.equals(otherObj.key)).should.be.true;
213 | });
214 |
215 | it('should derive a key with a given salt (async)', function(done) {
216 | var pass = 'asyncPassword';
217 | crypto.deriveKeyFromPass(pass, function(err, obj) {
218 | if(!err) {
219 | obj = toxPassKeyToObject(obj);
220 | crypto.deriveKeyWithSalt(pass, obj.salt, function(err, otherObj) {
221 | if(!err) {
222 | otherObj = toxPassKeyToObject(otherObj);
223 | (obj.salt.equals(otherObj.salt)).should.be.true;
224 | (obj.key.equals(otherObj.key)).should.be.true;
225 | done();
226 | } else done(err);
227 | });
228 | } else done(err);
229 | });
230 | });
231 | });
232 | });
233 |
--------------------------------------------------------------------------------
/test/util.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of node-toxcore.
3 | *
4 | * node-toxcore is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * node-toxcore is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with node-toxcore. If not, see .
16 | *
17 | */
18 |
19 | var assert = require('assert');
20 | var buffertools = require('buffertools');
21 | var should = require('should');
22 | var path = require('path');
23 | var util = require(path.join(__dirname, '..', 'lib', 'util'));
24 | var size_t = util.size_t;
25 |
26 | buffertools.extend(); // Extend Buffer.prototype
27 |
28 | describe('util', function() {
29 | describe('#size_t()', function() {
30 | it('should return a Buffer', function() {
31 | var zeroSize = size_t(0);
32 | should.exist(zeroSize);
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/typings/toxcore.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for toxcore 1.3.0
2 | // Project: https://github.com/saneki/node-toxcore
3 | // Definitions by: saneki
4 | // Definitions: https://github.com/borisyankov/DefinitelyTyped
5 |
6 | declare module 'toxcore' {
7 | import events = require('events');
8 | import EventEmitter = events.EventEmitter;
9 |
10 | interface ErrorCallback {
11 | (err: Error): void;
12 | }
13 |
14 | interface BooleanCallback {
15 | (err: Error, val: boolean): void;
16 | }
17 |
18 | interface BufferCallback {
19 | (err: Error, val: Buffer): void;
20 | }
21 |
22 | interface DateCallback {
23 | (err: Error, val: Date): void;
24 | }
25 |
26 | interface NumberCallback {
27 | (err: Error, val: number): void;
28 | }
29 |
30 | interface StringCallback {
31 | (err: Error, val: string): void;
32 | }
33 |
34 | interface NumberArrayCallback {
35 | (err: Error, list: number[]): void;
36 | }
37 |
38 | interface StringArrayCallback {
39 | (err: Error, list: string[]): void;
40 | }
41 |
42 | interface ToxCallback {
43 | (err: Error, tox: Tox): void;
44 | }
45 |
46 | interface GenerateObject {
47 | record: string;
48 | id: number;
49 | }
50 |
51 | interface GenerateCallback {
52 | (err: Error, generate: GenerateObject): void;
53 | }
54 |
55 | interface ToxDnsConstructorOptions {
56 | path?: string;
57 | key?: Buffer|string;
58 | }
59 |
60 | interface ToxDns {
61 | constructor(opts?: ToxDnsConstructorOptions);
62 | hasHandle(): boolean;
63 | getHandle(): any;
64 | getKey(): Buffer;
65 | getKeyHex(): string;
66 | getLibrary(): any;
67 | resolve(address: string, callback?: BufferCallback): void;
68 | resolveHex(address: string, callback?: StringCallback): void;
69 |
70 | decrypt(record: string, requestId: number, callback?: BufferCallback): void;
71 | decryptSync(record: string, requestId: number): Buffer;
72 | generate(name: string, callback?: GenerateCallback): void;
73 | generateSync(name: string): GenerateObject;
74 | kill(callback?: ErrorCallback): void;
75 | killSync(): void;
76 | }
77 |
78 | interface ToxPassKey {
79 | }
80 |
81 | interface ToxPassKeyCallback {
82 | (err: Error, passKey: ToxPassKey): void;
83 | }
84 |
85 | interface ToxEncryptSaveConstructorOptions {
86 | path?: string;
87 | }
88 |
89 | export class ToxEncryptSave {
90 | constructor(opts?: ToxEncryptSaveConstructorOptions);
91 | getLibrary(): any; // ffi.Library
92 |
93 | decrypt(data: Buffer, pass: Buffer|string, callback?: BufferCallback): void;
94 | decryptSync(data: Buffer, pass: Buffer|string): Buffer;
95 | encrypt(data: Buffer, pass: Buffer|string, callback?: BufferCallback): void;
96 | encryptSync(data: Buffer, pass: Buffer|string): Buffer;
97 | getSalt(data: Buffer, callback?: BufferCallback): void;
98 | getSaltSync(data: Buffer): Buffer;
99 | isDataEncrypted(data: Buffer, callback?: BooleanCallback): void;
100 | isDataEncryptedSync(data: Buffer): boolean;
101 | deriveKeyFromPass(pass: Buffer|string, callback?: ToxPassKeyCallback): void;
102 | deriveKeyFromPassSync(pass: Buffer|string): ToxPassKey;
103 | deriveKeyWithSalt(pass: Buffer|string, salt: Buffer, callback?: ToxPassKeyCallback): void;
104 | deriveKeyWithSaltSync(pass: Buffer|string, salt: Buffer): ToxPassKey;
105 | encryptFile(filepath: string, data: Buffer, pass: Buffer|string, callback?: ErrorCallback): void;
106 | encryptFileSync(filepath: string, data: Buffer, pass: Buffer|string): void;
107 | encryptPassKey(data: Buffer, passKey: ToxPassKey, callback?: BufferCallback): void;
108 | encryptPassKeySync(data: Buffer, passKey: ToxPassKey): Buffer;
109 | decryptFile(filepath: string, pass: Buffer|string, callback?: BufferCallback): void;
110 | decryptFileSync(filepath: string, pass: Buffer|string): Buffer;
111 | decryptPassKey(data: Buffer, passKey: ToxPassKey, callback?: BufferCallback): void;
112 | decryptPassKeySync(data: Buffer, passKey: ToxPassKey): Buffer;
113 | }
114 |
115 | interface ToxConstructorOptions {
116 | path?: string;
117 | data?: Buffer|string;
118 | crypto?: ToxEncryptSave|boolean|Object|string;
119 | }
120 |
121 | // Leaving out freeOptions/newOptions functions
122 | export class Tox {
123 | constructor(opts?: ToxConstructorOptions);
124 | static load(opts: ToxConstructorOptions, callback: ToxCallback): void;
125 | static load(callback: ToxCallback): void;
126 |
127 | createLibrary(libpath?: string): any; // ffi.Library
128 | crypto(): ToxEncryptSave;
129 | free(): void;
130 | getEmitter(): EventEmitter;
131 | getHandle(): any;
132 | getLibrary(): any; // ffi.Library
133 | hasCrypto(): boolean;
134 | hasHandle(): boolean;
135 | isStarted(): boolean;
136 | isTcp(): boolean;
137 | isUdp(): boolean;
138 | old(): ToxOld; // May also return undefined
139 | off(name: string, callback: Function): void;
140 | on(name: string, callback?: Function): void;
141 | saveToFile(filepath: string, callback?: ErrorCallback): void;
142 | saveToFileSync(filepath: string): void;
143 | start(wait?: number): void;
144 | stop(): void;
145 |
146 | addFriend(addr: Buffer, message: string, callback?: NumberCallback): void;
147 | addFriend(addr: string, message: string, callback?: NumberCallback): void;
148 | addFriendSync(addr: Buffer, message: string): number;
149 | addFriendSync(addr: string, message: string): number;
150 | addFriendNoRequest(publicKey: Buffer, callback?: NumberCallback): void;
151 | addFriendNoRequest(publicKey: string, callback?: NumberCallback): void;
152 | addFriendNoRequestSync(publicKey: Buffer): number;
153 | addFriendNoRequestSync(publicKey: string): number;
154 | addTCPRelay(address: string, port: number, publicKey: Buffer, callback?: ErrorCallback): void;
155 | addTCPRelay(address: string, port: number, publicKey: string, callback?: ErrorCallback): void;
156 | addTCPRelaySync(address: string, port: number, publicKey: Buffer): void;
157 | addTCPRelaySync(address: string, port: number, publicKey: string): void;
158 | bootstrap(address: string, port: number, publicKey: string, callback?: ErrorCallback): void;
159 | bootstrap(address: string, port: number, publicKey: Buffer, callback?: ErrorCallback): void;
160 | bootstrapSync(address: string, port: number, publicKey: string): void;
161 | bootstrapSync(address: string, port: number, publicKey: Buffer): void;
162 | // todo: control: (number|string)
163 | controlFile(friendnum: number, filenum: number, control: number, callback?: ErrorCallback): void;
164 | controlFileSync(friendnum: number, filenum: number, control: number|string): void;
165 | deleteFriend(friendnum: number, callback?: ErrorCallback): void;
166 | deleteFriendSync(friendnum: number): void;
167 | getAddress(callback?: BufferCallback): void;
168 | getAddressSync(): Buffer;
169 | getAddressHex(callback?: StringCallback): void;
170 | getAddressHexSync(): string;
171 | getConnectionStatus(callback?: NumberCallback): void;
172 | getConnectionStatusSync(): number;
173 | getFileId(friendnum: number, filenum: number, callback?: BufferCallback): void;
174 | getFileIdSync(friendnum: number, filenum: number): Buffer;
175 | getFriendByPublicKey(publicKey: Buffer, callback?: NumberCallback): void;
176 | getFriendByPublicKey(publicKey: string, callback?: NumberCallback): void;
177 | getFriendByPublicKeySync(publicKey: Buffer): number;
178 | getFriendByPublicKeySync(publicKey: string): number;
179 | getFriendConnectionStatus(friendnum: number, callback?: NumberCallback): void;
180 | getFriendConnectionStatusSync(friendnum: number): number;
181 | getFriendLastOnline(friendnum: number, callback?: DateCallback): void;
182 | getFriendLastOnlineSync(friendnum: number): Date;
183 | getFriendListSize(callback?: NumberCallback): void;
184 | getFriendListSizeSync(): number;
185 | getFriendList(callback?: NumberArrayCallback): void;
186 | getFriendListSync(): number[];
187 | getFriendName(friendnum: number, callback?: StringCallback): void;
188 | getFriendNameSync(friendnum: number): string;
189 | getFriendNameSize(friendnum: number, callback?: NumberCallback): void;
190 | getFriendNameSizeSync(friendnum: number): number;
191 | getFriendPublicKey(friendnum: number, callback?: BufferCallback): void;
192 | getFriendPublicKeySync(friendnum: number): Buffer;
193 | getFriendPublicKeyHex(friendnum: number, callback?: StringCallback): void;
194 | getFriendPublicKeyHexSync(friendnum: number): string;
195 | getFriendStatus(friendnum: number, callback?: NumberCallback): void;
196 | getFriendStatusSync(friendnum: number): number;
197 | getFriendStatusMessage(friendnum: number, callback?: StringCallback): void;
198 | getFriendStatusMessageSync(friendnum: number): string;
199 | getFriendStatusMessageSize(friendnum: number, callback?: NumberCallback): void;
200 | getFriendStatusMessageSizeSync(friendnum: number): number;
201 | getName(callback?: StringCallback): void;
202 | getNameSync(): string;
203 | getNameSize(callback?: NumberCallback): void;
204 | getNameSizeSync(): number;
205 | getNospam(callback?: NumberCallback): void;
206 | getNospamSync(): number;
207 | getPublicKey(callback?: BufferCallback): void;
208 | getPublicKeySync(): Buffer;
209 | getPublicKeyHex(callback?: StringCallback): void;
210 | getPublicKeyHexSync(): string;
211 | getSavedata(callback?: BufferCallback): void;
212 | getSavedataSync(): Buffer;
213 | getSavedataSize(callback?: NumberCallback): void;
214 | getSavedataSizeSync(): number;
215 | getSecretKey(callback?: BufferCallback): void;
216 | getSecretKeySync(): Buffer;
217 | getSecretKeyHex(callback?: StringCallback): void;
218 | getSecretKeyHexSync(): string;
219 | getStatus(callback?: NumberCallback): void;
220 | getStatusSync(): number;
221 | getStatusMessage(callback?: StringCallback): void;
222 | getStatusMessageSync(): string;
223 | getStatusMessageSize(callback?: NumberCallback): void;
224 | getStatusMessageSizeSync(): number;
225 | getTcpPort(callback?: NumberCallback): void;
226 | getTcpPortSync(): number;
227 | getUdpPort(callback?: NumberCallback): void;
228 | getUdpPortSync(): number;
229 | hash(buf: Buffer, callback?: BufferCallback): void;
230 | hashSync(buf: Buffer): Buffer;
231 | hash(buf: string, callback?: BufferCallback): void;
232 | hashSync(buf: string): Buffer;
233 | hasFriend(friendnum: number, callback?: BooleanCallback): void;
234 | hasFriendSync(friendnum: number): boolean;
235 | iterate(callback?: ErrorCallback): void;
236 | iterateSync(): void;
237 | iterationInterval(callback?: NumberCallback): void;
238 | iterationIntervalSync(): number;
239 | kill(callback?: ErrorCallback): void;
240 | killSync(): void;
241 | seekFile(friendnum: number, filenum: number, position: number, callback?: ErrorCallback): void;
242 | seekFileSync(friendnum: number, filenum: number, position: number): void;
243 | // Todo: fileid should be optional
244 | sendFile(friendnum: number, kind: number, filename: string, size: number, fileid: Buffer, callback?: NumberCallback): void;
245 | sendFileSync(friendnum: number, kind: number, filename: string, size: number, fileid?: Buffer): number;
246 | sendFileChunk(friendnum: number, filenum: number, position: number, data: Buffer, callback?: ErrorCallback): void;
247 | sendFileChunkSync(friendnum: number, filenum: number, position: number, data: Buffer): void;
248 | // Todo: Support more than just string 'type' for sendFriendMessage
249 | sendFriendMessage(friendnum: number, message: string, callback?: NumberCallback): void;
250 | sendFriendMessage(friendnum: number, message: string, type: string, callback?: NumberCallback): void;
251 | sendFriendMessageSync(friendnum: number, message: string, type?: string): number;
252 | sendLosslessPacket(friendnum: number, data: Buffer, callback?: ErrorCallback): void;
253 | sendLosslessPacket(friendnum: number, id: number, data: Buffer, callback?: ErrorCallback): void;
254 | sendLosslessPacketSync(friendnum: number, data: Buffer): void;
255 | sendLosslessPacketSync(friendnum: number, id: number, data: Buffer): void;
256 | sendLossyPacket(friendnum: number, data: Buffer, callback?: ErrorCallback): void;
257 | sendLossyPacket(friendnum: number, id: number, data: Buffer, callback?: ErrorCallback): void;
258 | sendLossyPacketSync(friendnum: number, data: Buffer): void;
259 | sendLossyPacketSync(friendnum: number, id: number, data: Buffer): void;
260 | setName(name: string, callback?: ErrorCallback): void;
261 | setNameSync(name: string): void;
262 | setNospam(nospam: number, callback?: ErrorCallback): void;
263 | setNospamSync(nospam: number): void;
264 | setStatus(status: number, callback?: ErrorCallback): void;
265 | setStatusSync(status: number): void;
266 | setStatusMessage(status: string, callback?: ErrorCallback): void;
267 | setStatusMessageSync(status: string): void;
268 | setTyping(friendnum: number, typing: boolean, callback?: ErrorCallback): void;
269 | setTypingSync(friendnum: number, typing: boolean): void;
270 | versionMajor(callback?: NumberCallback): void;
271 | versionMajorSync(): number;
272 | versionMinor(callback?: NumberCallback): void;
273 | versionMinorSync(): number;
274 | versionPatch(callback?: NumberCallback): void;
275 | versionPatchSync(): number;
276 | }
277 |
278 | interface ToxOldConstructorOptions {
279 | path?: string;
280 | tox: Tox;
281 | }
282 |
283 | export class ToxOld {
284 | constructor(opts?: ToxOldConstructorOptions);
285 | createLibrary(libpath?: string): any; // ffi.Library
286 | getEmitter(): EventEmitter;
287 | getHandle(): any;
288 | getLibrary(): any; // ffi.Library
289 | hasHandle(): boolean;
290 | off(name: string, callback: Function): void;
291 | on(name: string, callback?: Function): void;
292 | tox(): Tox;
293 |
294 | addGroupchat(callback?: NumberCallback): void;
295 | addGroupchatSync(): number;
296 | deleteGroupchat(groupnum: number, callback?: ErrorCallback): void;
297 | deleteGroupchatSync(groupnum: number): void;
298 | getGroupchats(callback?: NumberArrayCallback): void;
299 | getGroupchatsSync(): number[];
300 | getGroupchatCount(callback?: NumberCallback): void;
301 | getGroupchatCountSync(): number;
302 | getGroupchatPeername(groupnum: number, peernum: number, callback?: StringCallback): void;
303 | getGroupchatPeernameSync(groupnum: number, peernum: number): string;
304 | getGroupchatPeerCount(groupnum: number, callback?: NumberCallback): void;
305 | getGroupchatPeerCountSync(groupnum: number): number;
306 | getGroupchatPeerNames(groupnum: number, callback?: StringArrayCallback): void;
307 | getGroupchatPeerNamesSync(groupnum: number): string[];
308 | getGroupchatPeerPublicKey(groupnum: number, peernum: number, callback?: BufferCallback): void;
309 | getGroupchatPeerPublicKeySync(groupnum: number, peernum: number): Buffer;
310 | getGroupchatPeerPublicKeyHex(groupnum: number, peernum: number, callback?: StringCallback): void;
311 | getGroupchatPeerPublicKeyHexSync(groupnum: number, peernum: number): string;
312 | getGroupchatTitle(groupnum: number, callback?: StringCallback): void;
313 | getGroupchatTitleSync(groupnum: number): string;
314 | invite(friendnum: number, groupnum: number, callback?: ErrorCallback): void;
315 | inviteSync(friendnum: number, groupnum: number): void;
316 | joinGroupchat(friendnum: number, data: Buffer, callback?: ErrorCallback): void;
317 | joinGroupchatSync(friendnum: number, data: Buffer): number;
318 | peernumberIsOurs(groupnum: number, peernum: number, callback?: BooleanCallback): void;
319 | peernumberIsOursSync(groupnum: number, peernum: number): boolean;
320 | sendGroupchatAction(groupnum: number, action: string, callback?: ErrorCallback): void;
321 | sendGroupchatActionSync(groupnum: number, action: string): void;
322 | sendGroupchatMessage(groupnum: number, message: string, callback?: ErrorCallback): void;
323 | sendGroupchatMessageSync(groupnum: number, message: string): void;
324 | setGroupchatTitle(groupnum: number, title: string, callback?: ErrorCallback): void;
325 | setGroupchatTitleSync(groupnum: number, title: string): void;
326 | }
327 |
328 | export var Consts : {
329 | TOX_KEY_SIZE: number, //32,
330 | TOX_FRIEND_ADDRESS_SIZE: number, //(32 + 6),
331 |
332 | TOX_PUBLIC_KEY_SIZE: number, //32,
333 | TOX_SECRET_KEY_SIZE: number, //32,
334 | TOX_ADDRESS_SIZE: number, //(32 + 6),
335 | TOX_MAX_NAME_LENGTH: number, //128,
336 | TOX_MAX_STATUS_MESSAGE_LENGTH: number //1007,
337 | TOX_MAX_FRIEND_REQUEST_LENGTH: number, //1016,
338 | TOX_MAX_MESSAGE_LENGTH: number, //1372,
339 | TOX_MAX_CUSTOM_PACKET_SIZE: number, //1373,
340 | TOX_HASH_LENGTH: number, //32,
341 | TOX_FILE_ID_LENGTH: number, //32,
342 | TOX_MAX_FILENAME_LENGTH: number, //255,
343 |
344 | TOX_CONNECTION_NONE: number, //0,
345 | TOX_CONNECTION_TCP: number, //1,
346 | TOX_CONNECTION_UDP: number, //2,
347 |
348 | TOX_MESSAGE_TYPE_NORMAL: number, //0,
349 | TOX_MESSAGE_TYPE_ACTION: number, //1,
350 |
351 | TOX_USER_STATUS_NONE: number, //0,
352 | TOX_USER_STATUS_AWAY: number, //1,
353 | TOX_USER_STATUS_BUSY: number, //2,
354 |
355 | TOX_ERR_FILE_CONTROL_OK: number, //0,
356 | TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND: number, //1,
357 | TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED: number, //2,
358 | TOX_ERR_FILE_CONTROL_NOT_FOUND: number, //3,
359 | TOX_ERR_FILE_CONTROL_NOT_PAUSED: number, //4,
360 | TOX_ERR_FILE_CONTROL_DENIED: number, //5,
361 | TOX_ERR_FILE_CONTROL_ALREADY_PAUSED: number, //6,
362 | TOX_ERR_FILE_CONTROL_SENDQ: number, //7,
363 |
364 | TOX_ERR_FILE_GET_OK: number, //0,
365 | TOX_ERR_FILE_GET_FRIEND_NOT_FOUND: number, //1,
366 | TOX_ERR_FILE_GET_NOT_FOUND: number, //2,
367 |
368 | TOX_ERR_FILE_SEEK_OK: number, //0,
369 | TOX_ERR_FILE_SEEK_FRIEND_NOT_FOUND: number, //1,
370 | TOX_ERR_FILE_SEEK_FRIEND_NOT_CONNECTED: number, //2,
371 | TOX_ERR_FILE_SEEK_NOT_FOUND: number, //3,
372 | TOX_ERR_FILE_SEEK_DENIED: number, //4,
373 | TOX_ERR_FILE_SEEK_INVALID_POSITION: number, //5,
374 | TOX_ERR_FILE_SEEK_SENDQ: number, //6,
375 |
376 | TOX_ERR_FILE_SEND_OK: number, //0,
377 | TOX_ERR_FILE_SEND_NULL: number, //1,
378 | TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND: number, //2,
379 | TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED: number, //3,
380 | TOX_ERR_FILE_SEND_NAME_TOO_LONG: number, //4,
381 | TOX_ERR_FILE_SEND_TOO_MANY: number, //5,
382 |
383 | TOX_ERR_FILE_SEND_CHUNK_OK: number, //0,
384 | TOX_ERR_FILE_SEND_CHUNK_NULL: number, //1,
385 | TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_FOUND: number, //2,
386 | TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED: number, //3,
387 | TOX_ERR_FILE_SEND_CHUNK_NOT_FOUND: number, //4,
388 | TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING: number, //5,
389 | TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH: number, //6,
390 | TOX_ERR_FILE_SEND_CHUNK_SENDQ: number, //7,
391 | TOX_ERR_FILE_SEND_CHUNK_WRONG_POSITION: number, //8,
392 |
393 | TOX_ERR_FRIEND_ADD_OK: number, //0,
394 | TOX_ERR_FRIEND_ADD_NULL: number, //1,
395 | TOX_ERR_FRIEND_ADD_TOO_LONG: number, //2,
396 | TOX_ERR_FRIEND_ADD_NO_MESSAGE: number, //3,
397 | TOX_ERR_FRIEND_ADD_OWN_KEY: number, //4,
398 | TOX_ERR_FRIEND_ADD_ALREADY_SENT: number, //5,
399 | TOX_ERR_FRIEND_ADD_BAD_CHECKSUM: number, //6,
400 | TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM: number, //7,
401 | TOX_ERR_FRIEND_ADD_MALLOC: number, //8,
402 |
403 | TOX_ERR_FRIEND_CUSTOM_PACKET_OK: number, //0,
404 | TOX_ERR_FRIEND_CUSTOM_PACKET_NULL: number, //1,
405 | TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_FOUND: number, //2,
406 | TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_CONNECTED: number, //3,
407 | TOX_ERR_FRIEND_CUSTOM_PACKET_INVALID: number, //4,
408 | TOX_ERR_FRIEND_CUSTOM_PACKET_EMPTY: number, //5,
409 | TOX_ERR_FRIEND_CUSTOM_PACKET_TOO_LONG: number, //6,
410 | TOX_ERR_FRIEND_CUSTOM_PACKET_SENDQ: number, //7,
411 |
412 | TOX_ERR_FRIEND_DELETE_OK: number, //0,
413 | TOX_ERR_FRIEND_DELETE_FRIEND_NOT_FOUND: number, //1,
414 |
415 | TOX_ERR_FRIEND_GET_LAST_ONLINE_OK: number, //0,
416 | TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND: number, //1,
417 |
418 | TOX_ERR_FRIEND_QUERY_OK: number, //0,
419 | TOX_ERR_FRIEND_QUERY_NULL: number, //1,
420 | TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND: number, //2,
421 |
422 | TOX_ERR_FRIEND_SEND_MESSAGE_OK: number, //0,
423 | TOX_ERR_FRIEND_SEND_MESSAGE_NULL: number, //1,
424 | TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_FOUND: number, //2,
425 | TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_CONNECTED: number, //3,
426 | TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ: number, //4,
427 | TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG: number, //5,
428 | TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY: number, //6,
429 |
430 | TOX_ERR_NEW_OK: number, //0,
431 | TOX_ERR_NEW_NULL: number, //1,
432 | TOX_ERR_NEW_MALLOC: number, //2,
433 | TOX_ERR_NEW_PORT_ALLOC: number, //3,
434 | TOX_ERR_NEW_PROXY_TYPE: number, //4,
435 | TOX_ERR_NEW_PROXY_BAD_HOST: number, //5,
436 | TOX_ERR_NEW_PROXY_BAD_PORT: number, //6,
437 | TOX_ERR_NEW_PROXY_NOT_FOUND: number, //7,
438 | TOX_ERR_NEW_LOAD_ENCRYPTED: number, //8,
439 | TOX_ERR_NEW_LOAD_DECRYPTION_FAILED: number, //9,
440 | TOX_ERR_NEW_LOAD_BAD_FORMAT: number, //10,
441 |
442 | TOX_ERR_OPTIONS_NEW_OK: number, //0,
443 | TOX_ERR_OPTIONS_NEW_MALLOC: number, //1,
444 |
445 | TOX_ERR_BOOTSTRAP_OK: number, //0,
446 | TOX_ERR_BOOTSTRAP_NULL: number, //1,
447 | TOX_ERR_BOOTSTRAP_BAD_HOST: number, //2,
448 | TOX_ERR_BOOTSTRAP_BAD_PORT: number, //3,
449 |
450 | TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK: number, //0,
451 | TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL: number, //1,
452 | TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND: number, //2,
453 |
454 | TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK: number, //0,
455 | TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND: number, //1,
456 |
457 | TOX_ERR_GET_PORT_OK: number, //0,
458 | TOX_ERR_GET_PORT_NOT_BOUND: number, //1,
459 |
460 | TOX_ERR_SET_INFO_OK: number, //0,
461 | TOX_ERR_SET_INFO_NULL: number, //1,
462 | TOX_ERR_SET_INFO_TOO_LONG: number, //2,
463 |
464 | TOX_ERR_SET_TYPING_OK: number, //0,
465 | TOX_ERR_SET_TYPING_FRIEND_NOT_FOUND: number, //1,
466 |
467 | TOX_FILE_KIND_DATA: number, //0,
468 | TOX_FILE_KIND_AVATAR: number, //1,
469 |
470 | TOX_FILE_CONTROL_RESUME: number, //0,
471 | TOX_FILE_CONTROL_PAUSE: number, //1,
472 | TOX_FILE_CONTROL_CANCEL: number, //2,
473 |
474 | TOX_PROXY_TYPE_NONE: number, //0,
475 | TOX_PROXY_TYPE_HTTP: number, //1,
476 | TOX_PROXY_TYPE_SOCKS5: number, //2,
477 |
478 | TOX_SAVEDATA_TYPE_NONE: number, //0,
479 | TOX_SAVEDATA_TYPE_TOX_SAVE: number, //1,
480 | TOX_SAVEDATA_TYPE_SECRET_KEY: number, //2
481 |
482 | TOX_PASS_KEY_LENGTH: number, //32,
483 | TOX_PASS_SALT_LENGTH: number, //32,
484 | TOX_PASS_ENCRYPTION_EXTRA_LENGTH: number, //80,
485 |
486 | TOX_ERR_DECRYPTION_OK: number, //0,
487 | TOX_ERR_DECRYPTION_NULL: number, //1,
488 | TOX_ERR_DECRYPTION_INVALID_LENGTH: number, //2,
489 | TOX_ERR_DECRYPTION_BAD_FORMAT: number, //3,
490 | TOX_ERR_DECRYPTION_KEY_DERIVATION_FAILED: number, //4,
491 | TOX_ERR_DECRYPTION_FAILED: number, //5,
492 |
493 | TOX_ERR_ENCRYPTION_OK: number, //0,
494 | TOX_ERR_ENCRYPTION_NULL: number, //1,
495 | TOX_ERR_ENCRYPTION_KEY_DERIVATION_FAILED: number, //2,
496 | TOX_ERR_ENCRYPTION_FAILED: number, //3,
497 |
498 | TOX_ERR_KEY_DERIVATION_OK: number, //0,
499 | TOX_ERR_KEY_DERIVATION_NULL: number, //1,
500 | TOX_ERR_KEY_DERIVATION_FAILED: number, //2
501 | }
502 | }
503 |
--------------------------------------------------------------------------------