Initial commit

This commit is contained in:
Tha_14
2024-02-22 21:43:11 +02:00
commit 1b96a031d2
1108 changed files with 157706 additions and 0 deletions

View File

@ -0,0 +1,39 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
#import "OCTFileStorageProtocol.h"
/**
* Default storage for files. It has following directory structure:
* /baseDirectory/saveFileName.tox - tox save file name. You can specify it in appropriate method.
* /baseDirectory/database - database with chats, messages and related stuff.
* /baseDirectory/database.encryptionkey - encryption key for database.
* /baseDirectory/files/ - downloaded and uploaded files will be stored here.
* /baseDirectory/avatars/ - avatars will be stored here.
* /temporaryDirectory/ - temporary files will be stored here.
*/
@interface OCTDefaultFileStorage : NSObject <OCTFileStorageProtocol>
/**
* Creates default file storage. Will use "save.tox" as default save file name.
*
* @param baseDirectory Base directory to use. It will have "files", "avatars" subdirectories.
* @param temporaryDirectory All temporary files will be stored here. You can pass NSTemporaryDirectory() here.
*/
- (instancetype)initWithBaseDirectory:(NSString *)baseDirectory temporaryDirectory:(NSString *)temporaryDirectory;
/**
* Creates default file storage.
*
* @param saveFileName Name of file to store tox save data. ".tox" extension will be appended to the name.
* @param baseDirectory Base directory to use. It will have "files", "avatars" subdirectories.
* @param temporaryDirectory All temporary files will be stored here. You can pass NSTemporaryDirectory() here.
*/
- (instancetype)initWithToxSaveFileName:(NSString *)saveFileName
baseDirectory:(NSString *)baseDirectory
temporaryDirectory:(NSString *)temporaryDirectory;
@end

View File

@ -0,0 +1,66 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol OCTFileStorageProtocol <NSObject>
@required
/**
* Returns path where tox save data will be stored. Save file should have ".tox" extension.
* See Tox STS for more information: https://github.com/Tox/Tox-STS
*
* @return Full path to the file for loading/saving tox data.
*
* @warning Path should be file path. The file can be rewritten at any time while OCTManager is alive.
*/
@property (readonly) NSString *pathForToxSaveFile;
/**
* Returns file path for database to be stored in. Must be a file path, not directory.
* In database will be stored chats, messages and related stuff.
*
* @return Full path to the file for the database.
*
* @warning Path should be file path. The file can be rewritten at any time while OCTManager is alive.
*/
@property (readonly) NSString *pathForDatabase;
/**
* Returns file path for database encryption key to be stored in. Must be a file path, not a directory.
*
* @return Full path to the file to store database encryption key.
*
* @warning Path should be file path. The file can be rewritten at any time while OCTManager is alive.
*/
@property (readonly) NSString *pathForDatabaseEncryptionKey;
/**
* Returns path where all downloaded files will be stored.
*
* @return Full path to the directory with downloaded files.
*/
@property (readonly) NSString *pathForDownloadedFilesDirectory;
/**
* Returns path where all uploaded files will be stored.
*
* @return Full path to the directory with uploaded files.
*/
@property (readonly) NSString *pathForUploadedFilesDirectory;
/**
* Returns path where temporary files will be stored. This directory can be cleaned on relaunch of app.
* You can use NSTemporaryDirectory() here.
*
* @return Full path to the directory with temporary files.
*/
@property (readonly) NSString *pathForTemporaryFilesDirectory;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,60 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
#import "OCTFileStorageProtocol.h"
#import "OCTToxOptions.h"
/**
* Configuration for OCTManager.
*/
@interface OCTManagerConfiguration : NSObject <NSCopying>
/**
* File storage to use.
*
* Default values: OCTDefaultFileStorage will be used with following parameters:
* - tox save file is stored at "{app document directory}/me.dvor.objcTox/save.tox"
* - database file is stored at "{app document directory}/me.dvor.objcTox/database"
* - database encryption key file is stored at "{app document directory}/me.dvor.objcTox/database.encryptionkey"
* - downloaded files are stored at "{app document directory}/me.dvor.objcTox/downloads"
* - uploaded files are stored at "{app document directory}/me.dvor.objcTox/uploads"
* - avatars are stored at "{app document directory}/me.dvor.objcTox/avatars"
* - temporary files are stored at NSTemporaryDirectory()
*/
@property (strong, nonatomic, nonnull) id<OCTFileStorageProtocol> fileStorage;
/**
* Options for tox to use.
*/
@property (strong, nonatomic, nonnull) OCTToxOptions *options;
/**
* If this parameter is set, tox save file will be copied from given path.
* You can set this property to import tox save from some other location.
*
* Default value: nil.
*/
@property (strong, nonatomic, nullable) NSString *importToxSaveFromPath;
/**
* When faux offline messaging is enabled, it is allowed to send message to
* offline friends. In that case message would be stored in database and resend
* when friend comes online.
*
* Default value: YES.
*/
@property (assign, nonatomic) BOOL useFauxOfflineMessaging;
/**
* This is default configuration for manager.
* Each property of OCTManagerConfiguration has "Default value" field. This method returns configuration
* with those default values set.
*
* @return Default configuration for OCTManager.
*/
+ (nonnull instancetype)defaultConfiguration;
@end

View File

