old_server_utils.nim 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import ../../../dist/checksums/src/checksums/md5
  2. import
  3. streams, sockets,
  4. sg_packets, zlib_helpers, idgen
  5. type
  6. TClientType* = enum
  7. CServer = 0'i8, CPlayer, CUnknown
  8. PClient* = ref TClient
  9. TClient* = object of TObject
  10. id*: int32
  11. addy*: TupAddress
  12. clientID*: uint16
  13. auth*: bool
  14. outputBuf*: PStringStream
  15. case kind*: TClientType
  16. of CPlayer:
  17. alias*: string
  18. session*: string
  19. lastPing*: float
  20. failedPings*: int
  21. of CServer:
  22. record*: ScZoneRecord
  23. cfg*: TChecksumFile
  24. of CUnknown: nil
  25. TChecksumFile* = object
  26. unpackedSize*: int
  27. sum*: MD5Digest
  28. compressed*: string
  29. TupAddress* = tuple[host: string, port: int16]
  30. PIDGen*[T: Ordinal] = ref TIDGen[T]
  31. TIDGen[T: Ordinal] = object
  32. max: T
  33. freeIDs: seq[T]
  34. var cliID = newIdGen[int32]()
  35. proc sendMessage*(client: PClient; txt: string)
  36. proc sendError*(client: PClient; txt: string)
  37. proc `$`*(client: PClient): string
  38. proc newIncomingBuffer*(size = 1024): PStringStream =
  39. result = newStringStream("")
  40. result.data.setLen size
  41. result.data.setLen 0
  42. result.flushImpl = proc(stream: PStream) =
  43. stream.setPosition(0)
  44. PStringStream(stream).data.setLen(0)
  45. proc free*(c: PClient) =
  46. echo "Client freed: ", c
  47. cliID.del c.id
  48. c.outputBuf.flush()
  49. c.outputBuf = nil
  50. proc newClient*(addy: TupAddress): PClient =
  51. new(result, free)
  52. result.addy = addy
  53. result.outputBuf = newStringStream("")
  54. result.outputBuf.flushImpl = proc(stream: PStream) =
  55. stream.setPosition 0
  56. PStringStream(stream).data.setLen 0
  57. proc loginPlayer*(client: PClient; login: CsLogin): bool =
  58. if client.auth:
  59. client.sendError("You are already logged in.")
  60. return
  61. client.id = cliID.next()
  62. client.auth = true
  63. client.kind = CPlayer
  64. client.alias = login.alias
  65. client.session = getMD5(client.alias & $rand(10000))
  66. result = true
  67. proc `$`*(client: PClient): string =
  68. if not client.auth: return $client.addy
  69. case client.kind
  70. of CPlayer: result = client.alias
  71. of CServer: result = client.record.name
  72. else: result = $client.addy
  73. proc send*[T](client: PClient; pktType: char; pkt: var T) =
  74. client.outputBuf.write(pktType)
  75. pkt.pack(client.outputBuf)
  76. proc sendMessage*(client: PClient; txt: string) =
  77. var m = newScChat(CSystem, text = txt)
  78. client.send HChat, m
  79. proc sendError*(client: PClient; txt: string) =
  80. var m = newScChat(CError, text = txt)
  81. client.send HChat, m
  82. proc checksumFile*(filename: string): TChecksumFile =
  83. let fullText = readFile(filename)
  84. result.unpackedSize = fullText.len
  85. result.sum = toMD5(fullText)
  86. result.compressed = compress(fullText)
  87. proc checksumStr*(str: string): TChecksumFile =
  88. result.unpackedSize = str.len
  89. result.sum = toMD5(str)
  90. result.compressed = compress(str)