server_utils.nim 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import enet, sg_packets, estreams, md5, zlib_helpers, client_helpers, strutils,
  2. idgen, sg_assets, tables, os
  3. type
  4. PClient* = ref object
  5. id*: int32
  6. auth*: bool
  7. alias*: string
  8. peer*: PPeer
  9. FileChallengePair* = tuple[challenge: ScFileChallenge; file: TChecksumFile]
  10. PFileChallengeSequence* = ref TFileChallengeSequence
  11. TFileChallengeSequence = object
  12. index: int #which file is active
  13. transfer: ScFileTransfer
  14. file: ptr FileChallengePair
  15. var
  16. clientID = newIdGen[int32]()
  17. myAssets*: seq[FileChallengePair] = @[]
  18. fileChallenges = initTable[int32, PFileChallengeSequence](32)
  19. const FileChunkSize = 256
  20. proc free(client: PClient) =
  21. if client.id != 0:
  22. fileChallenges.del client.id
  23. clientID.del client.id
  24. proc newClient*(): PClient =
  25. new(result, free)
  26. result.id = clientID.next()
  27. result.alias = "billy"
  28. proc `$`*(client: PClient): string =
  29. result = "$1:$2".format(client.id, client.alias)
  30. proc send*[T](client: PClient; pktType: char; pkt: var T) =
  31. var buf = newBuffer(128)
  32. buf.write pktType
  33. buf.pack pkt
  34. discard client.peer.send(0.cuchar, buf, flagReliable)
  35. proc sendMessage*(client: PClient; txt: string) =
  36. var m = newScChat(CSystem, text = txt)
  37. client.send HChat, m
  38. proc sendError*(client: PClient; error: string) =
  39. var m = newScChat(CError, text = error)
  40. client.send HChat, m
  41. proc next*(challenge: PFileChallengeSequence, client: PClient)
  42. proc sendChunk*(challenge: PFileChallengeSequence, client: PClient)
  43. proc startVerifyingFiles*(client: PClient) =
  44. var fcs: PFileChallengeSequence
  45. new(fcs)
  46. fcs.index = -1
  47. fileChallenges[client.id] = fcs
  48. next(fcs, client)
  49. proc next*(challenge: PFileChallengeSequence, client: PClient) =
  50. inc(challenge.index)
  51. if challenge.index >= myAssets.len:
  52. client.sendMessage "You are cleared to enter"
  53. fileChallenges.del client.id
  54. return
  55. else:
  56. echo myAssets.len, "assets"
  57. challenge.file = addr myAssets[challenge.index]
  58. client.send HFileChallenge, challenge.file.challenge # :rolleyes:
  59. echo "sent challenge"
  60. proc sendChunk*(challenge: PFileChallengeSequence, client: PClient) =
  61. let size = min(FileChunkSize, challenge.transfer.fileSize - challenge.transfer.pos)
  62. challenge.transfer.data.setLen size
  63. copyMem(
  64. addr challenge.transfer.data[0],
  65. addr challenge.file.file.compressed[challenge.transfer.pos],
  66. size)
  67. client.send HFileTransfer, challenge.transfer
  68. echo "chunk sent"
  69. proc startSend*(challenge: PFileChallengeSequence, client: PClient) =
  70. challenge.transfer.fileSize = challenge.file.file.compressed.len().int32
  71. challenge.transfer.pos = 0
  72. challenge.transfer.data = ""
  73. challenge.transfer.data.setLen FileChunkSize
  74. challenge.sendChunk(client)
  75. echo "starting xfer"
  76. ## HFileTransfer
  77. proc handleFilePartAck*(client: PClient; buffer: PBuffer) =
  78. echo "got filepartack"
  79. var
  80. ftrans = readCsFilepartAck(buffer)
  81. fcSeq = fileChallenges[client.id]
  82. fcSeq.transfer.pos = ftrans.lastPos
  83. fcSeq.sendChunk client
  84. ## HFileCHallenge
  85. proc handleFileChallengeResp*(client: PClient; buffer: PBuffer) =
  86. echo "got file challenge resp"
  87. var
  88. fcResp = readCsFileChallenge(buffer)
  89. fcSeq = fileChallenges[client.id]
  90. let index = $(fcSeq.index + 1) / $(myAssets.len)
  91. if fcResp.needFile:
  92. client.sendMessage "Sending file... "&index
  93. fcSeq.startSend(client)
  94. else:
  95. var resp = newScChallengeResult(false)
  96. if fcResp.checksum == fcSeq.file.file.sum: ##client is good
  97. client.sendMessage "Checksum is good. "&index
  98. resp.status = true
  99. client.send HChallengeResult, resp
  100. fcSeq.next(client)
  101. else:
  102. client.sendMessage "Checksum is bad, sending file... "&index
  103. client.send HChallengeResult, resp
  104. fcSeq.startSend(client)