@ -0,0 +1,95 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
#import "OCTToxConstants.h"
#import "OCTManagerConstants.h"
NS_ASSUME_NONNULL_BEGIN
@class OCTManagerConfiguration;
@protocol OCTSubmanagerBootstrap;
@protocol OCTSubmanagerCalls;
@protocol OCTSubmanagerChats;
@protocol OCTSubmanagerFiles;
@protocol OCTSubmanagerFriends;
@protocol OCTSubmanagerObjects;
@protocol OCTSubmanagerUser;
@protocol OCTManager <NSObject>
/**
* Submanager responsible for connecting to other nodes.
*/
@property (strong, nonatomic, readonly) id<OCTSubmanagerBootstrap> bootstrap;
/**
* Submanager with all video/calling methods.
*/
@property (strong, nonatomic, readonly) id<OCTSubmanagerCalls> calls;
/**
* Submanager with all chats methods.
*/
@property (strong, nonatomic, readonly) id<OCTSubmanagerChats> chats;
/**
* Submanager with all files methods.
*/
@property (strong, nonatomic, readonly) id<OCTSubmanagerFiles> files;
/**
* Submanager with all friends methods.
*/
@property (strong, nonatomic, readonly) id<OCTSubmanagerFriends> friends;
/**
* Submanager with all objects methods.
*/
@property (strong, nonatomic, readonly) id<OCTSubmanagerObjects> objects;
/**
* Submanager with all user methods.
*/
@property (strong, nonatomic, readonly) id<OCTSubmanagerUser> user;
/**
* Configuration used by OCTManager.
*
* @return Copy of configuration used by manager.
*/
- (OCTManagerConfiguration *)configuration;
/**
* Copies tox save file to temporary directory and return path to it.
*
* @param error NSFileManager error in case if file cannot be copied.
*
* @return Temporary path of current tox save file.
*/
- (nullable NSString *)exportToxSaveFileAndReturnError:(NSError *__nullable *__nullable)error;
/**
* Set password to encrypt tox save file and database.
*
* @param newPassword New password used to encrypt tox save file and database.
* @param oldPassword Old password.
*
* @return YES on success, NO on failure (if old password doesn't match).
*/
- (BOOL)changeEncryptPassword:(nonnull NSString *)newPassword oldPassword:(nonnull NSString *)oldPassword;
/**
* Checks if manager is encrypted with given password.
*
* @param password Password to verify.
*
* @return YES if manager is encrypted with given password, NO otherwise.
*/
- (BOOL)isManagerEncryptedWithPassword:(nonnull NSString *)password;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,326 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import "OCTToxConstants.h"
/**
* Maximum avatar size as defined in
* https://tox.gitbooks.io/tox-client-standard/content/user_identification/avatar.html
*/
static const OCTToxFileSize kOCTManagerMaxAvatarSize = 65536;
typedef NS_ENUM(NSInteger, OCTFetchRequestType) {
OCTFetchRequestTypeFriend,
OCTFetchRequestTypeFriendRequest,
OCTFetchRequestTypeChat,
OCTFetchRequestTypeCall,
OCTFetchRequestTypeMessageAbstract,
};
typedef NS_ENUM(NSInteger, OCTMessageFileType) {
/**
* File is incoming and is waiting confirmation of user to be downloaded.
* Please start loading or cancel it with <<placeholder>> method.
*/
OCTMessageFileTypeWaitingConfirmation,
/**
* File is downloading or uploading.
*/
OCTMessageFileTypeLoading,
/**
* Downloading or uploading of file is paused.
*/
OCTMessageFileTypePaused,
/**
* Downloading or uploading of file was canceled.
*/
OCTMessageFileTypeCanceled,
/**
* File is fully loaded.
* In case of incoming file now it can be shown to user.
*/
OCTMessageFileTypeReady,
};
typedef NS_ENUM(NSInteger, OCTMessageFilePausedBy) {
/**
* File transfer isn't paused.
*/
OCTMessageFilePausedByNone = 0,
/**
* File transfer is paused by user.
*/
OCTMessageFilePausedByUser = 1 << 0,
/**
* File transfer is paused by friend.
*/
OCTMessageFilePausedByFriend = 1 << 1,
};
typedef NS_ENUM(NSInteger, OCTMessageCallEvent) {
/**
* Call was answered.
*/
OCTMessageCallEventAnswered,
/**
* Call was unanswered.
*/
OCTMessageCallEventUnanswered,
};
typedef NS_ENUM(NSInteger, OCTCallStatus) {
/**
* Call is currently ringing.
*/
OCTCallStatusRinging,
/**
* Call is currently dialing a chat.
*/
OCTCallStatusDialing,
/**
* Call is currently active in session.
*/
OCTCallStatusActive,
};
typedef NS_OPTIONS(NSInteger, OCTCallPausedStatus) {
/**
* Call is not paused
*/
OCTCallPausedStatusNone = 0,
/**
* Call is paused by the user
*/
OCTCallPausedStatusByUser = 1 << 0,
/**
* Call is paused by friend
*/
OCTCallPausedStatusByFriend = 1 << 1,
};
extern NSString *const kOCTManagerErrorDomain;
typedef NS_ENUM(NSInteger, OCTManagerInitError) {
/**
* Cannot create symmetric key from given passphrase.
*/
OCTManagerInitErrorPassphraseFailed,
/** ---------------------------------------- */
/**
* Cannot copy tox save at `importToxSaveFromPath` path.
*/
OCTManagerInitErrorCannotImportToxSave,
/** ---------------------------------------- */
/**
* Cannot create encryption key.
*/
OCTManagerInitErrorDatabaseKeyCannotCreateKey,
/**
* Cannot read encryption key.
*/
OCTManagerInitErrorDatabaseKeyCannotReadKey,
/**
* Old unencrypted database was found and migration attempt was made. However migration failed for some reason.
*
* You can check NSLocalizedDescriptionKey and NSLocalizedFailureReasonErrorKey for more info.
*/
OCTManagerInitErrorDatabaseKeyMigrationToEncryptedFailed,
/**
* Cannot decrypt database key file.
* Some input data was empty.
*/
OCTManagerInitErrorDatabaseKeyDecryptNull,
/**
* Cannot decrypt database key file.
* The input data is missing the magic number (i.e. wasn't created by this module, or is corrupted).
*/
OCTManagerInitErrorDatabaseKeyDecryptBadFormat,
/**
* Cannot decrypt database key file.
* The encrypted byte array could not be decrypted. Either the data was corrupt or the password/key was incorrect.
*/
OCTManagerInitErrorDatabaseKeyDecryptFailed,
/** ---------------------------------------- */
/**
* Cannot decrypt tox save file.
* Some input data was empty.
*/
OCTManagerInitErrorToxFileDecryptNull,
/**
* Cannot decrypt tox save file.
* The input data is missing the magic number (i.e. wasn't created by this module, or is corrupted).
*/
OCTManagerInitErrorToxFileDecryptBadFormat,
/**
* Cannot decrypt tox save file.
* The encrypted byte array could not be decrypted. Either the data was corrupt or the password/key was incorrect.
*/
OCTManagerInitErrorToxFileDecryptFailed,
/** ---------------------------------------- */
/**
* Cannot create tox.
* Unknown error occurred.
*/
OCTManagerInitErrorCreateToxUnknown,
/**
* Cannot create tox.
* Was unable to allocate enough memory to store the internal structures for the Tox object.
*/
OCTManagerInitErrorCreateToxMemoryError,
/**
* Cannot create tox.
* Was unable to bind to a port. This may mean that all ports have already been bound,
* e.g. by other Tox instances, or it may mean a permission error.
*/
OCTManagerInitErrorCreateToxPortAlloc,
/**
* Cannot create tox.
* proxyType was invalid.
*/
OCTManagerInitErrorCreateToxProxyBadType,
/**
* Cannot create tox.
* proxyAddress had an invalid format or was nil (while proxyType was set).
*/
OCTManagerInitErrorCreateToxProxyBadHost,
/**
* Cannot create tox.
* proxyPort was invalid.
*/
OCTManagerInitErrorCreateToxProxyBadPort,
/**
* Cannot create tox.
* The proxy host passed could not be resolved.
*/
OCTManagerInitErrorCreateToxProxyNotFound,
/**
* Cannot create tox.
* The saved data to be loaded contained an encrypted save.
*/
OCTManagerInitErrorCreateToxEncrypted,
/**
* Cannot create tox.
* The data format was invalid. This can happen when loading data that was
* saved by an older version of Tox, or when the data has been corrupted.
* When loading from badly formatted data, some data may have been loaded,
* and the rest is discarded. Passing an invalid length parameter also
* causes this error.
*/
OCTManagerInitErrorCreateToxBadFormat,
};
typedef NS_ENUM(NSInteger, OCTSetUserAvatarError) {
/**
* User avatar size is too big. It should be <= kOCTManagerMaxAvatarSize.
*/
OCTSetUserAvatarErrorTooBig,
};
typedef NS_ENUM(NSInteger, OCTSendFileError) {
/**
* Internal error occured while sending file.
* Check logs for more info.
*/
OCTSendFileErrorInternalError,
/**
* Cannot read file.
*/
OCTSendFileErrorCannotReadFile,
/**
* Cannot save send file to uploads folder.
*/
OCTSendFileErrorCannotSaveFileToUploads,
/**
* Friend to send file to was not found.
*/
OCTSendFileErrorFriendNotFound,
/**
* Friend is not connected at the moment.
*/
OCTSendFileErrorFriendNotConnected,
/**
* Filename length exceeded kOCTToxMaxFileNameLength bytes.
*/
OCTSendFileErrorNameTooLong,
/**
* Too many ongoing transfers. The maximum number of concurrent file transfers
* is 256 per friend per direction (sending and receiving).
*/
OCTSendFileErrorTooMany,
};
typedef NS_ENUM(NSInteger, OCTAcceptFileError) {
/**
* Internal error occured while sending file.
* Check logs for more info.
*/
OCTAcceptFileErrorInternalError,
/**
* File is not available for writing.
*/
OCTAcceptFileErrorCannotWriteToFile,
/**
* Friend to send file to was not found.
*/
OCTAcceptFileErrorFriendNotFound,
/**
* Friend is not connected at the moment.
*/
OCTAcceptFileErrorFriendNotConnected,
/**
* Wrong message specified (with no friend, no file or not waiting for confirmation).
*/
OCTAcceptFileErrorWrongMessage,
};
typedef NS_ENUM(NSInteger, OCTFileTransferError) {
/**
* Wrong message specified (with no file).
*/
OCTFileTransferErrorWrongMessage,
};

View File

@ -0,0 +1,35 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@class OCTManagerConfiguration;
@protocol OCTManager;
@interface OCTManagerFactory : NSObject
/**
* Create manager with configuration. There is no way to change configuration after init method. If you'd like to
* change it you have to recreate OCTManager.
*
* @param configuration Configuration to be used.
* @param encryptPassword Password used to encrypt/decrypt tox save file and database.
* Tox file will be encrypted automatically if it wasn't encrypted before.
* @param successBlock Block called on success with initialized OCTManager. Will be called on main thread.
* @param failureBlock Block called on failure. Will be called on main thread.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTManagerInitError for all error codes.
*
* @warning This method should be called on main thread.
*/
+ (void)managerWithConfiguration:(OCTManagerConfiguration *)configuration
encryptPassword:(NSString *)encryptPassword
successBlock:(nullable void (^)(id<OCTManager> manager))successBlock
failureBlock:(nullable void (^)(NSError *error))failureBlock;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,84 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
#import "OCTChat.h"
#import "OCTFriend.h"
#import "OCTManagerConstants.h"
/**
* Please note that all properties of this object are readonly.
* All management of calls are handeled through OCTCallSubmanagerCalls.
*/
@interface OCTCall : OCTObject
/**
* OCTChat related session with the call.
**/
@property (nonnull) OCTChat *chat;
/**
* Call status
**/
@property OCTCallStatus status;
/**
* This property contains paused status for Active call.
*/
@property OCTCallPausedStatus pausedStatus;
/**
* The friend who started the call.
* Nil if the you started the call yourself.
**/
@property (nullable) OCTFriend *caller;
/**
* Video device is active for this call
*/
@property BOOL videoIsEnabled;
/**
* Friend is sending audio.
*/
@property BOOL friendSendingAudio;
/**
* Friend is sending video.
*/
@property BOOL friendSendingVideo;
/**
* Friend is accepting audio.
*/
@property BOOL friendAcceptingAudio;
/**
* Friend is accepting video.
*/
@property BOOL friendAcceptingVideo;
/**
* Call duration
**/
@property NSTimeInterval callDuration;
/**
* The on hold start interval when call was put on hold.
*/
@property NSTimeInterval onHoldStartInterval;
/**
* The date when the call was put on hold.
*/
- (nullable NSDate *)onHoldDate;
/**
* Indicates if call is outgoing or incoming.
* In case if it is incoming you can check `caller` property for friend.
**/
- (BOOL)isOutgoing;
@end

View File

@ -0,0 +1,74 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import "OCTObject.h"
#import "OCTFriend.h"
@class OCTMessageAbstract;
/**
* Please note that all properties of this object are readonly.
* You can change some of them only with appropriate method in OCTSubmanagerObjects.
*/
@interface OCTChat : OCTObject
/**
* Array with OCTFriends that participate in this chat.
*/
@property (nonnull) RLMArray<OCTFriend> *friends;
/**
* The latest message that was send or received.
*/
@property (nullable) OCTMessageAbstract *lastMessage;
/**
* This property can be used for storing entered text that wasn't send yet.
*
* To change please use OCTSubmanagerObjects method.
*
* May be empty.
*/
@property (nullable) NSString *enteredText;
/**
* This property stores last date interval when chat was read.
* `hasUnreadMessages` method use lastReadDateInterval to determine if there are unread messages.
*
* To change please use OCTSubmanagerObjects method.
*/
@property NSTimeInterval lastReadDateInterval;
/**
* Date interval of lastMessage or chat creationDate if there is no last message.
*
* This property is workaround to support sorting. Should be replaced with keypath
* lastMessage.dateInterval sorting in future.
* See https://github.com/realm/realm-cocoa/issues/1277
*/
@property NSTimeInterval lastActivityDateInterval;
/**
* The date when chat was read last time.
*/
- (nullable NSDate *)lastReadDate;
/**
* Returns date of lastMessage or chat creationDate if there is no last message.
*/
- (nullable NSDate *)lastActivityDate;
/**
* If there are unread messages in chat YES is returned. All messages that have date later than lastReadDateInterval
* are considered as unread.
*
* Please note that you have to set lastReadDateInterval to make this method work.
*
* @return YES if there are unread messages, NO otherwise.
*/
- (BOOL)hasUnreadMessages;
@end
RLM_ARRAY_TYPE(OCTChat)

View File

@ -0,0 +1,110 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import "OCTObject.h"
#import "OCTToxConstants.h"
/**
* Class that represents friend (or just simply contact).
*
* Please note that all properties of this object are readonly.
* You can change some of them only with appropriate method in OCTSubmanagerObjects.
*/
@interface OCTFriend : OCTObject
/**
* Friend number that is unique for Tox.
* In case if friend will be deleted, old id may be reused on new friend creation.
*/
@property OCTToxFriendNumber friendNumber;
/**
* Nickname of friend.
*
* When friend is created it is set to the publicKey.
* It is set to name when obtaining name for the first time.
* After that name is unchanged (unless it is changed explicitly).
*
* To change please use OCTSubmanagerObjects method.
*/
@property (nonnull) NSString *nickname;
/**
* Public key of a friend, is kOCTToxPublicKeyLength length.
* Is constant, cannot be changed.
*/
@property (nonnull) NSString *publicKey;
/**
* Name of a friend.
*
* May be empty.
*/
@property (nullable) NSString *name;
/**
* Status message of a friend.
*
* May be empty.
*/
@property (nullable) NSString *statusMessage;
/**
* Status message of a friend.
*/
@property OCTToxUserStatus status;
/**
* Property specifies if friend is connected. For type of connection you can check
* connectionStatus property.
*/
@property BOOL isConnected;
/**
* Connection status message of a friend.
*/
@property OCTToxConnectionStatus connectionStatus;
/**
* The date interval when friend was last seen online.
* Contains actual information in case if friend has connectionStatus offline.
*/
@property NSTimeInterval lastSeenOnlineInterval;
/**
* Whether friend is typing now in current chat.
*/
@property BOOL isTyping;
/**
* Data representation of friend's avatar.
*/
@property (nullable) NSData *avatarData;
/**
* The date when friend was last seen online.
* Contains actual information in case if friend has connectionStatus offline.
*/
- (nullable NSDate *)lastSeenOnline;
/**
* Push Token of a friend.
*
* May be empty.
*/
@property (nullable) NSString *pushToken;
/**
* Indicate if a friend has msgV3 Capability.
*/
@property BOOL msgv3Capability;
/**
* Friend's capabilities. A 64 bit unsigned integer.
*/
@property (nonnull) NSString *capabilities2;
@end
RLM_ARRAY_TYPE(OCTFriend)

View File

@ -0,0 +1,35 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import "OCTObject.h"
/**
* Please note that all properties of this object are readonly.
* You can change some of them only with appropriate method in OCTSubmanagerObjects.
*/
@interface OCTFriendRequest : OCTObject
/**
* Public key of a friend.
*/
@property (nonnull) NSString *publicKey;
/**
* Message that friend did send with friend request.
*/
@property (nullable) NSString *message;
/**
* Date interval when friend request was received (since 1970).
*/
@property NSTimeInterval dateInterval;
/**
* Date when friend request was received.
*/
- (nonnull NSDate *)date;
@end
RLM_ARRAY_TYPE(OCTFriendRequest)

View File

@ -0,0 +1,67 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import "OCTObject.h"
@class OCTFriend;
@class OCTChat;
@class OCTMessageText;
@class OCTMessageFile;
@class OCTMessageCall;
/**
* An abstract message that represents one chunk of chat history.
*
* Please note that all properties of this object are readonly.
* You can change some of them only with appropriate method in OCTSubmanagerObjects.
*/
@interface OCTMessageAbstract : OCTObject
/**
* The date interval when message was send/received.
*/
@property NSTimeInterval dateInterval;
/**
* Unixtimestamp when messageV3 was sent or 0.
*/
@property NSTimeInterval tssent;
/**
* Unixtimestamp when messageV3 was received or 0.
*/
@property NSTimeInterval tsrcvd;
/**
* Unique identifier of friend that have send message.
* If the message if outgoing senderUniqueIdentifier is nil.
*/
@property (nullable) NSString *senderUniqueIdentifier;
/**
* The chat message message belongs to.
*/
@property (nonnull) NSString *chatUniqueIdentifier;
/**
* Message has one of the following properties.
*/
@property (nullable) OCTMessageText *messageText;
@property (nullable) OCTMessageFile *messageFile;
@property (nullable) OCTMessageCall *messageCall;
/**
* The date when message was send/received.
*/
- (nonnull NSDate *)date;
/**
* Indicates if message is outgoing or incoming.
* In case if it is incoming you can check `sender` property for message sender.
*/
- (BOOL)isOutgoing;
@end
RLM_ARRAY_TYPE(OCTMessageAbstract)

View File

@ -0,0 +1,20 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import "OCTObject.h"
#import "OCTManagerConstants.h"
@interface OCTMessageCall : OCTObject
/**
* The length of the call in seconds.
**/
@property NSTimeInterval callDuration;
/**
* The type of message call.
**/
@property OCTMessageCallEvent callEvent;
@end

View File

@ -0,0 +1,61 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import "OCTObject.h"
#import "OCTToxConstants.h"
#import "OCTManagerConstants.h"
/**
* Message that contains file, that has been send/received. Represents pending, canceled and loaded files.
*
* Please note that all properties of this object are readonly.
* You can change some of them only with appropriate method in OCTSubmanagerObjects.
*/
@interface OCTMessageFile : OCTObject
/**
* The current state of file.
*/
@property OCTMessageFileType fileType;
/**
* In case if fileType is equal to OCTMessageFileTypePaused this property will contain information
* by whom file transfer was paused.
*/
@property OCTMessageFilePausedBy pausedBy;
/**
* Size of file in bytes.
*/
@property OCTToxFileSize fileSize;
/**
* Name of the file as specified by sender. Note that actual fileName in path
* may differ from this fileName.
*/
@property (nullable) NSString *fileName;
/**
* Uniform Type Identifier of file.
*/
@property (nullable) NSString *fileUTI;
/**
* Path of file on disk. If you need fileName to show to user please use
* `fileName` property. filePath has it's own random fileName.
*
* In case of incoming file filePath will have value only if fileType is OCTMessageFileTypeReady
*/
- (nullable NSString *)filePath;
// Properties and methods below are for internal use.
// Do not use them or rely on them. They may change in any moment.
@property int internalFileNumber;
@property (nullable) NSString *internalFilePath;
- (void)internalSetFilePath:(nullable NSString *)path;
@end
RLM_ARRAY_TYPE(OCTMessageFile)

View File

@ -0,0 +1,49 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import "OCTObject.h"
#import "OCTToxConstants.h"
@class OCTToxConstants;
/**
* Simple text message.
*
* Please note that all properties of this object are readonly.
* You can change some of them only with appropriate method in OCTSubmanagerObjects.
*/
@interface OCTMessageText : OCTObject
/**
* The text of the message.
*/
@property (nullable) NSString *text;
/**
* Indicate if message is delivered. Actual only for outgoing messages.
*/
@property BOOL isDelivered;
/**
* Type of the message.
*/
@property OCTToxMessageType type;
@property OCTToxMessageId messageId;
/**
* msgV3 Hash as uppercase Hexstring.
*
* May be empty if message is not v3.
*/
@property (nullable) NSString *msgv3HashHex;
/**
* Indicate if message has triggered a push notification.
*/
@property BOOL sentPush;
@end
RLM_ARRAY_TYPE(OCTMessageText)

View File

