added manyloc test suite; --path now relative to project dir if not absolute
This commit is contained in:
parent
4f09794be9
commit
75b508032b
51 changed files with 9286 additions and 5 deletions
228
tests/manyloc/keineschweine/enet_server/enet_client.nim
Normal file
228
tests/manyloc/keineschweine/enet_server/enet_client.nim
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
import enet, strutils,
|
||||
sfml, sfml_colors, sg_gui, input_helpers,
|
||||
math_helpers, sg_packets, estreams, tables,
|
||||
json, sg_assets, client_helpers
|
||||
if enetInit() != 0:
|
||||
quit "Could not initialize ENet"
|
||||
type
|
||||
TClientSettings = object
|
||||
resolution*: TVideoMode
|
||||
offlineFile: string
|
||||
dirserver: tuple[host: string, port: int16]
|
||||
website*: string
|
||||
var
|
||||
clientSettings: TClientSettings
|
||||
event: enet.TEvent
|
||||
bConnected = false
|
||||
runServer = true
|
||||
gui = newGuiContainer()
|
||||
zonelist = newGuiContainer()
|
||||
kc = newKeyClient(setActive = true)
|
||||
clock = newClock()
|
||||
chatBox: PMessageArea
|
||||
chatInput: PTextEntry
|
||||
loginBtn, playBtn: PButton
|
||||
fpsText = newText("", guiFont, 18)
|
||||
connectionButtons: seq[PButton]
|
||||
connectButton: PButton
|
||||
u_alias, u_passwd: PTextEntry
|
||||
dirServer: PServer
|
||||
zone: PServer
|
||||
showZoneList = false
|
||||
myCreds = newScLogin(0, "", "") ##my session token
|
||||
|
||||
proc handleChat(server: PServer; buf: PBuffer) =
|
||||
let msg = readScChat(buf)
|
||||
chatBox.add msg
|
||||
proc handlePlayerLogin(server: PServer; buf: PBuffer) =
|
||||
let login = readScLogin(buf)
|
||||
myCreds = login
|
||||
echo("I am ", $myCreds)
|
||||
|
||||
|
||||
kc.registerHandler MouseLeft, down, proc() =
|
||||
gui.click(input_helpers.getMousePos())
|
||||
|
||||
block:
|
||||
var pos = vec2f(15, 550)
|
||||
chatBox = gui.newMessageArea(pos)
|
||||
pos.y += 20
|
||||
chatInput = gui.newTextEntry("...", pos, proc() =
|
||||
sendPubChat dirServer, chatInput.getText()
|
||||
chatInput.clearText())
|
||||
|
||||
gui.setActive(chatInput)
|
||||
|
||||
proc dispMessage(args: varargs[string, `$`]) =
|
||||
var s = ""
|
||||
for it in items(args):
|
||||
s.add it
|
||||
chatbox.add(s)
|
||||
proc dispMessage(text: string) {.inline.} =
|
||||
chatbox.add(text)
|
||||
proc dispError(text: string) {.inline.} =
|
||||
chatBox.add(newScChat(kind = CError, text = text))
|
||||
|
||||
proc updateButtons() =
|
||||
let conn = dirServer.connected
|
||||
for b in connectionButtons: setEnabled(b, conn)
|
||||
if conn:
|
||||
connectButton.setString "Disconnect"
|
||||
else:
|
||||
connectButton.setString "Connect"
|
||||
|
||||
proc poll(serv: PServer; timeout: cuint = 30) =
|
||||
if serv.isNil or serv.host.isNil: return
|
||||
if serv.connected:
|
||||
while serv.host.hostService(event, timeout) > 0:
|
||||
case event.kind
|
||||
of EvtReceive:
|
||||
var buf = newBuffer(event.packet)
|
||||
|
||||
serv.handlePackets(buf)
|
||||
|
||||
event.packet.destroy()
|
||||
of EvtDisconnect:
|
||||
dispMessage "Disconnected"
|
||||
serv.connected = false
|
||||
event.peer.data = nil
|
||||
updateButtons()
|
||||
of EvtNone: discard
|
||||
else:
|
||||
echo repr(event)
|
||||
else:
|
||||
if serv.host.hostService(event, timeout) > 0 and event.kind == EvtConnect:
|
||||
dispMessage "Connected"
|
||||
serv.connected = true
|
||||
if serv.peer != event.peer:
|
||||
serv.peer = event.peer
|
||||
event.peer.data = serv
|
||||
updateButtons()
|
||||
|
||||
proc tryLogin*(b: PButton) =
|
||||
var login = newCsLogin(
|
||||
alias = u_alias.getText(),
|
||||
passwd = u_passwd.getText())
|
||||
dirServer.send HLogin, login
|
||||
proc tryTransition*(b: PButton) =
|
||||
#zone.writePkt HZoneJoinReq, myCreds
|
||||
proc tryConnect*(b: PButton) =
|
||||
if not dirServer.connected:
|
||||
var error: string
|
||||
if not dirServer.connect(
|
||||
clientSettings.dirServer.host,
|
||||
clientSettings.dirServer.port,
|
||||
error):
|
||||
dispError(error)
|
||||
else:
|
||||
dirServer.peer.disconnect(1)
|
||||
|
||||
proc playOffline*(b: PButton) =
|
||||
var errors: seq[string] = @[]
|
||||
if loadSettingsFromFile(clientSettings.offlineFile, errors):
|
||||
transition()
|
||||
else:
|
||||
dispMessage "Errors reading the file (", clientSettings.offlineFile, "):"
|
||||
for e in errors: dispError(e)
|
||||
|
||||
proc getClientSettings*(): TClientSettings =
|
||||
result = clientSettings
|
||||
|
||||
|
||||
proc lobbyInit*() =
|
||||
var s = json.parseFile("./client_settings.json")
|
||||
clientSettings.offlineFile = "data/"
|
||||
clientSettings.offlineFile.add s["default-file"].str
|
||||
let dirserv = s["directory-server"]
|
||||
clientSettings.dirserver.host = dirserv["host"].str
|
||||
clientSettings.dirserver.port = dirserv["port"].num.int16
|
||||
clientSettings.resolution.width = s["resolution"][0].num.cint
|
||||
clientSettings.resolution.height= s["resolution"][1].num.cint
|
||||
clientSettings.resolution.bitsPerPixel = s["resolution"][2].num.cint
|
||||
clientSettings.website = s["website"].str
|
||||
zonelist.setPosition(vec2f(200.0, 100.0))
|
||||
connectionButtons = @[]
|
||||
|
||||
var pos = vec2f(10, 10)
|
||||
u_alias = gui.newTextEntry(
|
||||
if s.existsKey("alias"): s["alias"].str else: "alias",
|
||||
pos)
|
||||
pos.y += 20
|
||||
u_passwd = gui.newTextEntry("buzz", pos)
|
||||
pos.y += 20
|
||||
connectionButtons.add(gui.newButton(
|
||||
text = "Login",
|
||||
position = pos,
|
||||
onClick = tryLogin,
|
||||
startEnabled = false))
|
||||
pos.y += 20
|
||||
fpsText.setPosition pos
|
||||
pos.y += 20
|
||||
connectButton = gui.newButton(
|
||||
text = "Connect",
|
||||
position = pos,
|
||||
onClick = tryConnect)
|
||||
pos.y += 20
|
||||
gui.newButton("Test Files", position = pos, onClick = proc(b: PButton) =
|
||||
var req = newCsZoneJoinReq(myCreds)
|
||||
dirServer.send HZoneJoinReq, req)
|
||||
pos.y += 20
|
||||
connectionButtons.add(gui.newButton(
|
||||
text = "Test Chat",
|
||||
position = pos,
|
||||
onClick = (proc(b: PButton) =
|
||||
var pkt = newCsChat(text = "ohai")
|
||||
dirServer.send HChat, pkt),
|
||||
startEnabled = false))
|
||||
pos.y += 20
|
||||
downloadProgress.setPosition(pos)
|
||||
downloadProgress.bg.setFillColor(color(34, 139, 34))
|
||||
downloadProgress.bg.setSize(vec2f(0, 0))
|
||||
gui.add(downloadProgress)
|
||||
|
||||
playBtn = gui.newButton(
|
||||
text = "Play",
|
||||
position = vec2f(680.0, 8.0),
|
||||
onClick = tryTransition,
|
||||
startEnabled = false)
|
||||
gui.newButton(
|
||||
text = "Play Offline",
|
||||
position = vec2f(680.0, 28.0),
|
||||
onClick = playOffline)
|
||||
discard """gui.newButton(text = "Scrollback + 1", position = vec2f(185, 10), onClick = proc(b: PButton) =
|
||||
messageArea.scrollBack += 1
|
||||
update(messageArea))
|
||||
gui.newButton(text = "Scrollback - 1", position = vec2f(185+160, 10), onClick = proc(b: PButton) =
|
||||
messageArea.scrollBack -= 1
|
||||
update(messageArea))
|
||||
gui.newButton(text = "Flood msg area", position = vec2f(185, 30), onClick = proc(b: PButton) =
|
||||
for i in 0.. <30:
|
||||
dispMessage($i))"""
|
||||
dirServer = newServer()
|
||||
dirServer.addHandler HChat, handleChat
|
||||
dirServer.addHandler HLogin, handlePlayerLogin
|
||||
dirServer.addHandler HFileTransfer, client_helpers.handleFilePartRecv
|
||||
dirServer.addHandler HChallengeResult, client_helpers.handleFileChallengeResult
|
||||
dirServer.addHandler HFileChallenge, client_helpers.handleFileChallenge
|
||||
|
||||
proc lobbyReady*() =
|
||||
kc.setActive()
|
||||
gui.setActive(u_alias)
|
||||
|
||||
var i = 0
|
||||
proc lobbyUpdate*(dt: float) =
|
||||
dirServer.poll()
|
||||
#let res = disp.poll()
|
||||
gui.update(dt)
|
||||
i = (i + 1) mod 60
|
||||
if i == 0:
|
||||
fpsText.setString("FPS: "& ff(1.0/dt))
|
||||
|
||||
proc lobbyDraw*(window: PRenderWindow) =
|
||||
window.clear(Black)
|
||||
window.draw chatBox
|
||||
window.draw gui
|
||||
window.draw fpsText
|
||||
if showZonelist: window.draw zonelist
|
||||
window.display()
|
||||
|
||||
294
tests/manyloc/keineschweine/enet_server/enet_server.nim
Normal file
294
tests/manyloc/keineschweine/enet_server/enet_server.nim
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
import enet, strutils, idgen, tables, math_helpers,
|
||||
estreams, sg_packets, server_utils, sg_assets, client_helpers
|
||||
when appType == "gui":
|
||||
import sfml, sfml_colors, sg_gui,
|
||||
input_helpers, sfml_stuff
|
||||
else:
|
||||
import times
|
||||
type
|
||||
TCallback = proc(client: PClient; buffer: PBuffer)
|
||||
var
|
||||
server: PHost
|
||||
dirServer: PServer
|
||||
standAloneMode = true
|
||||
event: enet.TEvent
|
||||
clientID = newIDGen[int32]()
|
||||
clients = initTable[int32, PClient](64)
|
||||
handlers = initTable[char, TCallback](32)
|
||||
|
||||
when appType == "gui":
|
||||
var
|
||||
gui = newGuiContainer()
|
||||
chatBox = gui.newMessageArea(vec2f(15, 550))
|
||||
window = newRenderWindow(videoMode(800, 600, 32), "Sup yo", sfDefaultSTyle)
|
||||
mousepos = newText("", guiFont, 16)
|
||||
fpsText = mousePos.copy()
|
||||
inputClient = newKeyClient(setActive = true)
|
||||
chatBox.sizeVisible = 30
|
||||
mousePos.setColor(Green)
|
||||
fpsText.setposition(vec2f(0, 20))
|
||||
inputClient.registerHandler MouseLeft, down, proc() =
|
||||
gui.click(input_helpers.getMousePos())
|
||||
inputClient.registerHandler MouseMiddle, down, proc() =
|
||||
let pos = input_helpers.getMousePos()
|
||||
mousePos.setString("($1,$2)".format(ff(pos.x), ff(pos.y)))
|
||||
mousePos.setPosition(pos)
|
||||
proc dispMessage(args: varargs[string, `$`]) =
|
||||
var s = ""
|
||||
for it in items(args):
|
||||
s.add it
|
||||
chatbox.add(s)
|
||||
proc dispError(args: varargs[string, `$`]) =
|
||||
var s = ""
|
||||
for it in items(args): s.add(it)
|
||||
chatBox.add(newScChat(kind = CError, text = s))
|
||||
else:
|
||||
proc dispMessage(args: varargs[string, `$`]) =
|
||||
var m = ""
|
||||
for it in items(args): m.add(it)
|
||||
echo "<msg> ", m
|
||||
proc dispError(args: varargs[string, `$`]) =
|
||||
var m = ""
|
||||
for it in items(args): m.add(it)
|
||||
echo "**", m
|
||||
|
||||
|
||||
var pubChatQueue = newBuffer(1024)
|
||||
proc queuePub(sender: PClient, msg: CsChat) =
|
||||
var chat = newScChat(kind = CPub, fromPlayer = sender.alias, text = msg.text)
|
||||
pubChatQueue.write(HChat)
|
||||
pubChatQueue.pack(chat)
|
||||
proc flushPubChat() =
|
||||
if pubChatQueue.isDirty:
|
||||
let packet = pubChatQueue.toPacket(FlagReliable)
|
||||
for id, client in pairs(clients):
|
||||
discard client.peer.send(0.cuchar, packet)
|
||||
pubChatQueue.flush()
|
||||
|
||||
handlers[HChat] = proc(client: PClient; buffer: PBuffer) =
|
||||
var chat = readCsChat(buffer)
|
||||
|
||||
if not client.auth:
|
||||
client.sendError("You are not logged in.")
|
||||
return
|
||||
#if chat.target != "": ##private
|
||||
# if alias2client.hasKey(chat.target):
|
||||
# alias2client[chat.target].forwardPrivate(client, chat.text)
|
||||
#else:
|
||||
|
||||
dispmessage("<", client.alias, "> ", chat.text)
|
||||
queuePub(client, chat)
|
||||
|
||||
handlers[HLogin] = proc(client: PClient; buffer: PBuffer) =
|
||||
var info = readCsLogin(buffer)
|
||||
if client.auth:
|
||||
client.sendError "You are already logged in."
|
||||
return
|
||||
client.alias = info.alias
|
||||
client.auth = true
|
||||
var resp = newScLogin(client.id, client.alias, "sessionkeylulz")
|
||||
client.send HLogin, resp
|
||||
client.sendMessage "welcome"
|
||||
dispMessage("Client logged in: ", client)
|
||||
|
||||
|
||||
handlers[HFileTransfer] = server_utils.handleFilePartAck
|
||||
handlers[HFileChallenge] = server_utils.handleFileChallengeResp
|
||||
|
||||
handlers[HZoneJoinReq] = proc(client: PClient; buffer: PBuffer) =
|
||||
var info = readCsZoneJoinReq(buffer)
|
||||
dispmessage "Got zone join request"
|
||||
client.startVerifyingFiles()
|
||||
|
||||
|
||||
|
||||
when isMainModule:
|
||||
import parseopt, matchers, os, json
|
||||
|
||||
|
||||
if enetInit() != 0:
|
||||
quit "Could not initialize ENet"
|
||||
|
||||
var address: enet.TAddress
|
||||
|
||||
block:
|
||||
var zoneCfgFile = "./server_settings.json"
|
||||
for kind, key, val in getOpt():
|
||||
case kind
|
||||
of cmdShortOption, cmdLongOption:
|
||||
case key
|
||||
of "f", "file":
|
||||
if existsFile(val):
|
||||
zoneCfgFile = val
|
||||
else:
|
||||
echo("File does not exist: ", val)
|
||||
else:
|
||||
echo("Unknown option: ", key," ", val)
|
||||
else:
|
||||
echo("Unknown option: ", key, " ", val)
|
||||
var jsonSettings = parseFile(zoneCfgFile)
|
||||
let
|
||||
port = uint16(jsonSettings["port"].num)
|
||||
zoneFile = jsonSettings["settings"].str
|
||||
dirServerInfo = jsonSettings["dirserver"]
|
||||
|
||||
address.host = EnetHostAny
|
||||
address.port = port
|
||||
|
||||
var path = getAppDir()/../"data"/zoneFile
|
||||
if not existsFile(path):
|
||||
echo("Zone settings file does not exist: ../data/", zoneFile)
|
||||
echo(path)
|
||||
quit(1)
|
||||
|
||||
discard """block:
|
||||
var
|
||||
TestFile: FileChallengePair
|
||||
contents = repeatStr(2, "abcdefghijklmnopqrstuvwxyz")
|
||||
testFile.challenge = newScFileChallenge("foobar.test", FZoneCfg, contents.len.int32)
|
||||
testFile.file = checksumStr(contents)
|
||||
myAssets.add testFile"""
|
||||
|
||||
setCurrentDir getAppDir().parentDir()
|
||||
let zonesettings = readFile(path)
|
||||
var
|
||||
errors: seq[string] = @[]
|
||||
if not loadSettings(zoneSettings, errors):
|
||||
echo("You have errors in your zone settings:")
|
||||
for e in errors: echo("**", e)
|
||||
quit(1)
|
||||
errors.setLen 0
|
||||
|
||||
var pair: FileChallengePair
|
||||
pair.challenge.file = zoneFile
|
||||
pair.challenge.assetType = FZoneCfg
|
||||
pair.challenge.fullLen = zoneSettings.len.int32
|
||||
pair.file = checksumStr(zoneSettings)
|
||||
myAssets.add pair
|
||||
|
||||
allAssets:
|
||||
if not load(asset):
|
||||
echo "Invalid or missing file ", file
|
||||
else:
|
||||
var pair: FileChallengePair
|
||||
pair.challenge.file = file
|
||||
pair.challenge.assetType = assetType
|
||||
pair.challenge.fullLen = getFileSize(
|
||||
expandPath(assetType, file)).int32
|
||||
pair.file = asset.contents
|
||||
myAssets.add pair
|
||||
|
||||
echo "Zone has ", myAssets.len, " associated assets"
|
||||
|
||||
dirServer = newServer()
|
||||
|
||||
dirServer.addHandler HDsMsg, proc(serv: PServer; buffer: PBuffer) =
|
||||
var m = readDsMsg(buffer)
|
||||
dispMessage("<DirServer> ", m.msg)
|
||||
dirServer.addHandler HZoneLogin, proc(serv: PServer; buffer: PBuffer) =
|
||||
let loggedIn = readDsZoneLogin(buffer).status
|
||||
if loggedIn:
|
||||
#dirServerConnected = true
|
||||
|
||||
if dirServerInfo.kind == JArray:
|
||||
var error: string
|
||||
if not dirServer.connect(dirServerInfo[0].str, dirServerInfo[1].num.int16, error):
|
||||
dispError("<DirServer> "&error)
|
||||
|
||||
|
||||
server = enet.createHost(address, 32, 2, 0, 0)
|
||||
if server == nil:
|
||||
quit "Could not create the server!"
|
||||
|
||||
dispMessage("Listening on port ", address.port)
|
||||
|
||||
var
|
||||
serverRunning = true
|
||||
when appType == "gui":
|
||||
var frameRate = newClock()
|
||||
var pubChatDelay = newClock()
|
||||
else:
|
||||
var frameRate = epochTime()
|
||||
var pubChatDelay = frameRate
|
||||
|
||||
while serverRunning:
|
||||
when appType == "gui":
|
||||
let dt = frameRate.restart.asMilliseconds().float / 1000.0
|
||||
|
||||
for event in window.filterEvents():
|
||||
case event.kind
|
||||
of sfml.EvtClosed:
|
||||
window.close()
|
||||
serverRunning = false
|
||||
else:
|
||||
discard
|
||||
else:
|
||||
let dt = epochTime() - frameRate ##is this right? probably not
|
||||
frameRate = epochTime()
|
||||
|
||||
while server.hostService(event, 10) > 0:
|
||||
case event.kind
|
||||
of EvtConnect:
|
||||
var client = newClient()
|
||||
clients[client.id] = client
|
||||
|
||||
event.peer.data = addr client.id
|
||||
client.peer = event.peer
|
||||
|
||||
dispMessage("New client connected ", client)
|
||||
|
||||
var
|
||||
msg = "hello"
|
||||
resp = createPacket(cstring(msg), msg.len + 1, FlagReliable)
|
||||
|
||||
if event.peer.send(0.cuchar, resp) < 0:
|
||||
echo "FAILED"
|
||||
else:
|
||||
echo "Replied"
|
||||
of EvtReceive:
|
||||
let client = clients[cast[ptr int32](event.peer.data)[]]
|
||||
|
||||
var buf = newBuffer(event.packet)
|
||||
let k = buf.readChar()
|
||||
if handlers.hasKey(k):
|
||||
handlers[k](client, buf)
|
||||
else:
|
||||
dispError("Unknown packet from ", client)
|
||||
|
||||
destroy(event.packet)
|
||||
of EvtDisconnect:
|
||||
var
|
||||
id = cast[ptr int32](event.peer.data)[]
|
||||
client = clients[id]
|
||||
if client.isNil:
|
||||
disperror("CLIENT IS NIL!")
|
||||
dispmessage(event.peer.data.isNil)
|
||||
else:
|
||||
dispMessage(clients[id], " disconnected")
|
||||
GCUnref(clients[id])
|
||||
clients.del id
|
||||
|
||||
event.peer.data = nil
|
||||
else:
|
||||
discard
|
||||
|
||||
when appType == "gui":
|
||||
fpsText.setString(ff(1.0/dt))
|
||||
if pubChatDelay.getElapsedTime.asSeconds > 0.25:
|
||||
pubChatDelay.restart()
|
||||
flushPubChat()
|
||||
else:
|
||||
pubChatDelay -= dt
|
||||
if frameRate - pubChatDelay > 0.25:
|
||||
flushPubChat()
|
||||
|
||||
when appType == "gui":
|
||||
window.clear(Black)
|
||||
window.draw(GUI)
|
||||
window.draw chatbox
|
||||
window.draw mousePos
|
||||
window.draw fpstext
|
||||
window.display()
|
||||
|
||||
server.destroy()
|
||||
enetDeinit()
|
||||
13
tests/manyloc/keineschweine/enet_server/nakefile.nim
Normal file
13
tests/manyloc/keineschweine/enet_server/nakefile.nim
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import nake
|
||||
nakeimports
|
||||
|
||||
const
|
||||
ServerDefines = "-d:NoSFML --forceBuild"
|
||||
|
||||
task "server", "build the server":
|
||||
if shell("nimrod", ServerDefines, "-r", "compile", "enet_server") != 0:
|
||||
quit "Failed to build"
|
||||
task "gui", "build the server GUI mode":
|
||||
if shell("nimrod", "--app:gui", ServerDefines, "-r", "compile", "enet_server") != 0:
|
||||
quit "Failed to build"
|
||||
|
||||
9
tests/manyloc/keineschweine/enet_server/nimrod.cfg
Normal file
9
tests/manyloc/keineschweine/enet_server/nimrod.cfg
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
path = ".."
|
||||
path = "../dependencies/sfml"
|
||||
path = "../dependencies/enet"
|
||||
path = "../dependencies/nake"
|
||||
path = "../dependencies/genpacket"
|
||||
path = "../lib"
|
||||
define = "noChipmunk"
|
||||
define = "noSFML"
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "Alpha Zone",
|
||||
"desc": "Beta Testing",
|
||||
"host": "localhost",
|
||||
"port": 8024,
|
||||
"settings": "alphazone.json",
|
||||
"dirserver":["localhost",2049,"alphazone","skittles"]
|
||||
}
|
||||
120
tests/manyloc/keineschweine/enet_server/server_utils.nim
Normal file
120
tests/manyloc/keineschweine/enet_server/server_utils.nim
Normal file
|
|
@ -0,0 +1,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)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue