229 lines
6.6 KiB
Nim
229 lines
6.6 KiB
Nim
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) =
|
|
discard
|
|
#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.hasKey("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()
|
|
|