@ -0,0 +1,33 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Realm/Realm.h>
/**
* Please note that all properties of this object are readonly.
* You can change some of them only with appropriate method in OCTSubmanagerObjects.
*/
@interface OCTObject : RLMObject
/**
* The unique identifier of object.
*/
@property NSString *uniqueIdentifier;
/**
* Returns a string that represents the contents of the receiving class.
*/
- (NSString *)description;
/**
* Returns a Boolean value that indicates whether the receiver and a given object are equal.
*/
- (BOOL)isEqual:(id)object;
/**
* Returns an integer that can be used as a table address in a hash table structure.
*/
- (NSUInteger)hash;
@end

View File

@ -0,0 +1,17 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import "TargetConditionals.h"
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
typedef UIView OCTView;
#else
#import <AppKit/AppKit.h>
typedef NSView OCTView;
#endif

View File

@ -0,0 +1,57 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
#import "OCTToxConstants.h"
NS_ASSUME_NONNULL_BEGIN
@protocol OCTSubmanagerBootstrap <NSObject>
/**
* Add node to bootstrap with.
*
* This will NOT start bootstrapping. To start actual bootstrapping set all desired nodes
* and call `bootstrap` method.
*
* @param ipv4Host IPv4 hostname or an IP address of the node.
* @param ipv6Host IPv4 hostname or an IP address of the node.
* @param udpPort The port on the host on which the bootstrap Tox instance is listening.
* @param tcpPorts NSNumbers with OCTToxPorts on which the TCP relay is listening.
* @param publicKey Public key of the node (of kOCTToxPublicKeyLength length).
*/
- (void)addNodeWithIpv4Host:(nullable NSString *)ipv4Host
ipv6Host:(nullable NSString *)ipv6Host
udpPort:(OCTToxPort)udpPort
tcpPorts:(NSArray<NSNumber *> *)tcpPorts
publicKey:(NSString *)publicKey;
/**
* Add nodes from https://nodes.tox.chat/. objcTox is trying to keep this list up to date.
* You can check all nodes and update date in nodes.json file.
*
* This will NOT start bootstrapping. To start actual bootstrapping set all desired nodes
* and call `bootstrap` method.
*/
- (void)addPredefinedNodes;
/**
* You HAVE TO call this method on startup to connect to Tox network.
*
* Before calling this method add nodes to bootstrap with.
*
* After calling this method
* - if manager wasn't connected before it will start bootstrapping immediately.
* - if it was connected before, it will wait 10 to connect to existing nodes
* before starting actually bootstrapping.
*
* When bootstrapping, submanager will bootstrap 4 random nodes from a list every 5 seconds
* until is will be connected.
*/
- (void)bootstrap;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,145 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
#import "OCTView.h"
#import "OCTChat.h"
#import "OCTToxAVConstants.h"
#import "OCTSubmanagerCallsDelegate.h"
@class OCTToxAV;
@class OCTCall;
@protocol OCTSubmanagerCalls <NSObject>
@property (nullable, weak, nonatomic) id<OCTSubmanagerCallDelegate> delegate;
/**
* Set the property to YES to enable the microphone, otherwise NO.
* Default value is YES at the start of every call;
**/
@property (nonatomic, assign) BOOL enableMicrophone;
/**
* This must be called once after initialization.
* @param error Pointer to an error when setting up.
* @return YES on success, otherwise NO.
*/
- (BOOL)setupAndReturnError:(NSError *__nullable *__nullable)error;
/**
* This class is responsible for telling the end-user what calls we have available.
* We can also initialize a call session from here.
* @param chat The chat for which we would like to initiate a call.
* @param enableAudio YES for Audio, otherwise NO.
* @param enableVideo YES for Video, otherwise NO.
* @param error Pointer to an error when attempting to answer a call
* @return OCTCall session
*/
- (nullable OCTCall *)callToChat:(nonnull OCTChat *)chat
enableAudio:(BOOL)enableAudio
enableVideo:(BOOL)enableVideo
error:(NSError *__nullable *__nullable)error;
/**
* Enable video calling for an active call.
* Use this when you started a call without video in the first place.
* @param enable YES to enable video, NO to stop video sending.
* @param call Call to enable video for.
* @param error Pointer to an error object.
* @return YES on success, otherwise NO.
*/
- (BOOL)enableVideoSending:(BOOL)enable
forCall:(nonnull OCTCall *)call
error:(NSError *__nullable *__nullable)error;
/**
* Answer a call
* @param call The call session we would like to answer
* @param enableAudio YES for Audio, otherwise NO.
* @param enableVideo YES for Video, otherwise NO.
* @param error Pointer to an error when attempting to answer a call
* @return YES if we were able to succesfully answer the call, otherwise NO.
*/
- (BOOL)answerCall:(nonnull OCTCall *)call
enableAudio:(BOOL)enableAudio
enableVideo:(BOOL)enableVideo
error:(NSError *__nullable *__nullable)error;
/**
* Send call control to call.
* @param control The control to send to call.
* @param call The appopriate call to send to.
* @param error Pointer to error object if there's an issue muting the call.
* @return YES if succesful, NO otherwise.
*/
- (BOOL)sendCallControl:(OCTToxAVCallControl)control
toCall:(nonnull OCTCall *)call
error:(NSError *__nullable *__nullable)error;
/**
* The OCTView that will have the video feed.
*/
- (nullable OCTView *)videoFeed;
/**
* The preview video of the user.
* You must be in a video call for this to show. Otherwise the layer will
* just be black.
* @param completionBlock Block responsible for using the layer. This
* must not be nil.
*/
- (void)getVideoCallPreview:(void (^__nonnull)( CALayer *__nullable layer))completionBlock;
/**
* Set the Audio bit rate.
* @param bitrate The bitrate to change to.
* @param call The Call to set the bitrate for.
* @param error Pointer to error object if there's an issue setting the bitrate.
*/
- (BOOL)setAudioBitrate:(int)bitrate forCall:(nonnull OCTCall *)call error:(NSError *__nullable *__nullable)error;
#if ! TARGET_OS_IPHONE
/**
* Set input source and output targets for A/V.
*
* On iPhone OS, you must pass one of the OCT[Input|Output]Device... constants
* as the deviceUniqueID.
* On OS X, you can get valid deviceUniqueID values from:
* - AVFoundation: video and audio (inputs only) (AVCaptureDevice uniqueID)
* - Core Audio: audio inputs and outputs (kAudioDevicePropertyDeviceUID).
* @param deviceUniqueID The device ID to use. May be nil, in which case
* a default device will be used
*/
- (BOOL)setAudioInputDevice:(nullable NSString *)deviceUniqueID
error:(NSError *__nullable *__nullable)error;
- (BOOL)setAudioOutputDevice:(nullable NSString *)deviceUniqueID
error:(NSError *__nullable *__nullable)error;
- (BOOL)setVideoInputDevice:(nullable NSString *)deviceUniqueID
error:(NSError *__nullable *__nullable)error;
#else
/**
* Send the audio to the speaker
* @param speaker YES to send audio to speaker, NO to reset to default.
* @param error Pointer to error object.
* @return YES if successful, otherwise NO.
*/
- (BOOL)routeAudioToSpeaker:(BOOL)speaker
error:(NSError *__nullable *__nullable)error;
/**
* Use a different camera for input.
* @param front YES to use the front camera, NO to use the
* rear camera. Front camera is used by default.
* @error Pointer to error object.
* @return YES on success, otherwise NO.
*/
- (BOOL)switchToCameraFront:(BOOL)front error:(NSError *__nullable *__nullable)error;
#endif
@end

View File

@ -0,0 +1,15 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
@class OCTCall;
@protocol OCTSubmanagerCalls;
@protocol OCTSubmanagerCallDelegate <NSObject>
/**
* This gets called when we receive a call.
**/
- (void)callSubmanager:(id<OCTSubmanagerCalls>)callSubmanager receiveCall:(OCTCall *)call audioEnabled:(BOOL)audioEnabled videoEnabled:(BOOL)videoEnabled;
@end

View File

@ -0,0 +1,84 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
#import "OCTToxConstants.h"
@class OCTChat;
@class OCTFriend;
@class OCTMessageAbstract;
@protocol OCTSubmanagerChats <NSObject>
/**
* Searches for a chat with specific friend. If chat is not found creates one and returns it.
*
* @param friend Friend to get/create chat with.
*
* @return Chat with specific friend.
*/
- (OCTChat *)getOrCreateChatWithFriend:(OCTFriend *)friend;
/**
* Removes given messages.
*
* @param messages Array with messages to remove.
*
* @warning Destructive operation! There is no way to restore messages after removal.
*/
- (void)removeMessages:(NSArray<OCTMessageAbstract *> *)messages;
/**
* Removes all messages in chat and chat itself.
*
* @param chat Chat to remove in.
* @param removeChat Whether remove chat or not
*
* @warning Destructive operation! There is no way to restore chat or messages after removal.
*/
- (void)removeAllMessagesInChat:(OCTChat *)chat removeChat:(BOOL)removeChat;
/**
* Send text message to specific chat
*
* @param chat Chat send message to.
* @param text Text to send.
* @param type Type of message to send.
* @param successBlock Block called when message was successfully send.
* @param message Message that was send.
* @param failureBlock Block called when submanager failed to send message.
* @param error Error that occurred. See OCTToxErrorFriendSendMessage for all error codes.
*/
- (void)sendMessageToChat:(OCTChat *)chat
text:(NSString *)text
type:(OCTToxMessageType)type
successBlock:(void (^)(OCTMessageAbstract *message))userSuccessBlock
failureBlock:(void (^)(NSError *error))userFailureBlock;
/**
* Trigger PUSH Message to yourself
*/
- (void)sendOwnPush;
/**
* Trigger PUSH Message to Friend if the Text Message was sent in a period where the friend
* was online to us, but the friend was in fact already offline.
* so no message was sent AND not PUSH was triggered.
*/
- (void)sendMessagePushToChat:(OCTChat *)chat;
/**
* Set our typing status for a chat. You are responsible for turning it on or off.
*
* @param isTyping Status showing whether user is typing or not.
* @param chat Chat to set typing status.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTToxErrorSetTyping for all error codes.
*
* @return YES on success, NO on failure.
*/
- (BOOL)setIsTyping:(BOOL)isTyping inChat:(OCTChat *)chat error:(NSError **)error;
@end

