old_server_utils.nim 2.7 KB

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