1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
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
|