View File

@ -0,0 +1,124 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
@class OCTMessageAbstract;
@class OCTChat;
@protocol OCTSubmanagerFilesProgressSubscriber;
@protocol OCTSubmanagerFiles <NSObject>
/**
* Send given data to particular chat. After sending OCTMessageAbstract with messageFile will be added to this chat.
* You can monitor progress using this message.
*
* File will be saved in uploaded files directory (see OCTFileStorageProtocol).
*
* @param data Data to send.
* @param fileName Name of the file.
* @param chat Chat to send data to.
* @param failureBlock Block that will be called in case of upload failure.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTSendFileError for all error codes.
*/
- (void)sendData:(nonnull NSData *)data
withFileName:(nonnull NSString *)fileName
toChat:(nonnull OCTChat *)chat
failureBlock:(nullable void (^)(NSError *__nonnull error))failureBlock;
/**
* Send given file to particular chat. After sending OCTMessageAbstract with messageFile will be added to this chat.
* You can monitor progress using this message.
*
* @param filePath Path of file to upload.
* @param moveToUploads If YES file will be moved to uploads directory.
* @param chat Chat to send file to.
* @param failureBlock Block that will be called in case of upload failure.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTSendFileError for all error codes.
*/
- (void)sendFileAtPath:(nonnull NSString *)filePath
moveToUploads:(BOOL)moveToUploads
toChat:(nonnull OCTChat *)chat
failureBlock:(nullable void (^)(NSError *__nonnull error))failureBlock;
/**
* Accept file transfer.
*
* @param message Message with file transfer. Message should be incoming and have OCTMessageFile with
* fileType OCTMessageFileTypeWaitingConfirmation. Otherwise nothing will happen.
* @param failureBlock Block that will be called in case of download failure.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTAcceptFileError for all error codes.
*/
- (void)acceptFileTransfer:(nonnull OCTMessageAbstract *)message
failureBlock:(nullable void (^)(NSError *__nonnull error))failureBlock;
/**
* Cancel file transfer. File transfer can be waiting confirmation or active.
*
* @param message Message with file transfer. Message should have OCTMessageFile. Otherwise nothing will happen.
*/
- (BOOL)cancelFileTransfer:(nonnull OCTMessageAbstract *)message error:(NSError *__nullable *__nullable)error;
/**
* Retry to send file using same OCTMessageAbstract. This message should have Canceled type, otherwise retry will failure.
*
* @param message File transfer message to send.
* @param failureBlock Block that will be called in case of upload failure.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTSendFileError for all error codes.
*/
- (void)retrySendingFile:(nonnull OCTMessageAbstract *)message
failureBlock:(nullable void (^)(NSError *__nonnull error))failureBlock;
/**
* Pause or resume file transfer.
* - For pausing transfer should be in Loading state or paused by friend, otherwise nothing will happen.
* - For resuming transfer should be in Paused state and paused by user, otherwise nothing will happen.
*
* @param pause Flag notifying of pausing/resuming file transfer.
* @param message Message with file transfer. Message should have OCTMessageFile.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTFileTransferError for all error codes.
*
* @return YES on success, NO on failure.
*/
- (BOOL)pauseFileTransfer:(BOOL)pause
message:(nonnull OCTMessageAbstract *)message
error:(NSError *__nullable *__nullable)error;
/**
* Add progress subscriber for given file transfer. Subscriber will receive progress immediately after subscribing.
* File transfer should be in Loading or Paused state, otherwise subscriber won't be added.
*
* @param subscriber Object listening to progress protocol.
* @param message Message with file transfer. Message should have OCTMessageFile. Otherwise nothing will happen.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTFileTransferError for all error codes.
*
* @return YES on success, NO on failure.
*
* @warning Subscriber will be stored as weak reference, so it is safe to dealloc it without unsubscribing.
*/
- (BOOL)addProgressSubscriber:(nonnull id<OCTSubmanagerFilesProgressSubscriber>)subscriber
forFileTransfer:(nonnull OCTMessageAbstract *)message
error:(NSError *__nullable *__nullable)error;
/**
* Remove progress subscriber for given file transfer.
*
* @param subscriber Object listening to progress protocol.
* @param message Message with file transfer. Message should have OCTMessageFile. Otherwise nothing will happen.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTFileTransferError for all error codes.
*
* @return YES on success, NO on failure.
*/
- (BOOL)removeProgressSubscriber:(nonnull id<OCTSubmanagerFilesProgressSubscriber>)subscriber
forFileTransfer:(nonnull OCTMessageAbstract *)message
error:(NSError *__nullable *__nullable)error;
@end

View File

@ -0,0 +1,30 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
@class OCTMessageAbstract;
@protocol OCTSubmanagerFilesProgressSubscriber <NSObject>
/**
* Method called on download/upload progress.
*
* @param progress Progress of download/upload. From 0.0 to 1.0.
* @param message File message with progress update.
*/
- (void)submanagerFilesOnProgressUpdate:(float)progress message:(nonnull OCTMessageAbstract *)message;
/**
* Method called on download/upload eta update.
*
* @param eta Estimated time of finish of download/upload.
* @param bytesPerSecond Speed of download/upload.
* @param message File message with progress update.
*/
- (void)submanagerFilesOnEtaUpdate:(CFTimeInterval)eta
bytesPerSecond:(OCTToxFileSize)bytesPerSecond
message:(nonnull OCTMessageAbstract *)message;
@end

View File

@ -0,0 +1,53 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
@class OCTFriendRequest;
@class OCTFriend;
@protocol OCTSubmanagerFriends <NSObject>
/**
* Send friend request to given address. Automatically adds friend with this address to friend list.
*
* @param address Address of a friend. If required.
* @param message Message to send with friend request. Is required.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTToxErrorFriendAdd for all error codes.
*
* @return YES on success, NO on failure.
*/
- (BOOL)sendFriendRequestToAddress:(NSString *)address message:(NSString *)message error:(NSError **)error;
/**
* Approve given friend request. After approving new friend will be added and friendRequest will be removed.
*
* @param friendRequest Friend request to approve.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTToxErrorFriendAdd for all error codes.
*
* @return YES on success, NO on failure.
*/
- (BOOL)approveFriendRequest:(OCTFriendRequest *)friendRequest error:(NSError **)error;
/**
* Remove friend request from list. This cannot be undone.
*
* @param friendRequest Friend request to remove.
*/
- (void)removeFriendRequest:(OCTFriendRequest *)friendRequest;
/**
* Remove friend from list. This cannot be undone.
*
* @param friend Friend to remove.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTToxErrorFriendDelete for all error codes.
*
* @return YES on success, NO on failure.
*/
- (BOOL)removeFriend:(OCTFriend *)friend error:(NSError **)error;
@end

View File

@ -0,0 +1,72 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
#import "OCTManagerConstants.h"
@class OCTObject;
@class OCTFriend;
@class OCTChat;
@class RLMResults;
@protocol OCTSubmanagerObjects <NSObject>
/**
* This property can be used to save any generic data you like.
*
* The default value is nil.
*/
@property (strong, nonatomic) NSData *genericSettingsData;
/**
* Returns fetch request for specified type.
*
* @param type Type of fetch request.
* @param predicate Predicate that represents search query.
*
* @return RLMResults with objects of specified type.
*/
- (RLMResults *)objectsForType:(OCTFetchRequestType)type predicate:(NSPredicate *)predicate;
/**
* Returns object for specified type with uniqueIdentifier.
*
* @param uniqueIdentifier Unique identifier of object.
* @param type Type of object.
*
* @return Object of specified type or nil, if object does not exist.
*/
- (OCTObject *)objectWithUniqueIdentifier:(NSString *)uniqueIdentifier forType:(OCTFetchRequestType)type;
#pragma mark - Friends
/**
* Sets nickname property for friend.
*
* @param friend Friend to change.
* @param nickname New nickname. If nickname is empty or nil, it will be set to friends name.
* If friend don't have name, it will be set to friends publicKey.
*/
- (void)changeFriend:(OCTFriend *)friend nickname:(NSString *)nickname;
#pragma mark - Chats
/**
* Sets enteredText property for chat.
*
* @param chat Chat to change.
* @param enteredText New text.
*/
- (void)changeChat:(OCTChat *)chat enteredText:(NSString *)enteredText;
/**
* Sets lastReadDateInterval property for chat.
*
* @param chat Chat to change.
* @param lastReadDateInterval New interval.
*/
- (void)changeChat:(OCTChat *)chat lastReadDateInterval:(NSTimeInterval)lastReadDateInterval;
@end

View File

@ -0,0 +1,104 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#import <Foundation/Foundation.h>
#import "OCTToxConstants.h"
@protocol OCTSubmanagerUser;
@protocol OCTSubmanagerUserDelegate <NSObject>
- (void)submanagerUser:(nonnull id<OCTSubmanagerUser>)submanager connectionStatusUpdate:(OCTToxConnectionStatus)connectionStatus;
@end
@protocol OCTSubmanagerUser <NSObject>
@property (weak, nonatomic, nullable) id<OCTSubmanagerUserDelegate> delegate;
/**
* Indicates if client is connected to the DHT.
*/
@property (assign, nonatomic, readonly) OCTToxConnectionStatus connectionStatus;
/**
* Client's address.
*
* Address for Tox as a hex string. Address is kOCTToxAddressLength length and has following format:
* [publicKey (32 bytes, 64 characters)][nospam number (4 bytes, 8 characters)][checksum (2 bytes, 4 characters)]
*/
@property (strong, nonatomic, readonly, nonnull) NSString *userAddress;
/**
* Client's Tox Public Key (long term public key) of kOCTToxPublicKeyLength.
*/
@property (strong, nonatomic, readonly, nonnull) NSString *publicKey;
/**
* Client's nospam part of the address. Any 32 bit unsigned integer.
*/
@property (assign, nonatomic) OCTToxNoSpam nospam;
/**
* Client's capabilities. A 64 bit unsigned integer.
*/
@property (nonatomic, readonly) OCTToxCapabilities capabilities;
/**
* Client's user status.
*/
@property (assign, nonatomic) OCTToxUserStatus userStatus;
/**
* Set the nickname for the client.
*
* @param name Name to be set. Minimum length of name is 1 byte.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTToxErrorSetInfoCode for all error codes.
*
* @return YES on success, NO on failure.
*/
- (BOOL)setUserName:(nullable NSString *)name error:(NSError *__nullable *__nullable)error;
/**
* Get client's nickname.
*
* @return Client's nickname or nil in case of error.
*/
- (nullable NSString *)userName;
/**
* Set client's status message.
*
* @param statusMessage Status message to be set.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTToxErrorSetInfoCode for all error codes.
*
* @return YES on success, NO on failure.
*/
- (BOOL)setUserStatusMessage:(nullable NSString *)statusMessage error:(NSError *__nullable *__nullable)error;
/**
* Get client's status message.
*
* @return Client's status message.
*/
- (nullable NSString *)userStatusMessage;
/**
* Set user avatar. Avatar should be <= kOCTManagerMaxAvatarSize.
*
* @param avatar NSData representation of avatar image.
* @param error If an error occurs, this pointer is set to an actual error object containing the error information.
* See OCTSetUserAvatarError for all error codes.
*
* @return YES on success, NO on failure.
*/
- (BOOL)setUserAvatar:(nullable NSData *)avatar error:(NSError *__nullable *__nullable)error;
/**
* Get data representation of user avatar.
*
* @return Data with user avatar if exists.
*/
- (nullable NSData *)userAvatar;
@end

View File

