123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import
- tables, sg_packets, enet, estreams, sg_gui, sfml,
- zlib_helpers, md5, sg_assets, os
- type
- PServer* = ptr TServer
- TServer* = object
- connected*: bool
- addy: enet.TAddress
- host*: PHost
- peer*: PPeer
- handlers*: Table[char, TScPktHandler]
- TScPktHandler* = proc(serv: PServer; buffer: PBuffer)
- TFileTransfer = object
- fileName: string
- assetType: TAssetType
- fullLen: int
- pos: int32
- data: string
- readyToSave: bool
- var
- currentFileTransfer: TFileTransfer
- downloadProgress* = newButton(nil, "", vec2f(0,0), nil)
- currentFileTransfer.data = ""
- proc addHandler*(serv: PServer; packetType: char; handler: TScPktHandler) =
- serv.handlers[packetType] = handler
- proc newServer*(): PServer =
- result = cast[PServer](alloc0(sizeof(TServer)))
- result.connected = false
- result.host = createHost(nil, 1, 2, 0, 0)
- result.handlers = initTable[char, TScPktHandler](32)
- proc connect*(serv: PServer; host: string; port: int16; error: var string): bool =
- if setHost(serv.addy, host) != 0:
- error = "Could not resolve host "
- error.add host
- return false
- serv.addy.port = port.cushort
- serv.peer = serv.host.connect(serv.addy, 2, 0)
- if serv.peer.isNil:
- error = "Could not connect to host "
- error.add host
- return false
- return true
- proc send*[T](serv: PServer; packetType: char; pkt: var T) =
- if serv.connected:
- var b = newBuffer(100)
- b.write packetType
- b.pack pkt
- serv.peer.send(0.cuchar, b, FlagUnsequenced)
- proc sendPubChat*(server: PServer; msg: string) =
- var chat = newCsChat("", msg)
- server.send HChat, chat
- proc handlePackets*(server: PServer; buf: PBuffer) =
- while not buf.atEnd():
- let typ = readChar(buf)
- if server.handlers.hasKey(typ):
- server.handlers[typ](server, buf)
- else:
- break
- proc updateFileProgress*() =
- let progress = currentFileTransfer.pos / currentFileTransfer.fullLen
- downloadProgress.bg.setSize(vec2f(progress * 100, 20))
- downloadProgress.setString($currentFileTransfer.pos & '/' & $currentFileTransfer.fullLen)
- ## HFileTransfer
- proc handleFilePartRecv*(serv: PServer; buffer: PBuffer) =
- var
- f = readScFileTransfer(buffer)
- updateFileProgress()
- if not(f.pos == currentFileTransfer.pos):
- echo "returning early from filepartrecv"
- return ##issues, probably
- if currentFileTransfer.data.len == 0:
- echo "setting current file size"
- currentFileTransfer.data.setLen f.fileSize
- let len = f.data.len
- copymem(
- addr currentFileTransfer.data[f.pos],
- addr f.data[0],
- len)
- currentFileTransfer.pos = f.pos + len.int32
- if currentFileTransfer.pos == f.fileSize: #file should be done, rizzight
- currentFileTransfer.data = uncompress(
- currentFileTransfer.data, currentFileTransfer.fullLen)
- currentFileTransfer.readyToSave = true
- var resp: CsFileChallenge
- resp.checksum = toMD5(currentFileTransfer.data)
- serv.send HFileChallenge, resp
- echo "responded with challenge (ready to save)"
- else:
- var resp = newCsFilepartAck(currentFileTransfer.pos)
- serv.send HFileTransfer, resp
- echo "responded for next part"
- proc saveCurrentFile() =
- if not currentFileTransfer.readyToSave: return
- let
- path = expandPath(currentFileTransfer.assetType, currentFileTransfer.fileName)
- parent = parentDir(path)
- if not dirExists(parent):
- createDir(parent)
- echo("Created dir")
- writeFile path, currentFIleTransfer.data
- echo "Write file"
- ## HChallengeResult
- proc handleFileChallengeResult*(serv: PServer; buffer: PBuffer) =
- var res = readScChallengeResult(buffer).status
- echo "got challnege result: ", res
- if res and currentFileTransfer.readyToSave:
- echo "saving"
- saveCurrentFile()
- else:
- currentFileTransfer.readyToSave = false
- currentFileTransfer.pos = 0
- echo "REsetting current file"
- ## HFileCHallenge
- proc handleFileChallenge*(serv: PServer; buffer: PBuffer) =
- var
- challenge = readScFileChallenge(buffer)
- path = expandPath(challenge)
- resp: CsFileChallenge
- if not fileExists(path):
- resp.needFile = true
- echo "Got file challenge, need file."
- else:
- resp.checksum = toMD5(readFile(path))
- echo "got file challenge, sending sum"
- currentFileTransfer.fileName = challenge.file
- currentFileTransfer.assetType = challenge.assetType
- currentFileTransfer.fullLen = challenge.fullLen.int
- currentFileTransfer.pos = 0
- currentFileTransfer.data.setLen 0
- currentFileTransfer.readyToSave = false
- serv.send HFileChallenge, resp
|