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
|
import enet, sg_packets, estreams, md5, zlib_helpers, client_helpers, strutils,
idgen, sg_assets, tables, os
type
PClient* = ref object
id*: int32
auth*: bool
alias*: string
peer*: PPeer
FileChallengePair* = tuple[challenge: ScFileChallenge; file: TChecksumFile]
PFileChallengeSequence* = ref TFileChallengeSequence
TFileChallengeSequence = object
index: int #which file is active
transfer: ScFileTransfer
file: ptr FileChallengePair
var
clientID = newIdGen[int32]()
myAssets*: seq[FileChallengePair] = @[]
fileChallenges = initTable[int32, PFileChallengeSequence](32)
const FileChunkSize = 256
proc free(client: PClient) =
if client.id != 0:
fileChallenges.del client.id
clientID.del client.id
proc newClient*(): PClient =
new(result, free)
result.id = clientID.next()
result.alias = "billy"
proc `$`*(client: PClient): string =
result = "$1:$2".format(client.id, client.alias)
proc send*[T](client: PClient; pktType: char; pkt: var T) =
var buf = newBuffer(128)
buf.write pktType
buf.pack pkt
discard client.peer.send(0.cuchar, buf, flagReliable)
proc sendMessage*(client: PClient; txt: string) =
var m = newScChat(CSystem, text = txt)
client.send HChat, m
proc sendError*(client: PClient; error: string) =
var m = newScChat(CError, text = error)
client.send HChat, m
proc next*(challenge: PFileChallengeSequence, client: PClient)
proc sendChunk*(challenge: PFileChallengeSequence, client: PClient)
proc startVerifyingFiles*(client: PClient) =
var fcs: PFileChallengeSequence
new(fcs)
fcs.index = -1
fileChallenges[client.id] = fcs
next(fcs, client)
proc next*(challenge: PFileChallengeSequence, client: PClient) =
inc(challenge.index)
if challenge.index >= myAssets.len:
client.sendMessage "You are cleared to enter"
fileChallenges.del client.id
return
else:
echo myAssets.len, "assets"
challenge.file = addr myAssets[challenge.index]
client.send HFileChallenge, challenge.file.challenge # :rolleyes:
echo "sent challenge"
proc sendChunk*(challenge: PFileChallengeSequence, client: PClient) =
let size = min(FileChunkSize, challenge.transfer.fileSize - challenge.transfer.pos)
challenge.transfer.data.setLen size
copyMem(
addr challenge.transfer.data[0],
addr challenge.file.file.compressed[challenge.transfer.pos],
size)
client.send HFileTransfer, challenge.transfer
echo "chunk sent"
proc startSend*(challenge: PFileChallengeSequence, client: PClient) =
challenge.transfer.fileSize = challenge.file.file.compressed.len().int32
challenge.transfer.pos = 0
challenge.transfer.data = ""
challenge.transfer.data.setLen FileChunkSize
challenge.sendChunk(client)
echo "starting xfer"
## HFileTransfer
proc handleFilePartAck*(client: PClient; buffer: PBuffer) =
echo "got filepartack"
var
ftrans = readCsFilepartAck(buffer)
fcSeq = fileChallenges[client.id]
fcSeq.transfer.pos = ftrans.lastPos
fcSeq.sendChunk client
## HFileCHallenge
proc handleFileChallengeResp*(client: PClient; buffer: PBuffer) =
echo "got file challenge resp"
var
fcResp = readCsFileChallenge(buffer)
fcSeq = fileChallenges[client.id]
let index = $(fcSeq.index + 1) / $(myAssets.len)
if fcResp.needFile:
client.sendMessage "Sending file... "&index
fcSeq.startSend(client)
else:
var resp = newScChallengeResult(false)
if fcResp.checksum == fcSeq.file.file.sum: ##client is good
client.sendMessage "Checksum is good. "&index
resp.status = true
client.send HChallengeResult, resp
fcSeq.next(client)
else:
client.sendMessage "Checksum is bad, sending file... "&index
client.send HChallengeResult, resp
fcSeq.startSend(client)
|