@ -0,0 +1,776 @@
{
"last_scan": 1675968658,
"last_refresh": 1675968601,
"nodes": [
{
"ipv4": "144.217.167.73",
"ipv6": "-",
"port": 33445,
"tcp_ports": [
3389,
33445
],
"public_key": "7E5668E0EE09E19F320AD47902419331FFEE147BB3606769CFBE921A2A2FD34C",
"maintainer": "velusip",
"location": "CA",
"status_udp": true,
"status_tcp": true,
"version": "1000002013",
"motd": "Jera",
"last_ping": 1675968658
},
{
"ipv4": "tox.abilinski.com",
"ipv6": "-",
"port": 33445,
"tcp_ports": [
33445
],
"public_key": "10C00EB250C3233E343E2AEBA07115A5C28920E9C8D29492F6D00B29049EDC7E",
"maintainer": "AnthonyBilinski",
"location": "CA",
"status_udp": true,
"status_tcp": true,
"version": "1000002013",
"motd": "Running https://github.com/toktok/c-toxcore v0.2.13. qTox best Tox! Contact: AC18841E56CCDEE16E93E10E6AB2765BE54277D67F1372921B5B418A6B330D3D3FAFA60B0931",
"last_ping": 1675968658
},
{
"ipv4": "198.199.98.108",
"ipv6": "2604:a880:1:20::32f:1001",
"port": 33445,
"tcp_ports": [
33445,
3389
],
"public_key": "BEF0CFB37AF874BD17B9A8F9FE64C75521DB95A37D33C5BDB00E9CF58659C04F",
"maintainer": "Cody",
"location": "US",
"status_udp": true,
"status_tcp": true,
"version": "1000002015",
"motd": "Cody's Tox node!",
"last_ping": 1675968658
},
{
"ipv4": "tox.kurnevsky.net",
"ipv6": "tox.kurnevsky.net",
"port": 33445,
"tcp_ports": [],
"public_key": "82EF82BA33445A1F91A7DB27189ECFC0C013E06E3DA71F588ED692BED625EC23",
"maintainer": "kurnevsky",
"location": "NL",
"status_udp": true,
"status_tcp": false,
"version": "3000002000",
"motd": "Hi from tox-rs!",
"last_ping": 1675968658
},
{
"ipv4": "205.185.115.131",
"ipv6": "-",
"port": 53,
"tcp_ports": [
53,
443,
33445,
3389
],
"public_key": "3091C6BEB2A993F1C6300C16549FABA67098FF3D62C6D253828B531470B53D68",
"maintainer": "GDR!",
"location": "US",
"status_udp": true,
"status_tcp": true,
"version": "1000002018",
"motd": "https://gdr.name/tuntox/",
"last_ping": 1675968658
},
{
"ipv4": "tox2.abilinski.com",
"ipv6": "tox2.abilinski.com",
"port": 33445,
"tcp_ports": [
33445
],
"public_key": "7A6098B590BDC73F9723FC59F82B3F9085A64D1B213AAF8E610FD351930D052D",
"maintainer": "AnthonyBilinski",
"location": "US",
"status_udp": true,
"status_tcp": true,
"version": "1000002013",
"motd": "Running https://github.com/toktok/c-toxcore v0.2.13. qTox best Tox! Contact: AC18841E56CCDEE16E93E10E6AB2765BE54277D67F1372921B5B418A6B330D3D3FAFA60B0931",
"last_ping": 1675968658
},
{
"ipv4": "46.101.197.175",
"ipv6": "2a03:b0c0:3:d0::ac:5001",
"port": 33445,
"tcp_ports": [
3389,
33445
],
"public_key": "CD133B521159541FB1D326DE9850F5E56A6C724B5B8E5EB5CD8D950408E95707",
"maintainer": "kotelnik",
"location": "DE",
"status_udp": true,
"status_tcp": true,
"version": "1000002018",
"motd": "Power to Ukraine!",
"last_ping": 1675968659
},
{
"ipv4": "tox1.mf-net.eu",
"ipv6": "tox1.mf-net.eu",
"port": 33445,
"tcp_ports": [
3389,
33445
],
"public_key": "B3E5FA80DC8EBD1149AD2AB35ED8B85BD546DEDE261CA593234C619249419506",
"maintainer": "2mf",
"location": "DE",
"status_udp": true,
"status_tcp": true,
"version": "1000002018",
"motd": "tox-bootstrapd",
"last_ping": 1675968660
},
{
"ipv4": "tox2.mf-net.eu",
"ipv6": "tox2.mf-net.eu",
"port": 33445,
"tcp_ports": [
33445,
3389
],
"public_key": "70EA214FDE161E7432530605213F18F7427DC773E276B3E317A07531F548545F",
"maintainer": "2mf",
"location": "DE",
"status_udp": true,
"status_tcp": true,
"version": "1000002018",
"motd": "tox-bootstrapd",
"last_ping": 1675968659
},
{
"ipv4": "195.201.7.101",
"ipv6": "-",
"port": 33445,
"tcp_ports": [
3389,
33445
],
"public_key": "B84E865125B4EC4C368CD047C72BCE447644A2DC31EF75BD2CDA345BFD310107",
"maintainer": "tux1973",
"location": "DE",
"status_udp": true,
"status_tcp": true,
"version": "1000002012",
"motd": "tox-bootstrapd",
"last_ping": 1675968660
},
{
"ipv4": "tox4.plastiras.org",
"ipv6": "-",
"port": 33445,
"tcp_ports": [
443,
3389,
33445
],
"public_key": "836D1DA2BE12FE0E669334E437BE3FB02806F1528C2B2782113E0910C7711409",
"maintainer": "Tha_14",
"location": "MD",
"status_udp": true,
"status_tcp": true,
"version": "1000002018",
"motd": "Add me on Tox: F0AA7C8C55552E8593B2B77AC6FCA598A40D1F5F52A26C2322690A4BF1DFCB0DD8AEDD2822FF",
"last_ping": 1675968659
},
{
"ipv4": "188.225.9.167",
"ipv6": "209:dead:ded:4991:49f3:b6c0:9869:3019",
"port": 33445,
"tcp_ports": [
33445,
3389
],
"public_key": "1911341A83E02503AB1FD6561BD64AF3A9D6C3F12B5FBB656976B2E678644A67",
"maintainer": "Nikat",
"location": "RU",
"status_udp": true,
"status_tcp": true,
"version": "1000002013",
"motd": "First yggdrasil tox bootstrapd!!!\nYou can read about it here: https://yggdrasil-network.github.io/",
"last_ping": 1675968659
},
{
"ipv4": "122.116.39.151",
"ipv6": "2001:b011:8:2f22:1957:7f9d:e31f:96dd",
"port": 33445,
"tcp_ports": [
3389,
33445
],
"public_key": "5716530A10D362867C8E87EE1CD5362A233BAFBBA4CF47FA73B7CAD368BD5E6E",
"maintainer": "miaoski",
"location": "TW",
"status_udp": true,
"status_tcp": true,
"version": "1000002018",
"motd": "tox-bootstrapd",
"last_ping": 1675968659
},
{
"ipv4": "tox3.plastiras.org",
"ipv6": "tox3.plastiras.org",
"port": 33445,
"tcp_ports": [
33445,
3389
],
"public_key": "4B031C96673B6FF123269FF18F2847E1909A8A04642BBECD0189AC8AEEADAF64",
"maintainer": "Tha_14",
"location": "DE",
"status_udp": true,
"status_tcp": true,
"version": "1000002018",
"motd": "Add me on Tox: F0AA7C8C55552E8593B2B77AC6FCA598A40D1F5F52A26C2322690A4BF1DFCB0DD8AEDD2822FF",
"last_ping": 1675968659
},
{
"ipv4": "104.225.141.59",
"ipv6": "-",
"port": 43334,
"tcp_ports": [],
"public_key": "933BA20B2E258B4C0D475B6DECE90C7E827FE83EFA9655414E7841251B19A72C",
"maintainer": "Gabe",
"location": "US",
"status_udp": true,
"status_tcp": false,
"version": "1000002018",
"motd": "True peace is in Jesus Matt 11:28-30 Tox ID: 07D7B9018C5C724A2E9EB34C60782F78B7BDF64D5316946EF49F8E6A20F26B4631FEC281D6A4",
"last_ping": 1675968658
},
{
"ipv4": "139.162.110.188",
"ipv6": "2400:8902::f03c:93ff:fe69:bf77",
"port": 33445,
"tcp_ports": [
443,
3389,
33445
],
"public_key": "F76A11284547163889DDC89A7738CF271797BF5E5E220643E97AD3C7E7903D55",
"maintainer": "ToxTom",
"location": "CA",
"status_udp": true,
"status_tcp": true,
"version": "1000002013",
"motd": "ToxTom",
"last_ping": 1675968659
},
{
"ipv4": "198.98.49.206",
"ipv6": "2605:6400:10:caa:1:be:a:7001",
"port": 33445,
"tcp_ports": [
33445
],
"public_key": "28DB44A3CEEE69146469855DFFE5F54DA567F5D65E03EFB1D38BBAEFF2553255",
"maintainer": "Cüber",
"location": "US",
"status_udp": true,
"status_tcp": true,
"version": "1000002013",
"motd": "Tox",
"last_ping": 1675968660
},
{
"ipv4": "172.105.109.31",
"ipv6": "2600:3c04::f03c:92ff:fe30:5df",
"port": 33445,
"tcp_ports": [
33445
],
"public_key": "D46E97CF995DC1820B92B7D899E152A217D36ABE22730FEA4B6BF1BFC06C617C",
"maintainer": "amr",
"location": "CA",
"status_udp": true,
"status_tcp": true,
"version": "1000002018",
"motd": "FrozenDev Node: tox-bootstrapd Add me on tox: A625D9E9EAAA7B40C399F50BA8B255836EE5A09B6DD0C54CF0E190E24544DC39237D6389FAED",
"last_ping": 1675968660
},
{
"ipv4": "91.146.66.26",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "B5E7DAC610DBDE55F359C7F8690B294C8E4FCEC4385DE9525DBFA5523EAD9D53",
"maintainer": "Toxdaemon",
"location": "EE",
"status_udp": true,
"status_tcp": false,
"version": "1000002013",
"motd": "tox-bootstrapd 91.146.66.26",
"last_ping": 1675968658
},
{
"ipv4": "tox01.ky0uraku.xyz",
"ipv6": "tox01.ky0uraku.xyz",
"port": 33445,
"tcp_ports": [
33445
],
"public_key": "FD04EB03ABC5FC5266A93D37B4D6D6171C9931176DC68736629552D8EF0DE174",
"maintainer": "ky0uraku",
"location": "NL",
"status_udp": true,
"status_tcp": true,
"version": "1000002013",
"motd": "ky0uraku tox01 node",
"last_ping": 1675968660
},
{
"ipv4": "tox02.ky0uraku.xyz",
"ipv6": "tox02.ky0uraku.xyz",
"port": 33445,
"tcp_ports": [
33445
],
"public_key": "D3D6D7C0C7009FC75406B0A49E475996C8C4F8BCE1E6FC5967DE427F8F600527",
"maintainer": "ky0uraku",
"location": "FR",
"status_udp": true,
"status_tcp": true,
"version": "1000002016",
"motd": "ky0uraku tox02 node",
"last_ping": 1675968660
},
{
"ipv4": "tox.plastiras.org",
"ipv6": "tox.plastiras.org",
"port": 33445,
"tcp_ports": [
33445,
443
],
"public_key": "8E8B63299B3D520FB377FE5100E65E3322F7AE5B20A0ACED2981769FC5B43725",
"maintainer": "Tha_14",
"location": "LU",
"status_udp": true,
"status_tcp": true,
"version": "1000002018",
"motd": "Add me on Tox: F0AA7C8C55552E8593B2B77AC6FCA598A40D1F5F52A26C2322690A4BF1DFCB0DD8AEDD2822FF",
"last_ping": 1675968659
},
{
"ipv4": "kusoneko.moe",
"ipv6": "kusoneko.moe",
"port": 33445,
"tcp_ports": [
33445
],
"public_key": "BE7ED53CD924813507BA711FD40386062E6DC6F790EFA122C78F7CDEEE4B6D1B",
"maintainer": "Kusoneko",
"location": "CA",
"status_udp": true,
"status_tcp": true,
"version": "1000002013",
"motd": "Managed by kusoneko (ID:D8E4A5E926A4E7A85FA40F8CA55D47554F043D3C5CDB457187726F19CE20E52C0D7C3FCE9466)",
"last_ping": 1675968658
},
{
"ipv4": "tox2.plastiras.org",
"ipv6": "tox2.plastiras.org",
"port": 33445,
"tcp_ports": [
33445,
3389
],
"public_key": "B6626D386BE7E3ACA107B46F48A5C4D522D29281750D44A0CBA6A2721E79C951",
"maintainer": "Tha_14",
"location": "DE",
"status_udp": true,
"status_tcp": true,
"version": "1000002018",
"motd": "Add me on Tox: F0AA7C8C55552E8593B2B77AC6FCA598A40D1F5F52A26C2322690A4BF1DFCB0DD8AEDD2822FF",
"last_ping": 1675968659
},
{
"ipv4": "172.104.215.182",
"ipv6": "2600:3c03::f03c:93ff:fe7f:6096",
"port": 33445,
"tcp_ports": [
443,
33445,
3389
],
"public_key": "DA2BD927E01CD05EBCC2574EBE5BEBB10FF59AE0B2105A7D1E2B40E49BB20239",
"maintainer": "zero-one",
"location": "US",
"status_udp": true,
"status_tcp": true,
"version": "1000002018",
"motd": "tox-bootstrapd",
"last_ping": 1675968658
},
{
"ipv4": "5.19.249.240",
"ipv6": "-",
"port": 38296,
"tcp_ports": [
38296,
3389
],
"public_key": "DA98A4C0CD7473A133E115FEA2EBDAEEA2EF4F79FD69325FC070DA4DE4BA3238",
"maintainer": "Toxdaemon",
"location": "RU",
"status_udp": false,
"status_tcp": true,
"version": "",
"motd": "",
"last_ping": 1675968659
},
{
"ipv4": "NONE",
"ipv6": "2607:f130:0:f8::4c85:a645",
"port": 33445,
"tcp_ports": [
3389,
33445
],
"public_key": "8AFE1FC6426E5B77AB80318ED64F5F76341695B9FB47AB8AC9537BF5EE9E9D29",
"maintainer": "Busindre",
"location": "US",
"status_udp": false,
"status_tcp": true,
"version": "",
"motd": "",
"last_ping": 1675968658
},
{
"ipv4": "91.219.59.156",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "8E7D0B859922EF569298B4D261A8CCB5FEA14FB91ED412A7603A585A25698832",
"maintainer": "ray65536",
"location": "RU",
"status_udp": false,
"status_tcp": false,
"version": "1000002013",
"motd": "Ray's Tox Node. TOX ID:3C3D6DB24D24754393679E59F198EF45EE26835AEF7EA3E3ECEA40E204F2B828BE86DF012ABF",
"last_ping": 1669411200
},
{
"ipv4": "85.143.221.42",
"ipv6": "2a04:ac00:1:9f00:5054:ff:fe01:becd",
"port": 33445,
"tcp_ports": [],
"public_key": "DA4E4ED4B697F2E9B000EEFE3A34B554ACD3F45F5C96EAEA2516DD7FF9AF7B43",
"maintainer": "MAH69K",
"location": "RU",
"status_udp": false,
"status_tcp": false,
"version": "1000002013",
"motd": "Saluton! Mia Tox ID: B229B7BD68FC66C2716EAB8671A461906321C764782D7B3EDBB650A315F6C458EF744CE89F07. Scribu! ;)",
"last_ping": 1667642040
},
{
"ipv4": "tox.verdict.gg",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "1C5293AEF2114717547B39DA8EA6F1E331E5E358B35F9B6B5F19317911C5F976",
"maintainer": "Deliran",
"location": "DE",
"status_udp": false,
"status_tcp": false,
"version": "",
"motd": "",
"last_ping": 0
},
{
"ipv4": "78.46.73.141",
"ipv6": "2a01:4f8:120:4091::3",
"port": 33445,
"tcp_ports": [],
"public_key": "02807CF4F8BB8FB390CC3794BDF1E8449E9A8392C5D3F2200019DA9F1E812E46",
"maintainer": "Sorunome",
"location": "DE",
"status_udp": false,
"status_tcp": false,
"version": "",
"motd": "",
"last_ping": 0
},
{
"ipv4": "tox.initramfs.io",
"ipv6": "tox.initramfs.io",
"port": 33445,
"tcp_ports": [],
"public_key": "3F0A45A268367C1BEA652F258C85F4A66DA76BCAA667A49E770BCC4917AB6A25",
"maintainer": "initramfs",
"location": "TW",
"status_udp": false,
"status_tcp": false,
"version": "1000002018",
"motd": "initramfs' tox bootstrap node",
"last_ping": 1674742139
},
{
"ipv4": "46.229.50.168",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "813C8F4187833EF0655B10F7752141A352248462A567529A38B6BBF73E979307",
"maintainer": "Stranger",
"location": "UA",
"status_udp": false,
"status_tcp": false,
"version": "",
"motd": "",
"last_ping": 0
},
{
"ipv4": "mk.tox.dcntrlzd.network",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "5E815C25A4E58910A7350EC64ECB32BC9E1919F86844DC97125735C2C30FBE6E",
"maintainer": "cryptogospod",
"location": "MK",
"status_udp": false,
"status_tcp": false,
"version": "",
"motd": "",
"last_ping": 0
},
{
"ipv4": "tox.novg.net",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "D527E5847F8330D628DAB1814F0A422F6DC9D0A300E6C357634EE2DA88C35463",
"maintainer": "blind_oracle",
"location": "NL",
"status_udp": false,
"status_tcp": false,
"version": "1000002012",
"motd": "tox-bootstrapd",
"last_ping": 1673387100
},
{
"ipv4": "87.118.126.207",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "0D303B1778CA102035DA01334E7B1855A45C3EFBC9A83B9D916FFDEBC6DD3B2E",
"maintainer": "quux",
"location": "DE",
"status_udp": false,
"status_tcp": false,
"version": "",
"motd": "",
"last_ping": 0
},
{
"ipv4": "81.169.136.229",
"ipv6": "2a01:238:4254:2a00:7aca:fe8c:68e0:27ec",
"port": 33445,
"tcp_ports": [],
"public_key": "E0DB78116AC6500398DDBA2AEEF3220BB116384CAB714C5D1FCD61EA2B69D75E",
"maintainer": "9ofSpades",
"location": "DE",
"status_udp": false,
"status_tcp": false,
"version": "1000002009",
"motd": "🂩 wishes happy toxing. 📡",
"last_ping": 1674603960
},
{
"ipv4": "floki.blog",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "6C6AF2236F478F8305969CCFC7A7B67C6383558FF87716D38D55906E08E72667",
"maintainer": "Floki",
"location": "GB",
"status_udp": false,
"status_tcp": false,
"version": "",
"motd": "",
"last_ping": 0
},
{
"ipv4": "bg.tox.dcntrlzd.network",
"ipv6": "bg.tox.dcntrlzd.network",
"port": 33445,
"tcp_ports": [],
"public_key": "20AD2A54D70E827302CDF5F11D7C43FA0EC987042C36628E64B2B721A1426E36",
"maintainer": "cryptogospod",
"location": "BG",
"status_udp": false,
"status_tcp": false,
"version": "1000002015",
"motd": "BG tox-bootstrapd node, courtesy of DCNTRLZD NETWORK. Get in touch at 03279E64D53B1B71DFB35F4F5568B448B015F467C0C6F73FB52C9CCF86C78A45DB83C24E7DF2",
"last_ping": 1667250480
},
{
"ipv4": "46.146.229.184",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "94750E94013586CCD989233A621747E2646F08F31102339452CADCF6DC2A760A",
"maintainer": "GS",
"location": "RU",
"status_udp": false,
"status_tcp": false,
"version": "",
"motd": "",
"last_ping": 0
},
{
"ipv4": "gt.sot-te.ch",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "F4F4856F1A311049E0262E9E0A160610284B434F46299988A9CB42BD3D494618",
"maintainer": "SOT-TECH",
"location": "JP",
"status_udp": false,
"status_tcp": false,
"version": "1000002018",
"motd": "SOT-TECH NPO",
"last_ping": 1672337220
},
{
"ipv4": "209.59.144.175",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "214B7FEA63227CAEC5BCBA87F7ABEEDB1A2FF6D18377DD86BF551B8E094D5F1E",
"maintainer": "LasersAreGreat",
"location": "US",
"status_udp": false,
"status_tcp": false,
"version": "",
"motd": "",
"last_ping": 0
},
{
"ipv4": "rs.tox.dcntrlzd.network",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "FC4BADF62DCAF17168A4E3ACAD5D656CF424EDB5E0C0C2B9D77E509E74BD8F0D",
"maintainer": "cryptogospod",
"location": "RS",
"status_udp": false,
"status_tcp": false,
"version": "",
"motd": "",
"last_ping": 0
},
{
"ipv4": "195.123.208.139",
"ipv6": "2a02:27ac::3ff",
"port": 33445,
"tcp_ports": [],
"public_key": "534A589BA7427C631773D13083570F529238211893640C99D1507300F055FE73",
"maintainer": "Cüber",
"location": "LV",
"status_udp": false,
"status_tcp": false,
"version": "1000002013",
"motd": "😺 meow moew",
"last_ping": 1672186498
},
{
"ipv4": "208.38.228.104",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "3634666A51CA5BE1579C031BD31B20059280EB7C05406ED466BD9DFA53373271",
"maintainer": "LasersAreGreat",
"location": "US",
"status_udp": false,
"status_tcp": false,
"version": "",
"motd": "",
"last_ping": 0
},
{
"ipv4": "lunarfire.spdns.org",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "E61F5963268A6306CCFE7AF98716345235763529957BD5F45889484654EE052B",
"maintainer": "Merlinoz",
"location": "DE",
"status_udp": false,
"status_tcp": false,
"version": "",
"motd": "",
"last_ping": 0
},
{
"ipv4": "ru.tox.dcntrlzd.network",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "DBB2E896990ECC383DA2E68A01CA148105E34F9B3B9356F2FE2B5096FDB62762",
"maintainer": "cryptogospod",
"location": "RU",
"status_udp": false,
"status_tcp": false,
"version": "1000002015",
"motd": "RU tox-bootstrapd node, courtesy of DCNTRLZD NETWORK. Get in touch @ 03279E64D53B1B71DFB35F4F5568B448B015F467C0C6F73FB52C9CCF86C78A45DB83C24E7DF2",
"last_ping": 1666732500
},
{
"ipv4": "43.231.185.239",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "27D4029A96C9674C15B958011C62F63D4D35A23142EF2BA5CD9AF164162B3448",
"maintainer": "Jskmm",
"location": "US",
"status_udp": false,
"status_tcp": false,
"version": "",
"motd": "",
"last_ping": 0
},
{
"ipv4": "141.95.108.234",
"ipv6": "-",
"port": 33445,
"tcp_ports": [],
"public_key": "2DEF3156812324B1593A6442C937EAE0A8BD98DE529D2D4A7DD4BA6CB3ECF262",
"maintainer": "CTL.DPC.RE",
"location": "DE",
"status_udp": false,
"status_tcp": false,
"version": "1000002013",
"motd": "tox-bootstrapd",
"last_ping": 1661962379
},
{
"ipv4": "NONE",
"ipv6": "200:832f:2e56:91a6:678e:aaaf:80bf:4a8a",
"port": 33445,
"tcp_ports": [],
"public_key": "444361B1717AD5E10D9C03EA1C714A846C9D3B16A875186D0034DC516A49F013",
"maintainer": "Dima(Yggdrasil)",
"location": "RU",
"status_udp": false,
"status_tcp": false,
"version": "",
"motd": "",
"last_ping": 0
}
]
}