client_helpers.nim 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import ../../../../dist/checksums/src/checksums/md5
  2. import
  3. tables, sg_packets, enet, estreams, sg_gui, sfml,
  4. zlib_helpers, sg_assets, os
  5. type
  6. PServer* = ptr TServer
  7. TServer* = object
  8. connected*: bool
  9. addy: enet.TAddress
  10. host*: PHost
  11. peer*: PPeer
  12. handlers*: Table[char, TScPktHandler]
  13. TScPktHandler* = proc(serv: PServer; buffer: PBuffer)
  14. TFileTransfer = object
  15. fileName: string
  16. assetType: TAssetType
  17. fullLen: int
  18. pos: int32
  19. data: string
  20. readyToSave: bool
  21. var
  22. currentFileTransfer: TFileTransfer
  23. downloadProgress* = newButton(nil, "", vec2f(0,0), nil)
  24. currentFileTransfer.data = ""
  25. proc addHandler*(serv: PServer; packetType: char; handler: TScPktHandler) =
  26. serv.handlers[packetType] = handler
  27. proc newServer*(): PServer =
  28. result = cast[PServer](alloc0(sizeof(TServer)))
  29. result.connected = false
  30. result.host = createHost(nil, 1, 2, 0, 0)
  31. result.handlers = initTable[char, TScPktHandler](32)
  32. proc connect*(serv: PServer; host: string; port: int16; error: var string): bool =
  33. if setHost(serv.addy, host) != 0:
  34. error = "Could not resolve host "
  35. error.add host
  36. return false
  37. serv.addy.port = port.cushort
  38. serv.peer = serv.host.connect(serv.addy, 2, 0)
  39. if serv.peer.isNil:
  40. error = "Could not connect to host "
  41. error.add host
  42. return false
  43. return true
  44. proc send*[T](serv: PServer; packetType: char; pkt: var T) =
  45. if serv.connected:
  46. var b = newBuffer(100)
  47. b.write packetType
  48. b.pack pkt
  49. serv.peer.send(0.cuchar, b, FlagUnsequenced)
  50. proc sendPubChat*(server: PServer; msg: string) =
  51. var chat = newCsChat("", msg)
  52. server.send HChat, chat
  53. proc handlePackets*(server: PServer; buf: PBuffer) =
  54. while not buf.atEnd():
  55. let typ = readChar(buf)
  56. if server.handlers.hasKey(typ):
  57. server.handlers[typ](server, buf)
  58. else:
  59. break
  60. proc updateFileProgress*() =
  61. let progress = currentFileTransfer.pos / currentFileTransfer.fullLen
  62. downloadProgress.bg.setSize(vec2f(progress * 100, 20))
  63. downloadProgress.setString($currentFileTransfer.pos & '/' & $currentFileTransfer.fullLen)
  64. ## HFileTransfer
  65. proc handleFilePartRecv*(serv: PServer; buffer: PBuffer) =
  66. var
  67. f = readScFileTransfer(buffer)
  68. updateFileProgress()
  69. if not(f.pos == currentFileTransfer.pos):
  70. echo "returning early from filepartrecv"
  71. return ##issues, probably
  72. if currentFileTransfer.data.len == 0:
  73. echo "setting current file size"
  74. currentFileTransfer.data.setLen f.fileSize
  75. let len = f.data.len
  76. copymem(
  77. addr currentFileTransfer.data[f.pos],
  78. addr f.data[0],
  79. len)
  80. currentFileTransfer.pos = f.pos + len.int32
  81. if currentFileTransfer.pos == f.fileSize: #file should be done, rizzight
  82. currentFileTransfer.data = uncompress(
  83. currentFileTransfer.data, currentFileTransfer.fullLen)
  84. currentFileTransfer.readyToSave = true
  85. var resp: CsFileChallenge
  86. resp.checksum = toMD5(currentFileTransfer.data)
  87. serv.send HFileChallenge, resp
  88. echo "responded with challenge (ready to save)"
  89. else:
  90. var resp = newCsFilepartAck(currentFileTransfer.pos)
  91. serv.send HFileTransfer, resp
  92. echo "responded for next part"
  93. proc saveCurrentFile() =
  94. if not currentFileTransfer.readyToSave: return
  95. let
  96. path = expandPath(currentFileTransfer.assetType, currentFileTransfer.fileName)
  97. parent = parentDir(path)
  98. if not dirExists(parent):
  99. createDir(parent)
  100. echo("Created dir")
  101. writeFile path, currentFIleTransfer.data
  102. echo "Write file"
  103. ## HChallengeResult
  104. proc handleFileChallengeResult*(serv: PServer; buffer: PBuffer) =
  105. var res = readScChallengeResult(buffer).status
  106. echo "got challnege result: ", res
  107. if res and currentFileTransfer.readyToSave:
  108. echo "saving"
  109. saveCurrentFile()
  110. else:
  111. currentFileTransfer.readyToSave = false
  112. currentFileTransfer.pos = 0
  113. echo "REsetting current file"
  114. ## HFileCHallenge
  115. proc handleFileChallenge*(serv: PServer; buffer: PBuffer) =
  116. var
  117. challenge = readScFileChallenge(buffer)
  118. path = expandPath(challenge)
  119. resp: CsFileChallenge
  120. if not fileExists(path):
  121. resp.needFile = true
  122. echo "Got file challenge, need file."
  123. else:
  124. resp.checksum = toMD5(readFile(path))
  125. echo "got file challenge, sending sum"
  126. currentFileTransfer.fileName = challenge.file
  127. currentFileTransfer.assetType = challenge.assetType
  128. currentFileTransfer.fullLen = challenge.fullLen.int
  129. currentFileTransfer.pos = 0
  130. currentFileTransfer.data.setLen 0
  131. currentFileTransfer.readyToSave = false
  132. serv.send HFileChallenge, resp