Source: instantiated.js

/**
 * Initializes the SDK for networking developers.
 * @constructor
 */
class InstantiatedSDK {
    constructor() {
        this.socket = new WebSocket("wss://instantiated.xyz:12701");
        this.Session = "";
        this.Socket = -1;
        this.Role = "";
        this.Clients = [];
        this.IsConnected = false;
        this.IsHost = false;
    }

    /**
     * Defines an on open connection for the websocket.
     * @param {Function} func 
     */
    onOpen(func) {
        // Sets an onopen event to the this.socket.
        this.socket.onopen = func;
    }

    /**
     * Defines an on message event listening to a event.data
     * @param {Function} func 
     */
    onMessage(func) {
        // Sets an onmessage event to the this.socket.
        this.socket.onmessage = func;
    }

    /**
     * Defines an on close event for when the connection was closed.
     * @param {Function} func 
     */
    onClose(func) {
        // Sets an onclose event to the this.socket.
        this.socket.onclose = func;
    }

    /**
     * Defines an on error event for when the connection times out.
     * @param {Function} func 
     */
    onError(func) {
        // Sets an onerror event to the this.socket.
        this.socket.onerror = func;
    }

    /**
     * Sets the role from the client.
     * @param {String} RoleID 
     */
    SetRole(RoleID) {
        this.Role = RoleID;
    }

    /**
     * Returns the role's id and outputs it in a string.
     * @returns Role's ID String
     */
    GetRole() {
        return this.Role;
    }

    /**
     * Sets the session id (which is required for any other calls.)
     * @param {String} InstanceID 
     */
    SetSessionID(InstanceID) {
        // Sets the session id to the api.
        this.Session = InstanceID;
    }

    /**
     * Sets the socket id (optional but is required for GetSocketID())
     * @param {Number} SocketID 
     */
    SetSocketID(SocketID) {
        // Sets the socket id to the api.
        this.Socket = SocketID;
    }

    /**
     * Grabs the socket id from the object and returns a number.
     * @returns Socket ID
     */
    GetSocketID() {
        // Returns the socket id.
        return this.Socket;
    }

    /**
     * Grabs the session id from the object and returns a string.
     * @returns Session ID
     */
    GetSessionID() {
        // Returns the session id.
        return this.Session;
    }

    /**
     * Creates a new session to host.
     * @param {String} AppTitle 
     * @param {Number} MaxConnections 
     * @param {Boolean} Whitelist 
     * @param {String} Password 
     * @param {String} RootPassword 
     * @param {Boolean} DefaultValues 
     * @param {Boolean} ForceHostTransfer 
     * @param {Boolean} KillHostServer 
     * @param {Boolean} AnnounceOpenSession
     */
    CreateSession(AppTitle, MaxConnections, Whitelist, Password, RootPassword, DefaultValues, ForceHostTransfer, KillHostServer, AnnounceOpenSession = false) {
        // Creates a new session for the client. The client is now considered the host.
        this.socket.send(JSON.stringify({
            msg: "create_server_session",
            Title: AppTitle,
            max_clients: MaxConnections,
            whitelist: Whitelist,
            passkey: Password,
            root_passkey: RootPassword,
            default_values: DefaultValues,
            force_host_transfer: ForceHostTransfer,
            host_killserver: KillHostServer,
            announceOpenSession: AnnounceOpenSession
        }));
    }

    /**
     * 
     * @param {String} Session_ID 
     * @param {String} AppTitle 
     * @param {Number} MaxConnections 
     * @param {Boolean} Whitelist 
     * @param {String} Password 
     * @param {Boolean} DefaultValues
     * @param {Boolean} AnnounceOpenSession
     */
    CreateServer(Session_ID, AppTitle, MaxConnections, Whitelist, Password, DefaultValues, AnnounceOpenSession = false) {
        // Creates a server only based session for the client. The client is now considered the host. Useful if your game is hosting under a console and doesn't require graphics.
        this.socket.send(JSON.stringify({
            msg: "server_only",
            SessionID: Session_ID,
            Title: AppTitle,
            max_clients: MaxConnections,
            whitelist: Whitelist,
            passkey: Password,
            default_values: DefaultValues,
            announceOpenSession: AnnounceOpenSession
        }));
    }

    /**
     * Disconnects from the session.
     */
    Disconnect() {
        // Disconnects from the session.
        this.socket.send(JSON.stringify({
            msg: "disconnect",
            instance_guid: this.Session
        }));
    }

