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
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"network":"lamenet",
|
||||
"port":2049,
|
||||
"zones":[
|
||||
{"name":"alphazone","key":"skittles"}
|
||||
]
|
||||
}
|
||||
6
tests/manyloc/keineschweine/server/nimrod.cfg
Normal file
6
tests/manyloc/keineschweine/server/nimrod.cfg
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
debugger = off
|
||||
deadCodeElim = on
|
||||
path = ".."
|
||||
path = "../genpacket"
|
||||
path = "../helpers"
|
||||
define = NoSFML
|
||||
201
tests/manyloc/keineschweine/server/old_dirserver.nim
Normal file
201
tests/manyloc/keineschweine/server/old_dirserver.nim
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
## directory server
|
||||
## handles client authorization and assets
|
||||
|
||||
import
|
||||
sockets, times, streams, streams_enh, tables, json, os,
|
||||
sg_packets, sg_assets, md5, server_utils, map_filter
|
||||
type
|
||||
THandler = proc(client: PCLient; stream: PStream)
|
||||
var
|
||||
server: TSocket
|
||||
handlers = initTable[char, THandler](16)
|
||||
thisZone = newScZoneRecord("local", "sup")
|
||||
zoneList = newScZoneList()
|
||||
thisZoneSettings: string
|
||||
zoneSlots: seq[tuple[name: string; key: string]] = @[]
|
||||
zones: seq[PClient] = @[]
|
||||
## I was high.
|
||||
clients = initTable[TupAddress, PClient](16)
|
||||
alias2client = initTable[string, PClient](32)
|
||||
allClients: seq[PClient] = @[]
|
||||
|
||||
proc findClient*(host: string; port: int16): PClient =
|
||||
let addy: TupAddress = (host, port)
|
||||
if clients.hasKey(addy):
|
||||
return clients[addy]
|
||||
result = newClient(addy)
|
||||
clients[addy] = result
|
||||
allClients.add(result)
|
||||
|
||||
proc loginZone(client: PClient; login: SdZoneLogin): bool =
|
||||
if not client.auth:
|
||||
for s in zoneSlots.items:
|
||||
if s.name == login.name and s.key == login.key:
|
||||
client.auth = true
|
||||
client.kind = CServer
|
||||
client.record = login.record
|
||||
result = true
|
||||
break
|
||||
|
||||
proc sendZoneList(client: PClient) =
|
||||
echo(">> zonelist ", client, ' ', HZoneList)
|
||||
client.send(HZonelist, zonelist)
|
||||
proc forwardPrivate(rcv: PClient; sender: PClient; txt: string) =
|
||||
var m = newScChat(CPriv, sender.alias, txt)
|
||||
rcv.send(HChat, m)
|
||||
proc sendChat(client: PClient; kind: ChatType; txt: string) =
|
||||
echo(">> chat ", client)
|
||||
var m = newScChat(kind, "", txt)
|
||||
client.send(HChat, m)
|
||||
|
||||
|
||||
|
||||
var pubChatQueue = newIncomingBuffer()
|
||||
proc queuePub(sender: string, msg: CsChat) =
|
||||
var chat = newScChat(kind = CPub, fromPlayer = sender, text = msg.text)
|
||||
pubChatQueue.write(HChat)
|
||||
chat.pack(pubChatQueue)
|
||||
|
||||
handlers[HHello] = (proc(client: PClient; stream: PStream) =
|
||||
var h = readCsHello(stream)
|
||||
if h.i == 14:
|
||||
var greet = newScHello("Well hello there")
|
||||
client.send(HHello, greet))
|
||||
handlers[HLogin] = proc(client: PClient; stream: PStream) =
|
||||
var loginInfo = readCsLogin(stream)
|
||||
echo("** login: alias = ", loginInfo.alias)
|
||||
if alias2client.hasKey(loginInfo.alias):
|
||||
client.sendError("Alias in use.")
|
||||
return
|
||||
if client.loginPlayer(loginInfo):
|
||||
alias2client[client.alias] = client
|
||||
client.sendMessage("Welcome "& client.alias)
|
||||
var session = newScLogin(client.id, client.alias, client.session)
|
||||
client.send HLogin, session
|
||||
client.sendZonelist()
|
||||
|
||||
handlers[HZoneList] = proc(client: PClient; stream: PStream) =
|
||||
var pinfo = readCsZoneList(stream)
|
||||
echo("** zonelist req")
|
||||
sendZoneList client
|
||||
handlers[HChat] = proc(client: PClient; stream: PStream) =
|
||||
var chat = readCsChat(stream)
|
||||
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:
|
||||
queuePub(client.alias, chat)
|
||||
|
||||
proc sendServMsg(client: PClient; msg: string) =
|
||||
var m = newDsMsg(msg)
|
||||
client.send HDsMsg, m
|
||||
handlers[HZoneLogin] = proc(client: PClient; stream: PStream) =
|
||||
var
|
||||
login = readSdZoneLogin(stream)
|
||||
if not client.loginZone(login):
|
||||
client.sendServMsg "Invalid login"
|
||||
else:
|
||||
client.sendServMsg "Welcome to the servers"
|
||||
echo "** Zone logged in: ", login
|
||||
zones.add client
|
||||
zonelist.zones.add client.record
|
||||
|
||||
|
||||
handlers[HFileChallenge] = proc(client: PClient; stream: PStream) =
|
||||
if client.auth:
|
||||
if client.kind == CServer:
|
||||
var chg = readScFileChallenge(stream)
|
||||
|
||||
proc handlePkt(s: PClient; stream: PStream) =
|
||||
while not stream.atEnd:
|
||||
var typ = readChar(stream)
|
||||
if not handlers.hasKey(typ):
|
||||
break
|
||||
else:
|
||||
handlers[typ](s, stream)
|
||||
|
||||
proc createServer(port: TPort) =
|
||||
if not server.isNil:
|
||||
server.close()
|
||||
server = socket(typ = SOCK_DGRAM, protocol = IPPROTO_UDP, buffered = false)
|
||||
server.bindAddr(port)
|
||||
|
||||
|
||||
var clientIndex = 0
|
||||
var incoming = newIncomingBuffer()
|
||||
proc poll*(timeout: int = 250) =
|
||||
if server.isNil: return
|
||||
var
|
||||
reads = @[server]
|
||||
writes = @[server]
|
||||
if select(reads, timeout) > 0:
|
||||
var
|
||||
addy = ""
|
||||
port: TPort
|
||||
incoming.data.setLen 512
|
||||
let res = server.recvFromAsync(incoming.data, 512, addy, port, 0)
|
||||
if not res:
|
||||
echo("No recv")
|
||||
return
|
||||
else:
|
||||
var client = findClient(addy, port.int16)
|
||||
echo "<< ", res, " ", client, ": ", len(incoming.data), " ", repr(incoming.data)
|
||||
handlePkt(client, incoming)
|
||||
incoming.flush()
|
||||
if selectWrite(writes, timeout) > 0:
|
||||
let nclients = allClients.len
|
||||
if nclients == 0:
|
||||
return
|
||||
clientIndex = (clientIndex + 1) mod nclients
|
||||
var c = allClients[clientIndex]
|
||||
if c.outputBuf.getPosition > 0:
|
||||
let res = server.sendTo(c.addy.host, c.addy.port.TPort, c.outputBuf.data)
|
||||
echo("Write ", c, " result: ", res, " data: ", repr(c.outputBuf.data))
|
||||
c.outputBuf.flush()
|
||||
|
||||
when isMainModule:
|
||||
import parseopt, matchers, strutils
|
||||
var cfgFile = "dirserver_settings.json"
|
||||
for kind, key, val in getOpt():
|
||||
case kind
|
||||
of cmdShortOption, cmdLongOption:
|
||||
case key
|
||||
of "f", "file":
|
||||
if existsFile(val):
|
||||
cfgFile = val
|
||||
else:
|
||||
echo("File does not exist: ", val)
|
||||
else:
|
||||
echo("Unknown option: ", key," ", val)
|
||||
else:
|
||||
echo("Unknown option: ", key, " ", val)
|
||||
var jsonSettings = parseFile(cfgFile)
|
||||
let port = TPort(jsonSettings["port"].num)
|
||||
zonelist.network = jsonSettings["network"].str
|
||||
for slot in jsonSettings["zones"].items:
|
||||
zoneSlots.add((slot["name"].str, slot["key"].str))
|
||||
|
||||
createServer(port)
|
||||
echo("Listening on port ", port, "...")
|
||||
var pubChatTimer = cpuTime() #newClock()
|
||||
const PubChatDelay = 1000/1000
|
||||
while true:
|
||||
poll(15)
|
||||
## TODO sort this type of thing VV into a queue api
|
||||
if cpuTime() - pubChatTimer > PubChatDelay: #.getElapsedTime.asMilliseconds > 100:
|
||||
pubChatTimer -= pubChatDelay
|
||||
if pubChatQueue.getPosition > 0:
|
||||
var cn = 0
|
||||
let sizePubChat = pubChatQueue.data.len
|
||||
var sent = 0
|
||||
filterIt2(allClients, it.auth == true and it.kind == CPlayer):
|
||||
it.outputBuf.writeData(addr pubChatQueue.data[0], sizePubChat)
|
||||
sent += 1
|
||||
#for c in allClients:
|
||||
# c.outputBuf.writeData(addr pubChatQueue.data[0], sizePubChat)
|
||||
pubChatQueue.flush()
|
||||
echo "pubChatQueue flushed to ", sent, "clients"
|
||||
|
||||
98
tests/manyloc/keineschweine/server/old_server_utils.nim
Normal file
98
tests/manyloc/keineschweine/server/old_server_utils.nim
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import
|
||||
streams, md5, sockets, unsigned,
|
||||
sg_packets, zlib_helpers, idgen
|
||||
type
|
||||
TClientType* = enum
|
||||
CServer = 0'i8, CPlayer, CUnknown
|
||||
PClient* = ref TClient
|
||||
TClient* = object of TObject
|
||||
id*: int32
|
||||
addy*: TupAddress
|
||||
clientID*: uint16
|
||||
auth*: bool
|
||||
outputBuf*: PStringStream
|
||||
case kind*: TClientType
|
||||
of CPlayer:
|
||||
alias*: string
|
||||
session*: string
|
||||
lastPing*: float
|
||||
failedPings*: int
|
||||
of CServer:
|
||||
record*: ScZoneRecord
|
||||
cfg*: TChecksumFile
|
||||
of CUnknown: nil
|
||||
TChecksumFile* = object
|
||||
unpackedSize*: int
|
||||
sum*: MD5Digest
|
||||
compressed*: string
|
||||
TupAddress* = tuple[host: string, port: int16]
|
||||
PIDGen*[T: Ordinal] = ref TIDGen[T]
|
||||
TIDGen[T: Ordinal] = object
|
||||
max: T
|
||||
freeIDs: seq[T]
|
||||
var cliID = newIdGen[int32]()
|
||||
|
||||
proc sendMessage*(client: PClient; txt: string)
|
||||
proc sendError*(client: PClient; txt: string)
|
||||
proc `$`*(client: PClient): string
|
||||
|
||||
proc newIncomingBuffer*(size = 1024): PStringStream =
|
||||
result = newStringStream("")
|
||||
result.data.setLen size
|
||||
result.data.setLen 0
|
||||
result.flushImpl = proc(stream: PStream) =
|
||||
stream.setPosition(0)
|
||||
PStringStream(stream).data.setLen(0)
|
||||
|
||||
|
||||
proc free*(c: PClient) =
|
||||
echo "Client freed: ", c
|
||||
cliID.del c.id
|
||||
c.outputBuf.flush()
|
||||
c.outputBuf = nil
|
||||
proc newClient*(addy: TupAddress): PClient =
|
||||
new(result, free)
|
||||
result.addy = addy
|
||||
result.outputBuf = newStringStream("")
|
||||
result.outputBuf.flushImpl = proc(stream: PStream) =
|
||||
stream.setPosition 0
|
||||
PStringStream(stream).data.setLen 0
|
||||
|
||||
proc loginPlayer*(client: PClient; login: CsLogin): bool =
|
||||
if client.auth:
|
||||
client.sendError("You are already logged in.")
|
||||
return
|
||||
client.id = cliID.next()
|
||||
client.auth = true
|
||||
client.kind = CPlayer
|
||||
client.alias = login.alias
|
||||
client.session = getMD5(client.alias & $rand(10000))
|
||||
result = true
|
||||
|
||||
proc `$`*(client: PClient): string =
|
||||
if not client.auth: return $client.addy
|
||||
case client.kind
|
||||
of CPlayer: result = client.alias
|
||||
of CServer: result = client.record.name
|
||||
else: result = $client.addy
|
||||
proc send*[T](client: PClient; pktType: char; pkt: var T) =
|
||||
client.outputBuf.write(pktType)
|
||||
pkt.pack(client.outputBuf)
|
||||
|
||||
proc sendMessage*(client: PClient; txt: string) =
|
||||
var m = newScChat(CSystem, text = txt)
|
||||
client.send HChat, m
|
||||
proc sendError*(client: PClient; txt: string) =
|
||||
var m = newScChat(CError, text = txt)
|
||||
client.send HChat, m
|
||||
|
||||
proc checksumFile*(filename: string): TChecksumFile =
|
||||
let fullText = readFile(filename)
|
||||
result.unpackedSize = fullText.len
|
||||
result.sum = toMD5(fullText)
|
||||
result.compressed = compress(fullText)
|
||||
proc checksumStr*(str: string): TChecksumFile =
|
||||
result.unpackedSize = str.len
|
||||
result.sum = toMD5(str)
|
||||
result.compressed = compress(str)
|
||||
|
||||
254
tests/manyloc/keineschweine/server/old_sg_server.nim
Normal file
254
tests/manyloc/keineschweine/server/old_sg_server.nim
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
import
|
||||
sockets, times, streams, streams_enh, tables, json, os, unsigned,
|
||||
sg_packets, sg_assets, md5, server_utils, client_helpers
|
||||
var
|
||||
dirServer: PServer
|
||||
thisZone = newScZoneRecord("local", "sup")
|
||||
thisZoneSettings: PZoneSettings
|
||||
dirServerConnected = false
|
||||
## I was high.
|
||||
clients = initTable[TupAddress, PClient](16)
|
||||
alias2client = initTable[string, PClient](32)
|
||||
allClients: seq[PClient] = @[]
|
||||
zonePlayers: seq[PClient] = @[]
|
||||
const
|
||||
PubChatDelay = 100/1000 #100 ms
|
||||
|
||||
import hashes
|
||||
proc hash*(x: uint16): THash {.inline.} =
|
||||
result = int32(x)
|
||||
|
||||
proc findClient*(host: string; port: int16): PClient =
|
||||
let addy: TupAddress = (host, port)
|
||||
if clients.hasKey(addy):
|
||||
return clients[addy]
|
||||
result = newClient(addy)
|
||||
clients[addy] = result
|
||||
allClients.add(result)
|
||||
|
||||
|
||||
proc sendZoneList(client: PClient) =
|
||||
echo(">> zonelist ", client)
|
||||
#client.send(HZonelist, zonelist)
|
||||
|
||||
proc forwardPrivate(rcv: PClient; sender: PClient; txt: string) =
|
||||
var m = newScChat(CPriv, sender.alias, txt)
|
||||
rcv.send(HChat, m)
|
||||
proc sendChat(client: PClient; kind: ChatType; txt: string) =
|
||||
echo(">> chat ", client)
|
||||
var m = newScChat(kind, "", txt)
|
||||
client.send(HChat, m)
|
||||
|
||||
var pubChatQueue = newStringStream("")
|
||||
pubChatQueue.flushImpl = proc(stream: PStream) =
|
||||
stream.setPosition(0)
|
||||
PStringStream(stream).data.setLen(0)
|
||||
proc queuePub(sender: string, msg: CsChat) =
|
||||
var chat = newScChat(kind = CPub, fromPlayer = sender, text = msg.text)
|
||||
pubChatQueue.write(HChat)
|
||||
chat.pack(pubChatQueue)
|
||||
|
||||
handlers[HHello] = (proc(client: PClient; stream: PStream) =
|
||||
var h = readCsHello(stream)
|
||||
if h.i == 14:
|
||||
var greet = newScHello("Well hello there")
|
||||
client.send(HHello, greet))
|
||||
handlers[HLogin] = proc(client: PClient; stream: PStream) =
|
||||
var loginInfo = readCsLogin(stream)
|
||||
echo("** login: alias = ", loginInfo.alias)
|
||||
if not dirServerConnected and client.loginPlayer(loginInfo):
|
||||
client.sendMessage("Welcome "& client.alias)
|
||||
alias2client[client.alias] = client
|
||||
client.sendZonelist()
|
||||
handlers[HZoneList] = proc(client: PClient; stream: PStream) =
|
||||
var pinfo = readCsZoneList(stream)
|
||||
echo("** zonelist req")
|
||||
handlers[HChat] = proc(client: PClient; stream: PStream) =
|
||||
var chat = readCsChat(stream)
|
||||
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:
|
||||
queuePub(client.alias, chat)
|
||||
handlers[HZoneQuery] = proc(client: PClient; stream: PStream) =
|
||||
echo("Got zone query")
|
||||
var q = readCsZoneQuery(stream)
|
||||
var resp = newScZoneQuery(zonePlayers.len.uint16)
|
||||
client.send(HZoneQuery, resp)
|
||||
|
||||
|
||||
|
||||
handlers[HZoneJoinReq] = proc(client: PClient; stream: PStream) =
|
||||
var req = readCsZoneJoinReq(stream)
|
||||
echo "Join zone request from (",req.session.id,") ", req.session.alias
|
||||
if client.auth and client.kind == CPlayer:
|
||||
echo "Client is authenticated, verifying filez"
|
||||
client.startVerifyingFiles()
|
||||
elif dirServerConnected:
|
||||
echo "Dirserver is connected, verifying client"
|
||||
dirServer.send HVerifyClient, req.session
|
||||
else:
|
||||
echo "Dirserver is disconnected =("
|
||||
client.startVerifyingFiles()
|
||||
|
||||
|
||||
|
||||
proc handlePkt(s: PClient; stream: PStream) =
|
||||
while not stream.atEnd:
|
||||
var typ = readChar(stream)
|
||||
if not handlers.hasKey(typ):
|
||||
break
|
||||
else:
|
||||
handlers[typ](s, stream)
|
||||
|
||||
proc createServer(port: TPort) =
|
||||
if not server.isNil:
|
||||
server.close()
|
||||
server = socket(typ = SOCK_DGRAM, protocol = IPPROTO_UDP, buffered = false)
|
||||
server.bindAddr(port)
|
||||
|
||||
var clientIndex = 0
|
||||
var incoming = newIncomingBuffer()
|
||||
proc poll*(timeout: int = 250) =
|
||||
if server.isNil: return
|
||||
var
|
||||
reads = @[server]
|
||||
writes = @[server]
|
||||
if select(reads, timeout) > 0:
|
||||
var
|
||||
addy = ""
|
||||
port: TPort
|
||||
let res = server.recvFromAsync(incoming.data, 512, addy, port, 0)
|
||||
if not res:
|
||||
echo("No recv")
|
||||
return
|
||||
else:
|
||||
var client = findClient(addy, port.int16)
|
||||
#echo("<< ", res, " ", client.alias, ": ", len(line.data), " ", repr(line.data))
|
||||
handlePkt(client, incoming)
|
||||
incoming.flush()
|
||||
if selectWrite(writes, timeout) > 0:
|
||||
let nclients = allClients.len
|
||||
if nclients == 0:
|
||||
return
|
||||
clientIndex = (clientIndex + 1) mod nclients
|
||||
var c = allClients[clientIndex]
|
||||
if c.outputBuf.getPosition > 0:
|
||||
let res = server.sendTo(c.addy.host, c.addy.port.TPort, c.outputBuf.data)
|
||||
echo("Write ", c, " result: ", res, " data: ", c.outputBuf.data)
|
||||
c.outputBuf.flush()
|
||||
|
||||
when isMainModule:
|
||||
import parseopt, matchers, strutils
|
||||
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
|
||||
host = jsonSettings["host"].str
|
||||
port = TPort(jsonSettings["port"].num)
|
||||
zoneFile = jsonSettings["settings"].str
|
||||
dirServerInfo = jsonSettings["dirserver"]
|
||||
|
||||
var path = getAppDir()/../"data"/zoneFile
|
||||
if not existsFile(path):
|
||||
echo("Zone settings file does not exist: ../data/", zoneFile)
|
||||
echo(path)
|
||||
quit(1)
|
||||
|
||||
## Test file
|
||||
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()
|
||||
block:
|
||||
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 = newServerConnection(dirServerInfo[0].str, dirServerInfo[1].num.TPort)
|
||||
dirServer.handlers[HDsMsg] = proc(serv: PServer; stream: PStream) =
|
||||
var m = readDsMsg(stream)
|
||||
echo("DirServer> ", m.msg)
|
||||
dirServer.handlers[HZoneLogin] = proc(serv: PServer; stream: PStream) =
|
||||
let loggedIn = readDsZoneLogin(stream).status
|
||||
if loggedIn:
|
||||
dirServerConnected = true
|
||||
dirServer.writePkt HZoneLogin, login
|
||||
|
||||
thisZone.name = jsonSettings["name"].str
|
||||
thisZone.desc = jsonSettings["desc"].str
|
||||
thisZone.ip = "localhost"
|
||||
thisZone.port = port
|
||||
var login = newSdZoneLogin(
|
||||
dirServerInfo[2].str, dirServerInfo[3].str,
|
||||
thisZone)
|
||||
#echo "MY LOGIN: ", $login
|
||||
|
||||
|
||||
|
||||
createServer(port)
|
||||
echo("Listening on port ", port, "...")
|
||||
var pubChatTimer = cpuTime()#newClock()
|
||||
while true:
|
||||
discard dirServer.pollServer(15)
|
||||
poll(15)
|
||||
## TODO sort this type of thing VV into a queue api
|
||||
#let now = cpuTime()
|
||||
if cpuTime() - pubChatTimer > PubChatDelay: #.getElapsedTime.asMilliseconds > 100:
|
||||
pubChatTimer -= pubChatDelay #.restart()
|
||||
if pubChatQueue.getPosition > 0:
|
||||
var cn = 0
|
||||
let sizePubChat = pubChatQueue.data.len
|
||||
for c in allClients:
|
||||
c.outputBuf.writeData(addr pubChatQueue.data[0], sizePubChat)
|
||||
pubChatQueue.flush()
|
||||
|
||||
|
||||
|
||||
267
tests/manyloc/keineschweine/server/sg_lobby.nim
Normal file
267
tests/manyloc/keineschweine/server/sg_lobby.nim
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
|
||||
import
|
||||
sockets, streams, tables, times, math, strutils, json, os, md5,
|
||||
sfml, sfml_vector, sfml_colors,
|
||||
streams_enh, input_helpers, zlib_helpers, client_helpers, sg_packets, sg_assets, sg_gui
|
||||
type
|
||||
TClientSettings = object
|
||||
resolution*: TVideoMode
|
||||
offlineFile: string
|
||||
dirserver: tuple[host: string, port: TPort]
|
||||
website*: string
|
||||
var
|
||||
clientSettings: TClientSettings
|
||||
gui = newGuiContainer()
|
||||
zonelist = newGuiContainer()
|
||||
u_alias, u_passwd: PTextEntry
|
||||
activeInput = 0
|
||||
aliasText, passwdText: PText
|
||||
fpsTimer: PButton
|
||||
loginBtn: PButton
|
||||
playBtn: PButton
|
||||
keyClient = newKeyClient("lobby")
|
||||
showZonelist = false
|
||||
chatInput*: PTextEntry
|
||||
messageArea*: PMessageArea
|
||||
mySession*: ScLogin
|
||||
var
|
||||
dirServer: PServer
|
||||
zone*: PServer
|
||||
activeServer: PServer
|
||||
bConnected = false
|
||||
outgoing = newStringStream("")
|
||||
downloadProgress: PButton
|
||||
connectionButtons: seq[PButton] #buttons that depend on connection to function
|
||||
|
||||
template dispmessage(m: expr): stmt =
|
||||
messageArea.add(m)
|
||||
proc connectZone(host: string; port: TPort)
|
||||
proc connectToDirserv()
|
||||
|
||||
proc writePkt[T](pid: PacketID; p: var T) =
|
||||
if activeServer.isNil: return
|
||||
activeServer.writePkt pid, p
|
||||
|
||||
proc setConnected(state: bool) =
|
||||
if state:
|
||||
bConnected = true
|
||||
for b in connectionButtons: enable(b)
|
||||
else:
|
||||
bConnected = false
|
||||
for b in connectionButtons: disable(b)
|
||||
|
||||
proc setActiveZone(ind: int; zone: ScZoneRecord) =
|
||||
#hilight it or something
|
||||
dispmessage("Selected " & zone.name)
|
||||
connectZone(zone.ip, zone.port)
|
||||
playBtn.enable()
|
||||
|
||||
proc handleChat(serv: PServer; s: PStream) =
|
||||
var msg = readScChat(s)
|
||||
messageArea.add(msg)
|
||||
|
||||
proc connectToDirserv() =
|
||||
if dirServer.isNil:
|
||||
dirServer = newServerConnection(clientSettings.dirserver.host, clientSettings.dirserver.port)
|
||||
dirServer.handlers[HHello] = proc(serv: PServer; s: PStream) =
|
||||
let msg = readScHello(s)
|
||||
dispMessage(msg.resp)
|
||||
setConnected(true)
|
||||
dirServer.handlers[HLogin] = proc(serv: PServer; s: PStream) =
|
||||
mySession = readScLogin(s)
|
||||
##do something here
|
||||
dirServer.handlers[HZonelist] = proc(serv: PServer; s: PStream) =
|
||||
var
|
||||
info = readScZonelist(s)
|
||||
zones = info.zones
|
||||
if zones.len > 0:
|
||||
zonelist.clearButtons()
|
||||
var pos = vec2f(0.0, 0.0)
|
||||
zonelist.newButton(
|
||||
text = "Zonelist - "& info.network,
|
||||
position = pos,
|
||||
onClick = proc(b: PButton) =
|
||||
dispmessage("Click on header"))
|
||||
pos.y += 20
|
||||
for i in 0..zones.len - 1:
|
||||
var z = zones[i]
|
||||
zonelist.newButton(
|
||||
text = z.name, position = pos,
|
||||
onClick = proc(b: PButton) =
|
||||
setActiveZone(i, z))
|
||||
pos.y += 20
|
||||
showZonelist = true
|
||||
dirServer.handlers[HPoing] = proc(serv: PServer; s: PStream) =
|
||||
var ping = readPoing(s)
|
||||
dispmessage("Ping: "& $ping.time)
|
||||
ping.time = epochTime().float32
|
||||
serv.writePkt HPoing, ping
|
||||
dirServer.handlers[HChat] = handleChat
|
||||
dirServer.handlers[HFileChallenge] = handleFileChallenge
|
||||
var hello = newCsHello()
|
||||
dirServer.writePkt HHello, hello
|
||||
activeServer = dirServer
|
||||
|
||||
|
||||
proc zoneListReq() =
|
||||
var pkt = newCsZonelist("sup")
|
||||
writePkt HZonelist, pkt
|
||||
|
||||
##key handlers
|
||||
keyClient.registerHandler(MouseMiddle, down, proc() =
|
||||
gui.setPosition(getMousePos()))
|
||||
|
||||
keyClient.registerHandler(KeyO, down, proc() =
|
||||
if keyPressed(KeyRShift): echo(repr(outgoing)))
|
||||
keyClient.registerHandler(KeyTab, down, proc() =
|
||||
activeInput = (activeInput + 1) mod 2) #does this work?
|
||||
keyClient.registerHandler(MouseLeft, down, proc() =
|
||||
let p = getMousePos()
|
||||
gui.click(p)
|
||||
if showZonelist: zonelist.click(p))
|
||||
var mptext = newText("", guiFont, 16)
|
||||
keyClient.registerHandler(MouseRight, down, proc() =
|
||||
let p = getMousePos()
|
||||
mptext.setPosition(p)
|
||||
mptext.setString("($1,$2)"%[$p.x.int,$p.y.int]))
|
||||
|
||||
|
||||
proc connectZone(host: string, port: TPort) =
|
||||
echo "Connecting to zone at ", host, ':', port
|
||||
if zone.isNil:
|
||||
zone = newServerConnection(host, port)
|
||||
zone.handlers[HFileChallenge] = handleFileChallenge
|
||||
zone.handlers[HChallengeResult] = handleFileChallengeResult
|
||||
zone.handlers[HFileTransfer] = handleFileTransfer
|
||||
zone.handlers[HChat] = handleChat
|
||||
else:
|
||||
zone.sock.connect(host, port)
|
||||
var hello = newCsHello()
|
||||
zone.writePkt HHello, hello
|
||||
|
||||
|
||||
|
||||
proc lobbyReady*() =
|
||||
keyClient.setActive()
|
||||
gui.setActive(u_alias)
|
||||
|
||||
proc tryConnect*(b: PButton) =
|
||||
connectToDirserv()
|
||||
proc tryLogin*(b: PButton) =
|
||||
var login = newCsLogin(
|
||||
alias = u_alias.getText(),
|
||||
passwd = u_passwd.getText())
|
||||
writePkt HLogin, login
|
||||
proc tryTransition*(b: PButton) =
|
||||
##check if we're logged in
|
||||
#<implementation censored by the church>
|
||||
#var joinReq = newCsJ
|
||||
zone.writePkt HZoneJoinReq, mySession
|
||||
#var errors: seq[string] = @[]
|
||||
#if loadSettings("", errors):
|
||||
# transition()
|
||||
#else:
|
||||
# for e in errors: dispmessage(e)
|
||||
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: dispmessage(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.TPort
|
||||
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 = @[]
|
||||
|
||||
downloadProgress = gui.newButton(
|
||||
text = "", position = vec2f(10, 130), onClick = nil)
|
||||
downloadProgress.bg.setFillColor(color(34, 139, 34))
|
||||
downloadProgress.bg.setSize(vec2f(0, 0))
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
fpsTimer = gui.newButton(
|
||||
text = "FPS: ",
|
||||
position = vec2f(10.0, 70.0),
|
||||
onClick = proc(b: PButton) = nil)
|
||||
gui.newButton(
|
||||
text = "Connect",
|
||||
position = vec2f(10.0, 90.0),
|
||||
onClick = tryConnect)
|
||||
connectionButtons.add(gui.newButton(
|
||||
text = "Test Chat",
|
||||
position = vec2f(10.0, 110.0),
|
||||
onClick = (proc(b: PButton) =
|
||||
var pkt = newCsChat(text = "ohai")
|
||||
writePkt HChat, pkt),
|
||||
startEnabled = false))
|
||||
chatInput = gui.newTextEntry("...", vec2f(10.0, 575.0), proc() =
|
||||
sendChat dirServer, chatInput.getText()
|
||||
chatInput.clearText())
|
||||
messageArea = gui.newMessageArea(vec2f(10.0, 575.0 - 20.0))
|
||||
messageArea.sizeVisible = 25
|
||||
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))
|
||||
|
||||
var i = 0
|
||||
proc lobbyUpdate*(dt: float) =
|
||||
#let res = disp.poll()
|
||||
gui.update(dt)
|
||||
i = (i + 1) mod 60
|
||||
if i == 0:
|
||||
fpsTimer.setString("FPS: "& $round(1.0/dt))
|
||||
if not pollServer(dirServer, 5) and bConnected:
|
||||
setConnected(false)
|
||||
echo("Lost connection")
|
||||
discard pollServer(zone, 5)
|
||||
|
||||
proc lobbyDraw*(window: PRenderWindow) =
|
||||
window.clear(Black)
|
||||
window.draw messageArea
|
||||
window.draw mptext
|
||||
window.draw gui
|
||||
if showZonelist: window.draw zonelist
|
||||
window.display()
|
||||
Loading…
Add table
Add a link
Reference in a new issue