diff options
Diffstat (limited to 'tests/manyloc/keineschweine/server/old_dirserver.nim')
-rw-r--r-- | tests/manyloc/keineschweine/server/old_dirserver.nim | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/tests/manyloc/keineschweine/server/old_dirserver.nim b/tests/manyloc/keineschweine/server/old_dirserver.nim new file mode 100644 index 000000000..a63829691 --- /dev/null +++ b/tests/manyloc/keineschweine/server/old_dirserver.nim @@ -0,0 +1,201 @@ +## directory server +## handles client authorization and assets +import ../../../dist/checksums/src/checksums/md5 +import + sockets, times, streams, streams_enh, tables, json, os, + sg_packets, sg_assets, 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 true: + import parseopt, strutils + var cfgFile = "dirserver_settings.json" + for kind, key, val in getopt(): + case kind + of cmdShortOption, cmdLongOption: + case key + of "f", "file": + if fileExists(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" + |