    /**
     * Sends data to the host.
     * @param {JSON} Json 
     */
    Send(Json) {
        // Sends JSON data or a string to the host.
        this.socket.send(JSON.stringify({
            msg: "sent",
            instance_guid: this.Session,
            DataStream: Json,
            role_id: this.Role
        }));
    }

    /**
     * Host sends data to all connected clients.
     * @param {JSON} Json 
     */
    Receive(Json) {
        // Sends JSON data or a string to all the clients connected to this session.
        this.socket.send(JSON.stringify({
            msg: "received",
            instance_guid: this.Session,
            DataStream: Json
        }));
    }

    /**
     * Privately sends data to a connected socket.
     * @param {JSON} Json 
     * @param {Number} Socket_ID 
     */
    PrivateSend (Json, Socket_ID) {
        // Privately sends JSON data or a string to a single client connected to this session.
        this.socket.send(JSON.stringify({
            msg: "private_msg",
            instance_guid: this.Session,
            DataStream: Json,
            socket: Socket_ID
        }));
    }

    /**
     * Sends data to a socket (does not need to join a session.)
     * @param {JSON} Json 
     * @param {Number} Socket_ID 
     */
    SocketSend (Json, Socket_ID) {
        // Sends JSON Data or a string to a socket that is connected to the Instantiated server. They do not need to be connected to the session to send data to you.
        this.socket.send(JSON.stringify({
            msg: "socket_to",
            DataStream: Json,
            SocketID: Socket_ID
        }));
    }

    /**
     * Pings the server that your alive. (times out at a minute.)
     */
    Ping () {
        // Pings the network letting them know that you are still alive.
        this.socket.send(JSON.stringify({
            msg: "ping"
        }));
    }

    /**
     * Transfers session ownership to someone else. (The host must initiate this.)
     * @param {Number} socket_id 
     */
    TransferOwnership (socket_id) {
        // Transfers ownership to someone else if they're online.
        this.socket.send(JSON.stringify({
            msg: "transfer_ownership",
            instance_guid: this.Session,
            socketid: socket_id,
            role_id: this.Role
        }));
    }

    /**
     * Creates an invite code for users to join with. (Does not bypass bans or passwords.)
     * @param {Number} max_use 
     */
    CreateInvite(max_use) {
        // Creates an invite code for you to send to your friends.
        this.socket.send(JSON.stringify({
            msg: "CreateInvite",
            instance_guid: this.Session,
            limitUse: max_use,
            role_id: this.Role
        }));
    }

    /**
     * Deletes an invite code making it useless.
     * @param {String} code 
     */
    DeleteInvite(code) {
        // Deletes an invite code and invalidates it.
        this.socket.send(JSON.stringify({
            msg: "DeleteInvite",
            instance_guid: this.Session,
            invite_code: code,
            role_id: this.Role
        }));
    }

