summary refs log tree commit diff stats
path: root/tests/manyloc/keineschweine/server/old_dirserver.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manyloc/keineschweine/server/old_dirserver.nim')
-rw-r--r--tests/manyloc/keineschweine/server/old_dirserver.nim201
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"
+