summary refs log tree commit diff stats
path: root/tests/manyloc/keineschweine/lib/client_helpers.nim
blob: 0ebb4ade1106942a18980abb1a4d097172315eb3 (plain) (blame)
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