    /**
     * Exports account data from the session.
     */
    AccountExport() {
        // Allows you to backup accounts from the session.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "Export"
        }));
    }

    /**
     * Imports account data to the session.
     * @param {JSON} account_data 
     */
    AccountImport(account_data) {
        // Allows you to restore accounts from json data.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "Import",
            account_json: account_data
        }));
    }

    /**
     * Logs in to your account in the session. Must be registered in your session.
     * @param {String} username 
     * @param {String} password 
     */
    AccountLogin(username, password) {
        // Logs you in to your registered account in the session.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "Login",
            userid: username,
            passkey: password
        }));
    }

    /**
     * Registers an account on the session.
     * @param {String} username 
     * @param {String} password 
     * @param {String} alias 
     */
    AccountRegister(username, password, alias) {
        // Registers an account in a connected session.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "Register",
            userid: username,
            passkey: password,
            nickname: alias
        }));
    }

    /**
     * Logs out of the session account.
     */
    AccountLogout() {
        // Logs you out of the account.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "Logout"
        }));
    }

    /**
     * Stores an item to your personal account.
     * @param {String} Item 
     * @param {String} Data 
     */
    AccountSaveData(Item, Data) {
        // Stores private data that only the account has access to.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "SaveData",
            item: Item,
            data: Data
        }));
    }

    /**
     * Loads an item from your personal account.
     * @param {String} Item 
     */
    AccountLoadData(Item) {
        // Grabs the account's item data.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "LoadData",
            item: Item
        }));
    }

    /**
     * Deletes the item from your personal account.
     * @param {String} Item 
     */
    AccountDeleteData(Item) {
        // Deletes the account's item.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "DeleteData",
            item: Item
        }));
    }

    /**
     * Reads mail in your account. Hosts can use Username to read messages from the account.
     * @param {Number} mail_id 
     * @param {String} username 
     */
    AccountReadMail(mail_id, username = null) {
        // Reads messages sent by other accounts.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "ReadMailbox",
            position: mail_id,
            userid: username
        }));
    }

    /**
     * Sends mail to someone connected.
     * @param {String} To 
     * @param {String} Subject 
     * @param {String} TextMessage 
     */
    AccountSendMail(To, Subject, TextMessage) {
        // Sends a message to other accounts.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "SendMailbox",
            to: To,
            subject: Subject,
            textmessage: TextMessage
        }));
    }

    /**
     * Deletes a message from their session.
     * @param {Number} Position 
     * @param {String} Username 
     */
    AccountDeleteMessage(Position, Username) {
        // Deletes a message from your account.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "DeleteMessageMail",
            position: Position,
            userid: Username
        }));
    }

    /**
     * Edits the session account.
     * @param {String} Alias 
     * @param {String} Bio 
     * @param {String} Status 
     * @param {String} ProfileIMG_Url 
     * @param {String} Username 
     */
    AccountEdit(Alias, Bio, Status, ProfileIMG_Url, Username = null) {
        // Edits the account.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "EditAccount",
            nickname: Alias,
            bio: Bio,
            status: Status,
            profile_img: ProfileIMG_Url,
            userid: Username
        }));
    }

    /**
     * Searches the profile account from inside the session.
     * @param {String} Username 
     */
    AccountProfileSearch(Username) {
        // Search for an account using the username result.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "ProfileSearch",
            userid: Username
        }));
    }

    /**
     * Looks for the account information.
     * @param {String} Username 
     */
    AccountInfo(Username = null) {
        // Checks the account information.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "GrabAccountInfo",
            userid: Username
        }));
    }

    /**
     * Changes the account's password.
     * @param {String} NewPassword 
     * @param {String} Username 
     */
    AccountChangePassword(NewPassword, Username = null) {
        // Change the account's password.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "EditAccountPassword",
            passkey: NewPassword,
            userid: Username
        }));
    }

    /**
     * Deletes the account. Username left blank will delete your account.
     * @param {String} Username 
     */
    AccountDelete(Username = null) {
        // Completely deletes the account from the instance.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "DeleteInstanceAccount",
            userid: Username
        }));
    }

    /**
     * Assigns the account a role specified by the host.
     * @param {String} Username 
     * @param {String} RoleName 
     */
    AccountAssignRole(Username, RoleName) {
        // Assigns the account to a role so when logged in they are assigned automatically to that role.
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "AssignAccountRole",
            userid: Username,
            role_name: RoleName
        }));
    }

    /**
     * Unassigns the account a role specified by the host.
     * @param {String} Username 
     * @param {String} RoleName 
     */
    AccountUnassignRole(Username, RoleName) {
        // Unassign the account 
        this.socket.send(JSON.stringify({
            msg: "AccountSystem",
            instance_guid: this.Session,
            cmd: "RemoveAssignedAccountRole",
            userid: Username,
            role_name: RoleName
        }));
    }

    /**
     * Changes the instance's password.
     * @param {String} NewPassword 
     */
    ChangeInstancePassword(NewPassword) {
        // Changes the instance's password.
        this.socket.send(JSON.stringify({
            msg: "ChangeInstancePassword",
            instance_guid: this.Session,
            passkey: NewPassword,
            role_id: this.Role
        }));
    }

    /**
     * Announces the message to the instantiated discord under #session-loginfo.
     * @param {String} Message 
     * @param {String} Type 
     */
    AnnounceOnDiscord(Message, Type = "maintenance") {
        // Announces your events to discord.
        this.socket.send(JSON.stringify({
            msg: "AnnounceToDiscord",
            instance_guid: this.Session,
            announcement: Message,
            type: Type,
            role_id: this.Role
        }))
    }

    /**
     * Logins to your cloud account. (Only have to use it once)
     * @param {String} user 
     * @param {String} pass 
     */
    CloudLogin(user, pass) {
        this.socket.send(JSON.stringify({
            msg: "Cloud",
            action: "Login",
            username: user,
            password: pass
        }))
    }

    /**
     * Registers an account with the cloud services.
     * @param {String} user 
     * @param {String} pass 
     */
    CloudRegister(user, pass) {
        // Registers your ip address to the cloud.
        this.socket.send(JSON.stringify({
            msg: "Cloud",
            action: "Register",
            username: user,
            password: pass
        }));
    }

    /**
     * Adds data to the cloud storage.
     * @param {String} Key 
     * @param {String} Value 
     */
    CloudAdd(Key, Value) {
        // Adds the key data to the cloud.
        this.socket.send(JSON.stringify({
            msg: "Cloud",
            action: "Add",
            Item: Key,
            Data: Value
        }));
    }

    /**
     * Updates the data from the cloud storage.
     * @param {String} Key 
     * @param {String} Value 
     */
    CloudUpdate(Key, Value) {
        // Updates the key data to a value.
        this.socket.send(JSON.stringify({
            msg: "Cloud",
            action: "Update",
            Item: Key,
            Data: Value
        }));
    }

    /**
     * Grabs the item from cloud storage.
     * @param {String} Key 
     */
    CloudRemove(Key) {
        // Completely removes the key from the cloud storage.
        this.socket.send(JSON.stringify({
            msg: "Cloud",
            action: "Remove",
            Item: Key
        }));
    }

    /**
     * Increments a value by either adding or inserting a string or number.
     * @param {String} Key 
     * @param {String} Value 
     */
    CloudAppend(Key, Value) {
        // Add/Appends the data from the cloud storage.
        this.socket.send(JSON.stringify({
            msg: "Cloud",
            action: "Append",
            Item: Key,
            Data: Value
        }));
    }

    /**
     * Returns the data from cloud storage.
     * @param {String} Key 
     */
    CloudGetValue(Key) {
        // Retrieves the cloud key data.
        this.socket.send(JSON.stringify({
            msg: "Cloud",
            action: "Get",
            Item: Key
        }));
    }

    /**
     * Resets the cloud storage to zero. This action cannot be undone.
     */
    CloudReset() {
        // Resets the storage to zero. Cannot be undone.
        this.socket.send(JSON.stringify({
            msg: "Cloud",
            action: "Reset"
        }));
    }

    /**
     * Returns the cloud information, such as your support code, storage structure and your size limits.
     */
    CloudInfo() {
        // Displays information about your cloud storage.
        this.socket.send(JSON.stringify({
            msg: "Cloud",
            action: "Info"
        }));
    }

    /**
     * Deletes your cloud storage account (Warning: Once this packet is sent, your account will be permanently deleted from the database. It may be recoverable if contacted about missing accounts.)
     */
    CloudAccountDelete() {
        this.socket.send(JSON.stringify({
            msg: "Cloud",
            action: "DeleteUserAccount"
        }));
    }

    /**
     * Registers a mail account.
     * @param {String} Username 
     * @param {String} Password 
     */
    MailRegister(Username, Password) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "Register",
            username: Username,
            password: Password
        }));
    }
    
    /**
     * Logs into your mail account.
     * @param {String} Username 
     * @param {String} Password 
     */
    MailLogin(Username, Password) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "Login",
            username: Username,
            password: Password
        }));
    }

    /**
     * Lists folders inside the mail account.
     */
    MailListFolders() {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "ListFolders"
        }));
    }

    /**
     * Lists all the mail inside the folder.
     * @param {String} FolderName 
     */
    MailListMailInFolder(FolderName) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "ListMailInFolder",
            folder: FolderName
        }));
    }

    /**
     * Reads the mail inside the folder.
     * @param {String} FolderName 
     * @param {Number} MailNumber 
     */
    ReadMail(FolderName, MailNumber) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "ReadMail",
            folder: FolderName,
            mail_id: MailNumber
        }));
    }

    /**
     * Sends a message to someone with the invite code if specified.
     * @param {String} To 
     * @param {String} Subj 
     * @param {String} Msg 
     * @param {String} invite 
     */
    ComposeMail(To, Subj, Msg, invite = null) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "Compose",
            to: To,
            Subject: Subj,
            Message: Msg,
            InviteCode: invite
        }));
    }

    /**
     * Marks the message as read.
     * @param {String} FolderName 
     * @param {Number} MailNumber 
     */
    MarkMailAsRead(FolderName, MailNumber) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "MarkAsRead",
            folder: FolderName,
            mail_id: MailNumber
        }));
    }

    /**
     * Marks the message as un-read.
     * @param {String} FolderName 
     * @param {Number} MailNumber 
     */
    MarkMailAsUnread(FolderName, MailNumber) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "MarkAsUnread",
            folder: FolderName,
            mail_id: MailNumber
        }));
    }

    /**
     * Deletes the message to the folder.
     * @param {String} FolderName 
     * @param {Number} MailNumber 
     */
    DeleteMail(FolderName, MailNumber) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "DeleteMail",
            folder: FolderName,
            mail_id: MailNumber
        }));
    }

    /**
     * Moves the message to a folder.
     * @param {String} OldFolder 
     * @param {Number} MailNumber 
     * @param {String} NewFolder 
     */
    MoveMailToFolder(OldFolder, MailNumber, NewFolder) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "MoveMail",
            oldfolder: OldFolder,
            oldmail: MailNumber,
            newfolder: NewFolder
        }));
    }

    /**
     * Creates a new folder in the mail account.
     * @param {String} NewFolder 
     */
    CreateMailFolder(NewFolder) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "NewFolder",
            folder_name: NewFolder
        }));
    }

    /**
     * Adds someone to a spam list.
     * @param {String} Username 
     */
    AddSpammer(Username) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "AddSpammer",
            spammer: Username
        }));
    }

    /**
     * Removes someone to a spam list.
     * @param {String} Username 
     */
    RemoveSpammer(Username) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "RemoveSpammer",
            spammer: Username
        }));
    }

    /**
     * Blocks a user from contacting you.
     * @param {String} Username 
     */
    BlockMailUser(Username) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "BlockUser",
            username: Username
        }));
    }

    /**
     * Unblocks a user from contacting you.
     * @param {String} Username 
     */
    UnblockMailUser(Username) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "UnblockUser",
            username: Username
        }));
    }

    /**
     * Deletes a folder from the mail account.
     * @param {String} FolderName 
     */
    DeleteMailFolder(FolderName) {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "DeleteFolder",
            folder_name: FolderName
        }));
    }

    /**
     * Deletes the mail account. This action cannot be undone. You must also be logged in.
     */
    DeleteMailAccount() {
        this.socket.send(JSON.stringify({
            msg: "Mail",
            action: "DeleteAccount"
        }));
    }

    /**
     * Exposes the client's ip address if there connected to your session.
     */
    ExposeClientsIP() {
        // Exposes the clients ip address (instance host and roles that have this permission can use it.)
        this.socket.send(JSON.stringify({
            msg: "ExposeConnectedClients",
            instance_guid: this.Session,
            role_id: this.Role
        }));
    }

    /**
     * Check's the newsletter displayed from instantiated.
     */
    Check_Newsletters() {
        // Displays the latest news from instantiated.
        this.socket.send(JSON.stringify({
            msg: "Newsletters"
        }));
    }

    /**
     * Sets the instance's message of the day.
     * @param {String} Message 
     */
    SetInstanceMOTD(Message) {
        // Sets the message of the day text to something like "A WSTunnel Server."
        this.socket.send(JSON.stringify({
            msg: "MOTD",
            mode: "set",
            instance_guid: this.Session,
            motd: Message,
            role_id: this.Role
        }));
    }

    /**
     * Grabs the instance's message of the day.
     */
    GetInstanceMOTD() {
        // Retrieves the MOTD message.
        this.socket.send(JSON.stringify({
            msg: "MOTD",
            mode: "get",
            instance_guid: this.Session
        }));
    }

    /**
     * Adds the instance rule to the session.
     * @param {String} Rule_String 
     */
    AddInstanceRule(Rule_String) {
        // Adds your rule to the instance. (Host & Roles with the permissions can add rules.)
        this.socket.send(JSON.stringify({
            msg: "InstanceRules",
            mode: "Add",
            instance_guid: this.Session,
            rule: Rule_String,
            role_id: this.Role
        }));
    }

    /**
     * Removes the instance rule from the session.
     * @param {Number} RuleNumber 
     */
    RemoveInstanceRule(RuleNumber) {
        // Removes a rule from the instance. (Host & Roles with the permissions can remove rules.)
        this.socket.send(JSON.stringify({
            msg: "InstanceRules",
            mode: "Remove",
            instance_guid: this.Session,
            rule_num: RuleNumber,
            role_id: this.Role
        }));
    }

    /**
     * Updates the instance rule from an index. First rule is indexed at 0.
     * @param {Number} RuleNumber 
     * @param {String} Rule_String 
     */
    UpdateInstanceRule(RuleNumber, Rule_String) {
        // Replaces the old rule with a new one. (Host & Roles with the permissions can update the rules.)
        this.socket.send(JSON.stringify({
            msg: "InstanceRules",
            mode: "Update",
            instance_guid: this.Session,
            rule_num: RuleNumber,
            rule: Rule_String,
            role_id: this.Role
        }));
    }

    /**
     * Grabs the instance rules and displays them as arrays.
     */
    GetInstanceRules() {
        // Anyone can request the instance rules if there connected to an instance (might later change that.)
        this.socket.send(JSON.stringify({
            msg: "InstanceRules",
            mode: "Get",
            instance_guid: this.Session
        }));
    }

    /**
     * Creates the role with a specified color if defined.
     * @param {String} RoleName 
     * @param {Color} Color 
     */
    CreateRole(RoleName, Color = "#ff0000") {
        // Creates a new role with the color.
        this.socket.send(JSON.stringify({
            msg: "RoleManager",
            instance_guid: this.Session,
            cmd: "CreateRole",
            role_name: RoleName,
            color: Color,
            role_id: this.Role
        }));
    }

    /**
     * Edits the role's permission. If a permission is not defined from the permission's list it creates a definedpermission.
     * @param {String} PermissionID 
     * @param {String} RoleName 
     */
    EditRolePermission(PermissionID, RoleName) {
        // Edits the role's permissions set by the instance.
        this.socket.send(JSON.stringify({
            msg: "RoleManager",
            instance_guid: this.Session,
            cmd: "EditRole",
            permissionId: PermissionID,
            role_name: RoleName,
            role_id: this.Role
        }));
    }

    /**
     * Delete's the role. Any client assigned to this role is automatically removed.
     * @param {String} RoleName 
     */
    DeleteRole(RoleName) {
        // Deletes the role and removes it entirely.
        this.socket.send(JSON.stringify({
            msg: "RoleManager",
            instance_guid: this.Session,
            cmd: "DeleteRole",
            role_name: RoleName,
            role_id: this.Role
        }));
    }

    /**
     * Adds the client to the role.
     * @param {String} RoleName 
     * @param {Number} SocketID 
     */
    AddClientToRole(RoleName, SocketID) {
        // Assigns the role to a socket connected to the session.
        this.socket.send(JSON.stringify({
            msg: "RoleManager",
            instance_guid: this.Session,
            cmd: "AddClientToRole",
            role_name: RoleName,
            socketid: SocketID,
            role_id: this.Role
        }));
    }

    /**
     * Removes the role from the client.
     * @param {String} RoleName 
     * @param {Number} SocketID 
     */
    RemoveClientFromRole(RoleName, SocketID) {
        // Un-assign the role from a socket.
        this.socket.send(JSON.stringify({
            msg: "RoleManager",
            instance_guid: this.Session,
            cmd: "RemoveClientFromRole",
            role_name: RoleName,
            socketid: SocketID,
            role_id: this.Role
        }));
    }

    /**
     * Edit the role's color.
     * @param {String} RoleName 
     * @param {Color} Color 
     */
    EditRoleColor(RoleName, Color) {
        // Modify the role's color.
        this.socket.send(JSON.stringify({
            msg: "RoleManager",
            instance_guid: this.Session,
            cmd: "EditRoleColor",
            role_name: RoleName,
            color: Color,
            role_id: this.Role
        }));
    }

    /**
     * Views the roles from the session. Anyone can request this at anytime.
     */
    ViewRoles() {
        // Views a list of roles.
        this.socket.send(JSON.stringify({
            msg: "ViewRoles",
            instance_guid: this.Session
        }));
    }

    /**
     * Lock's the role from being edited or removed. Only the instance host can manage this role.
     * @param {String} RoleName 
     */
    LockRole(RoleName) {
        // Locks the role down to host only.
        this.socket.send(JSON.stringify({
            msg: "LockRole",
            instance_guid: this.Session,
            role_name: RoleName
        }));
    }

    /**
     * Reports the user to the session host.
     * @param {Number} Against 
     * @param {String} Reason 
     */
    ReportUserToHost(Against, Reason) {
        // Sends a report to the host.
        this.socket.send(JSON.stringify({
            msg: "report",
            instance_guid: this.Session,
            against: Against,
            reason: Reason
        }));
    }

    /**
     * Displays the about section of Instantiated.
     */
    AboutInstantiated() {
        // Sends an about Instantiated with JSON.
        this.socket.send(JSON.stringify({
            msg: "about"
        }));
    }

    /**
     * Globally reports the user to the staff members of Instantiated.
     * @param {Number} SocketID 
     * @param {String} MESSAGE 
     */
    ReportUserToStaff(SocketID, MESSAGE) {
        // Globally reports the user to Instantiated Staff members who have access to the report system.
        this.socket.send(JSON.stringify({
            msg: "FileReport",
            socketid: SocketID,
            Message: MESSAGE
        }));
    }

    /**
     * Grabs Instantiated's message of the day. This is global.
     */
    GetMOTD() {
        // Grab's instantiated's MOTD message.
        this.socket.send(JSON.stringify({
            msg: "SendMotd"
        }));
    }

    /**
     * Locks the instance from accepting new connections.
     */
    LockInstance() {
        // Locks the instance so no new clients can join.
        this.socket.send(JSON.stringify({
            msg: "toggle_lock",
            instance_guid: this.Session,
            role_id: this.Role
        }));
    }

    /**
     * Takes control of the instance and transfers instance ownership to the new client.
     * @param {String} Password 
     */
    TakeControl(Password) {
        // Takes over the instance with a root password.
        this.socket.send(JSON.stringify({
            msg: "take_control",
            instance_guid: this.Session,
            passkey: Password
        }));
    }

    /**
     * Joins the instance session if it's available.
     * @param {String} InstanceID 
     * @param {String} Password 
     * @param {String} Invitation_Code 
     */
    JoinServer(InstanceID, Password, Invitation_Code, AcceptWarning = 0) {
        // Joins the instance server with a password and an invite code (if provided one).
        this.socket.send(JSON.stringify({
            msg: "join_server",
            instance_guid: InstanceID,
            passkey: Password,
            invite_code: Invitation_Code,
            accept: AcceptWarning
        }));
    }

    /**
     * Bans the ip address from the session.
     * @param {String} IPAddress 
     * @param {Number} SocketID 
     * @param {EpochTimeStamp} Duration 
     * @param {String} Reason 
     */
    BanIP(IPAddress, SocketID, Duration, Reason) {
        // Bans the ip address from joining the session. Provided with duration and a reason for the ban.
        this.socket.send(JSON.stringify({
            msg: "ban_ip",
            instance_guid: this.Session,
            duration: Duration,
            banip: IPAddress,
            socket: SocketID,
            reason: Reason,
            role_id: this.Role
        }));
    }

    /**
     * Unbans the ip address, allowing the session to join.
     * @param {String} IPAddress 
     */
    UnbanIP(IPAddress) {
        // Completely pardons the ip address and unbans it. Allowing that ip address to rejoin back in.
        this.socket.send(JSON.stringify({
            msg: "unban_ip",
            instance_guid: this.Session,
            unbanip: IPAddress,
            role_id: this.Role
        }));
    }

    /**
     * Adds the ip address to the whitelist.
     * @param {String} IPAddress 
     */
    AddIPToWhitelist(IPAddress) {
        // Adds an ip address to the whitelist.
        this.socket.send(JSON.stringify({
            msg: "add_whitelist",
            instance_guid: this.Session,
            whitelist_ip: IPAddress,
            role_id: this.Role
        }));
    }

    /**
     * Removes the ip address from the whitelist.
     * @param {String} IPAddress 
     */
    RemoveIPFromWhitelist(IPAddress) {
        // Removes an ip address from the whitelist.
        this.socket.send(JSON.stringify({
            msg: "del_whitelist",
            instance_guid: this.Session,
            whitelist_ip: IPAddress,
            role_id: this.Role
        }));
    }

    /**
     * Toggles the whitelist from the session.
     */
    ToggleWhitelist() {
        // Toggles whitelisting.
        this.socket.send(JSON.stringify({
            msg: "toggle_whitelist",
            instance_guid: this.Session,
            role_id: this.Role
        }));
    }

    /**
     * Kicks the user from the session.
     * @param {Number} SocketID 
     * @param {String} Reason 
     */
    Kick(SocketID, Reason) {
        // Kicks a socket out of the session.
        this.socket.send(JSON.stringify({
            msg: "kick",
            instance_guid: this.Session,
            socketid: SocketID,
            reason: Reason,
            role_id: this.Role
        }));
    }

    /**
     * Grabs the data from the session's storage.
     * @param {String} Item_ 
     * @param {String} Password 
     */
    GetSessionData(Item_, Password = null) {
        // Grabs the session's item and reads it. (If password is provided then it is required unless you have the permission in your role.)
        this.socket.send(JSON.stringify({
            msg: "get_storage",
            instance_guid: this.Session,
            Item: Item_,
            passkey: Password,
            role_id: this.Role
        }));
    }

    /**
     * Deletes the item from the session's storage.
     * @param {String} Item_ 
     * @param {String} Password 
     */
    DeleteSessionItem(Item_, Password = null) {
        // Deletes the session's item from session storage. (If password is provided then it is required unless you have the permission in your role.)
        this.socket.send(JSON.stringify({
            msg: "del_storage",
            instance_guid: this.Session,
            Item: Item_,
            passkey: Password,
            role_id: this.Role
        }));
    }

    /**
     * Adds/Updates the item from the session's storage.
     * @param {String} Item_ 
     * @param {String} Data_ 
     * @param {String} Password 
     */
    AddSessionData(Item_, Data_, Password = null) {
        // Adds/Updates the session's item from session storage to a new value. (If password is provided then it is required unless you have the permission in your role.)
        this.socket.send(JSON.stringify({
            msg: "add_storage",
            instance_guid: this.Session,
            Item: Item_,
            Data: Data_,
            passkey: Password,
            role_id: this.Role
        }));
    }

    /**
     * Inspects the session and outputs the inspection. Use "All" for grabbing everything.
     * @param {String} Inspection 
     */
    InspectSession(Inspection = "All") {
        // Only the host instance can inspect the session. Retrieves the instance's information.
        this.socket.send(JSON.stringify({
            msg: "inspect_session",
            instance_guid: this.Session,
            Inspector: Inspection
        }));
    }

    /**
     * Searches the instance for the specified application title.
     * @param {String} ApplicationTitle 
     */
    SearchInstances(ApplicationTitle) {
        // Searches through every session with the provided application title.
        this.socket.send(JSON.stringify({
            msg: "get_sessions",
            Title: ApplicationTitle
        }));
    }

    /**
     * Searches the instance and finds the first one available.
     * @param {String} ApplicationTitle 
     */
    SearchInstanceOnce(ApplicationTitle) {
        // Finds the first instance it finds.
        this.socket.send(JSON.stringify({
            msg: "auto-discover",
            Title: ApplicationTitle
        }));
    }

    /**
     * Changes the session's icon from a image url.
     * @param {URL} ImageURL 
     */
    ChangeSessionIcon(ImageURL) {
        // Changes the session's icon to an image url.
        this.socket.send(JSON.stringify({
            msg: "ChangeSessionIcon",
            instance_guid: this.Session,
            image_url: ImageURL
        }));
    }

    /**
     * Grabs the session's icon.
     */
    GetSessionIcon() {
        // Retrieves the session's icon.
        this.socket.send(JSON.stringify({
            msg: "GetSessionIcon",
            instance_guid: this.Session
        }));
    }

    /**
     * Host warns the client with a specified reason.
     * @param {String} Reason 
     * @param {Number} SocketID 
     */
    WarnClient(Reason, SocketID) {
        // Warns the client about their behaviour in the instance. (only the host or the role with the permission can warn users.)
        this.socket.send(JSON.stringify({
            msg: "WarnClient",
            instance_guid: this.Session,
            reason: Reason,
            socketid: SocketID,
            role_id: this.Role
        }));
    }

    /**
     * Saves the premium session's data.
     * @param {String} RootPassword 
     */
    SavePremiumSession(RootPassword) {
        // Saves the premium session's data. (Must be premium and bought. Otherwise it won't work.)
        this.socket.send(JSON.stringify({
            msg: "SavePremiumSession",
            instance_guid: this.Session,
            root_passkey: RootPassword
        }));
    }
}