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) {.procvar.} = 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 existsDir(parent): createDir(parent) echo("Created dir") writeFile path, currentFIleTransfer.data echo "Write file" ## HChallengeResult proc handleFileChallengeResult*(serv: PServer; buffer: PBuffer) {.procvar.} = 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) {.procvar.} = var challenge = readScFileChallenge(buffer) path = expandPath(challenge) resp: CsFileChallenge if not existsFile(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