Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. 'use strict'
  2. import bsock = require('bsock');
  3. import * as T from './Types';
  4. import * as I from './Interfaces';
  5. //fix args with defaults like "force = true" -> "force"
  6. function stripAfterEquals(str:string){
  7. return str.split("=")[0]
  8. }
  9. export class RPCSocket implements I.Socket{
  10. private socket: I.Socket
  11. constructor(public port:number, private server: string, private tls: boolean = false){
  12. Object.defineProperty(this, 'socket', {value: undefined, writable: true})
  13. }
  14. public hook(name: T.Name, args: T.Arg){
  15. return this.socket.hook(name, args)
  16. }
  17. public unhook(name: T.Name){
  18. return this.socket.unhook(name)
  19. }
  20. public on(type: "error" | "close", f: (e?: any) => void){
  21. return this.socket.on(type, f)
  22. }
  23. public destroy(){
  24. return this.socket.destroy()
  25. }
  26. public close(){
  27. return this.socket.close()
  28. }
  29. public async call (rpcname: T.Name, ...args: T.Any[]) : Promise<T.Any>{
  30. return await this.socket.call.apply(this.socket, [rpcname, ...args])
  31. }
  32. public async fire(rpcname: T.Name, ...args: T.Any[]) : Promise<T.Any>{
  33. return await this.socket.fire.apply(this.socket, [rpcname, ...args])
  34. }
  35. public async connect(){
  36. this.socket = await bsock.connect(this.port, this.server, this.tls)
  37. this.on('error', () => {})
  38. const info:T.ExtendedRpcInfo[] = await this.info()
  39. info.forEach(i => {
  40. let f: any
  41. switch (i.type) {
  42. case 'Call':
  43. f = this.callGenerator(i.uniqueName, i.argNames)
  44. break
  45. case 'Hook':
  46. f = this.hookGenerator(i.uniqueName, i.argNames)
  47. break
  48. }
  49. if(this[i.owner] == null)
  50. this[i.owner] = {}
  51. this[i.owner][i.name] = f
  52. this[i.owner][i.name].bind(this)
  53. })
  54. }
  55. public async info(){
  56. return await this.socket.call('info')
  57. }
  58. private callGenerator(fnName: T.Name, fnArgs:T.Arg[]): T.AsyncFunction{
  59. const headerArgs = fnArgs.join(",")
  60. const argParams = fnArgs.map(stripAfterEquals).join(",")
  61. return eval( '( () => async ('+headerArgs+') => { return await this.socket.call("'+fnName+'", '+argParams+')} )()' )
  62. }
  63. private hookGenerator(fnName: T.Name, fnArgs:T.Arg[]): T.HookFunction{
  64. const headerArgs = fnArgs.join(",")
  65. const argParams = fnArgs.map(stripAfterEquals).join(",")
  66. return eval( `( () => async (`+headerArgs+(headerArgs.length!==0?",":"")+` callback) => {
  67. const r = await this.socket.call("`+fnName+`", `+argParams+`)
  68. if(r.result === 'Success'){
  69. this.socket.hook(r.uuid, callback)
  70. }
  71. return r
  72. } )()` )
  73. }
  74. }