-- Leo's gemini proxy

-- Connecting to git.thebackupbox.net:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

repo: game-server
action: commit
revision:
path_from:
revision_from: 1062a91c5cad5bcf96e0e4e8994a0f04b3ac2adf:
path_to:
revision_to:

git.thebackupbox.net

game-server

git://git.thebackupbox.net/game-server

commit 1062a91c5cad5bcf96e0e4e8994a0f04b3ac2adf
Author: epoch <epoch@thebackupbox.net>
Date:   Sat Mar 18 08:26:17 2023 +0000

    quick demo

diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..43ecef7d1a8ea954fedc1f18d1c0264124ae7f31
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+.PHONEY: all
+
+PREFIX:=/usr/local
+
+all: room-server
+
+install: all
+	install -Dt $(PREFIX)/libexec lobby.sh
+	install -Dt $(PREFIX)/libexec room-server
diff --git a/lobby.sh b/lobby.sh
new file mode 100755
index 0000000000000000000000000000000000000000..85223534963e3d71ad8a79ab812082cd2c39ef06
--- /dev/null
+++ b/lobby.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+export ROOM_DIR=/var/cache/game_rooms
+
+export REMOTE_ADDR="$(/usr/local/libexec/peerip | head -n1)"
+export LOCAL_ADDR="$(/usr/local/libexec/sockip | head -n1)"
+export REMOTE_PORT="$(/usr/local/libexec/peerip | tail -n1)"
+export LOCAL_PORT="$(/usr/local/libexec/sockip | tail -n1)"
+
+REMOTE_IDENT="$(ident "$LOCAL_ADDR" "$REMOTE_ADDR" 113 "$REMOTE_PORT" "$LOCAL_PORT")"
+printf "you have connected to a (currently) Rock Paper Scissors server.\n"
+if [ "$REMOTE_IDENT" ];then
+  printf "hello, %s! :D nice to see you\n" "$REMOTE_IDENT"
+else
+  printf "hello, Anonymous, (from %s) if you'd like a name, run an ident server\n" "$REMOTE_ADDR"
+  REMOTE_IDENT=Anonymous
+fi
+printf "games waiting for a player:\n"
+ls "${ROOM_DIR}"
+printf "please select one, or 'new' for a new room:\n"
+read room_path
+if [ -f "${ROOM_DIR}/${room_path}" ];then
+  printf "room %s selected.\n" "$room_path"
+  exec socat "unix:${ROOM_DIR}/${room_path}" stdio
+else
+  if [ "${room_path}" ];then
+    printf "room '%s' not found.\n" "${room_path}"
+  fi
+  room_path="$(ls "${ROOM_DIR}" | shuf | head -n1)"
+  if [ "${room_path}" -a "${room_path}" != "new" ];then
+    printf "selecting a random room. selected: %s\n" "$room_path"
+    exec socat "unix:${ROOM_DIR}/${room_path}" stdio
+  fi
+fi
+if [ "$room_path" == "new" -o "$room_path" == "" ];then
+  printf "creating a new one.\n"
+  exec /usr/local/libexec/room-server
+fi
+
+printf "how did you end up here?\n"
+exit 0
diff --git a/room-server.c b/room-server.c
new file mode 100644
index 0000000000000000000000000000000000000000..8c644e5552d6b910c480210cbbc48516270a97ec
--- /dev/null
+++ b/room-server.c
@@ -0,0 +1,110 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+int win_table[4][4]={
+//  R P S
+ {0,1,2}, //R
+ {2,0,1}, //P
+ {1,2,0}, //S
+};
+
+char who_win(int a,int b) {
+  int c=(a=='R'?0:a=='P'?1:a=='S'?2:-1);
+  int d=(b=='R'?0:b=='P'?1:b=='S'?2:-1);
+  if( c == -1 || d == -1) {
+    return -1;
+  }
+  return win_table[c][d];
+}
+
+int main(int argc,char *argv[]) {
+  struct sockaddr_un sun;
+  struct sockaddr_un peer_addr;
+  int s = socket(AF_UNIX,SOCK_STREAM,0);
+  int c;
+  memset( &sun, sizeof(sun), 0 );
+  sun.sun_family = AF_UNIX;
+
+  char room_id[sizeof(sun.sun_path)];
+  char room_path[sizeof(sun.sun_path)];
+  //printf("sun_path size: %d\n",sizeof(sun.sun_path)); // 108
+  //return 0;
+  if(!getenv("ROOM_DIR")) {
+    printf("well shit, this server is misconfigured.\n");
+    return 1;
+  }
+  snprintf(room_id,sizeof(room_id),"%d_%d_%d",time(0),getpid(),random());
+  snprintf(room_path,sizeof(room_path),"%s/%s",getenv("ROOM_DIR"),room_id);
+  printf("you have created room: %s\n",room_id);
+  fflush(stdout);
+
+  strncpy(sun.sun_path, room_path, sizeof(sun.sun_path) - 1);
+  if(bind(s, (struct sockaddr *) &sun, sizeof(sun)) == -1) {
+    perror("bind");
+    return 1;
+  }
+  if(listen(s, 0) == -1) {
+    perror("listen");
+    return 2;
+  }
+  // hrm... merp. I think I might have to add the newly accepted connection to an array.
+  // then select() on all of them for data.
+  // I've got a library for this kind of shit.
+  // because it is flaky code, so I only want to have to write it once.
+  unsigned int len = sizeof(peer_addr);
+  int good=0;
+  int over=0;
+  char buf0[4096];
+  char bufc[4096];
+  char tmp[1024];
+  //todo: probably make this work as a separate program.
+  if( (c = accept( s, (struct sockaddr *)&peer_addr, &len )) > 0 ) { //or we could limit it to two per room.
+    printf("received a connection!\n");
+    printf("unlinking the socket file\n");
+    unlink(room_path);
+#define dubwrite(a,b,c) do{write(a,c,strlen(c));write(b,c,strlen(c));} while(0)
+#define rite(a,b) write(a,b,strlen(b))
+    dubwrite(c,1,"hello\n");
+    dubwrite(c,1,"this is rock, paper, scissors.\n");
+    dubwrite(c,1,"move choises: R, P, S, Q\n");
+    dubwrite(c,1,"Q to quit the game\n");
+    dubwrite(c,1,"the game is about to start. please enter your moves like: R\n");
+    int p=c;
+    int wins0=0;
+    int winsc=0;
+    for( over=0 ; !over ; p=p?0:c) {
+      for( good=0 ; !good ; ) {
+        read(c,bufc,4096); //we'll just toss the rest of it.
+        bufc[1]=0;
+        read(0,buf0,4096);
+	buf0[1]=0;
+        //collect both moves. either one blocking is fine.
+        switch( who_win(buf0[0],bufc[0]) ) {
+          case 0:
+            dubwrite(c,1,"tie\n");
+            break;
+          case 1:
+	    winsc++;
+	    snprintf(tmp,sizeof(tmp),"you win (%d total)\n",winsc);
+            rite(c,tmp);
+            rite(1,"you lose\n");
+            break;
+          case 2:
+	    wins0++;
+            rite(c,"you lose\n");
+	    snprintf(tmp,sizeof(tmp),"you win (%d total)\n",wins0);
+	    rite(1,tmp);
+            break;
+          default:
+            dubwrite(c,1,"someone entered an invalid move.\n");
+            break;
+        }
+      }
+    }
+  }
+  close(s);
+}

-----END OF PAGE-----

-- Response ended

-- Page fetched on Sun Jun 2 16:28:07 2024