123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- import
- streams, md5, sockets,
- sg_packets, zlib_helpers, idgen
- type
- TClientType* = enum
- CServer = 0'i8, CPlayer, CUnknown
- PClient* = ref TClient
- TClient* = object of TObject
- id*: int32
- addy*: TupAddress
- clientID*: uint16
- auth*: bool
- outputBuf*: PStringStream
- case kind*: TClientType
- of CPlayer:
- alias*: string
- session*: string
- lastPing*: float
- failedPings*: int
- of CServer:
- record*: ScZoneRecord
- cfg*: TChecksumFile
- of CUnknown: nil
- TChecksumFile* = object
- unpackedSize*: int
- sum*: MD5Digest
- compressed*: string
- TupAddress* = tuple[host: string, port: int16]
- PIDGen*[T: Ordinal] = ref TIDGen[T]
- TIDGen[T: Ordinal] = object
- max: T
- freeIDs: seq[T]
- var cliID = newIdGen[int32]()
- proc sendMessage*(client: PClient; txt: string)
- proc sendError*(client: PClient; txt: string)
- proc `$`*(client: PClient): string
- proc newIncomingBuffer*(size = 1024): PStringStream =
- result = newStringStream("")
- result.data.setLen size
- result.data.setLen 0
- result.flushImpl = proc(stream: PStream) =
- stream.setPosition(0)
- PStringStream(stream).data.setLen(0)
- proc free*(c: PClient) =
- echo "Client freed: ", c
- cliID.del c.id
- c.outputBuf.flush()
- c.outputBuf = nil
- proc newClient*(addy: TupAddress): PClient =
- new(result, free)
- result.addy = addy
- result.outputBuf = newStringStream("")
- result.outputBuf.flushImpl = proc(stream: PStream) =
- stream.setPosition 0
- PStringStream(stream).data.setLen 0
- proc loginPlayer*(client: PClient; login: CsLogin): bool =
- if client.auth:
- client.sendError("You are already logged in.")
- return
- client.id = cliID.next()
- client.auth = true
- client.kind = CPlayer
- client.alias = login.alias
- client.session = getMD5(client.alias & $rand(10000))
- result = true
- proc `$`*(client: PClient): string =
- if not client.auth: return $client.addy
- case client.kind
- of CPlayer: result = client.alias
- of CServer: result = client.record.name
- else: result = $client.addy
- proc send*[T](client: PClient; pktType: char; pkt: var T) =
- client.outputBuf.write(pktType)
- pkt.pack(client.outputBuf)
- proc sendMessage*(client: PClient; txt: string) =
- var m = newScChat(CSystem, text = txt)
- client.send HChat, m
- proc sendError*(client: PClient; txt: string) =
- var m = newScChat(CError, text = txt)
- client.send HChat, m
- proc checksumFile*(filename: string): TChecksumFile =
- let fullText = readFile(filename)
- result.unpackedSize = fullText.len
- result.sum = toMD5(fullText)
- result.compressed = compress(fullText)
- proc checksumStr*(str: string): TChecksumFile =
- result.unpackedSize = str.len
- result.sum = toMD5(str)
- result.compressed = compress(str)
|