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
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go
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