wm: glendy

Download patch

ref: 3edf0f3d3bc73e05dc0a21e58305502470be910d
parent: d5c2af3bcb04031bd6f2724a480b9c7758eeacbb
author: mkf <mkf@cloud9p.org>
date: Thu Dec 12 07:37:57 EST 2024

srv4.c: remove

--- a/srv4.c
+++ /dev/null
@@ -1,504 +1,0 @@
-/*
- * glendy (unix) server, 4th revision
- */
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <time.h>
-#include <pthread.h>
-#include <sys/types.h> 
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include "unix.h"
-#include "engine.h"
-#include "util.h"
-#include "srv.h"
-
-#define playersock sockfd[turn % 2]
-
-int listenfd;
-int port = 1768;
-int debug = 1;
-char syncmsg[8];
-
-int sockfd[2];
-
-int gcount = 0;
-
-int id = 0;
-
-pthread_mutex_t game_lock;
-
-Game games[32];
-pthread_t threads[32][2];
-
-static void
-error(const char *msg)
-{
-	perror(msg);
-	pthread_exit(NULL);
-}
-
-static void
-cleanup(int game)
-{
-	dprint("cleanup(%d)\n", game);
-	close(games[game].sockfd[0]);
-	close(games[game].sockfd[1]);	
-}
-
-static void
-printclients(char *fmt, ...)
-{
-	/* it seems arg gets changed during the first call to vprint, thus we need two */
-	va_list arg, arg2;
-	
-	va_start(arg, fmt);
-	va_start(arg2, fmt);
-	
-	vfprint(sockfd[0], fmt, arg);
-	vfprint(sockfd[1], fmt, arg2);
-	va_end(arg);
-	va_end(arg2);
-}
-
-int
-setuplistener(int portno)
-{
-	int sockfd, option = 1;
-	struct sockaddr_in serv_addr;
-
-	sockfd = socket(AF_INET, SOCK_STREAM, 0);
-	if (sockfd < 0) 
-		error("ERROR opening listener socket.");
-	
-	memset(&serv_addr, 0, sizeof(serv_addr));
-	serv_addr.sin_family = AF_INET;	
-	serv_addr.sin_addr.s_addr = INADDR_ANY;	
-	serv_addr.sin_port = htons(portno);	
-	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
-
-	if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
-		error("ERROR binding listener socket.");
-
-	dprint("listener on\n");
-
-	return sockfd;
-}
-
-void
-drawlevel(void)
-{
-	/* prints first row, this assumes SzX = SzY, is there a better way? */
-	print("T%2d|", turn);
-	for(int i = 0 ; i < SzX ; i++)
-		print("%2d |", i);
-
-	dprint(" G%2d\n", id);
-
-	for(int x = 0; x < SzX; x++)
-	{
-		for(int i = 0 ; i < SzY+1 ; i++)
-			print("----");
-		print(x % 2 ? "\\" : "/");
-		print("\n");
-
-		/* show column number and have a zig-zag effect */
-		print("%2d %s|", x, x % 2 ? "  " : "");
-
-		for(int y = 0; y < SzY; y++)
-		{
-			/* it's [y][x], not [x][y] */
-			switch(grid[y][x])
-			{
-				case Wall: 
-					print(" * |");
-					break;
-				case Glenda:
-					/* fancy effect for glenda's face */
-					print(" g |");
-					break;
-				default:
-					print("   |");
-					break;
-			}
-		}
-		print("\n");
-	}
-}
-
-void
-sendlevel(void)
-{
-	if(state == Start)
-	{
-		printclients("INIT\n");
-	
-		for(int x = 0; x < SzX; x++)
-		{
-			for(int y = 0; y < SzY; y++)
-			{
-				switch(grid[x][y])
-				{
-					case Wall: 
-						printclients("w %d %d\n", x, y);
-						break;
-					case Glenda:
-						printclients("g %d %d\n", x, y);
-						break;
-				}
-			}
-		}
-		printclients("SENT\n");
-	}
-	else if(state == Playing)
-	{
-		printclients("SYNC %d %s\n", turn, syncmsg);
-	}
-	else
-	{
-		printclients("SYNC %d %s\n", turn, syncmsg);
-		if(state == Won)
-		{
-			dprint("hah, trapper won\n");
-			fprint(sockfd[0], "WON\n");
-			fprint(sockfd[1], "LOST\n");
-		}
-		else if(state == Lost)
-		{
-			dprint("welp, trapper lost\n");
-			fprint(sockfd[0], "LOST\n");
-			fprint(sockfd[1], "WON\n");
-		}
-		cleanup(id);
-		return;
-	}
-	dprint("Game %d, Turn is %d, min = %d\n", id, turn, findmin(findglenda()));
-	fprint(playersock, "TURN\n");
-	fprint(sockfd[!(turn % 2)], "WAIT\n");
-}
-
-/* p x y */
-void
-proc_put(char *s)
-{
-	char *xpos, *ypos;
-	unsigned int x, y, r;
-
-	xpos = strtok(s, " ");
-	ypos = strtok(nil, " ");
-	
-	if(xpos == nil || ypos == nil)
-	{
-		fprint(playersock, "ERR INVALIDINPUT proc_put():"
-		"not enough arguments or malformed string\n");
-		return;
-	}
-	
-	if(!isnum(xpos, strlen(xpos)) || !isnum(ypos, strlen(ypos)))
-	{
-		fprint(playersock, "ERR invalidinput proc_put():"
-		"expected string in %s and %s\n", xpos, ypos);
-		return;
-	}
-
-	/* engine assumes it's XY, protocol assumes it's YX */
-	x = atoi(xpos);
-	y = atoi(ypos);	
-	
-	dprint("put %d %d\n", x, y);
-
-	if(x >= SzX || x < 0 || y >= SzY || y < 0)
-	{
-		fprint(playersock, "ERR invalidinput proc_put(): %d %d\n", x, y);
-		return;
-	}
-
-	r = doput(Pt(x, y)); 
-	if(r == Wall)
-		fprint(playersock, "WALL %d %d\n", x, y);
-	else if(r == Glenda)
-		fprint(playersock, "GLND %d %d\n", x, y);
-	else
-	{
-		sprint(syncmsg, "%u %u", x, y);
-		syncmsg[7] = '\0';
-		dprint("syncmsg = %s\n", syncmsg);
-	}
-}
-
-/* m x y */
-void
-proc_move(char *s)
-{
-	int d;
-	Point p;
-	
-	p = findglenda();
-	d = strtodir(s);
-	
-	if(d == Err)
-	{
-		fprint(playersock, "ERR invalidinput proc_move(): %s\n", s);
-		return;
-	}
-	
-	if(domove(d) == Wall)
-	{
-		fprint(playersock, "WALL %s %d %d\n", s, p.x, p.y);
-		return;
-	}
-	else
-	{
-		strncpy(syncmsg, s, 7);
-		/* better be safe than sorry */
-		syncmsg[7] = '\0';
-		dprint("syncmsg = %s\n", syncmsg);
-	}
-}
-
-/*
- * handle input, which is in the form of:
- * trapper> p xx yy
- * puts a wall in xx yy
- * glenda> m {NE, E, SE, SW, W, NW}
- * moves the bunny
- * > q
- * quits the game
- */
-int
-proc(int player, char *s)
-{
-	int oturn;
-
-	/* early return paths */
-	if(*s == '\0' || *s == 'q')
-	{
-		fprint(sockfd[player], "DIE disconnected\n");
-		fprint(sockfd[!player], "DIE other client have been disconnected\n");
-		
-		/* mmhm... what happens if we close a fd we are reading from? */
-		cleanup(id);
-		return Err;
-	}
-	else if(turn % 2 != player)
-	{
-		fprint(sockfd[player], "ERR WAIT\n");
-		return Ok;
-	}
-
-	oturn = turn;
-	/* s+2 skips command and first space after it */
-	switch(*s)
-	{
-		case 'p':
-			if(turn % 2 == 0)
-				proc_put(s+2);
-			else if(turn % 2 == 1)
-				fprint(playersock, "CANTP\n");
-			break;
-		case 'm':
-			if(turn % 2 == 0)
-				fprint(playersock, "CANTM\n");
-			else if(turn % 2 == 1)
-				proc_move(s+2);
-			break;
-		default:
-			fprint(playersock, "ERR proc() unkown command %c\n", *s);
-	}
-	/* only print the map if turn have changed */
-	if(turn != oturn)
-	{
-		if(debug)
-			drawlevel();
-		sendlevel();
-	}
-	return Ok;
-}
-
-static char*
-input(int game, int player)
-{
-	char *s, c;
-	int n = 0;
-	
-	/* sang bozorg */
-	s = emalloc(1024);
-	memset(s, 0, 1024);
-	
-	/* we could use local variables, but that not worth the trouble */
-	while((c = read(games[game].sockfd[player], s+n, 1) == 1) && n < 1024)
-	{
-		if(s[n] == '\n' || s[n] == '\0')
-		{
-			s[n] = '\0';
-			break;
-		}
-		n++;
-	}
-	dprint("[G%2d/P%2d], got input: %s\n", game, player, s);
-
-	return s;
-}
-
-/*
- * most of game engine's works on global variables
- * set the global variables with one game from the array
- */
-static void
-loadgame(int n)
-{
-	if(n > sizeof(games) / sizeof(Game))
-		sysfatal("loadgame(%d): invalid game", n);
-	
-	id = games[n].id;
-	difficulty = games[n].difficulty;
-	state = games[n].state;
-	turn = games[n].turn;
-
-	strncpy(syncmsg, games[n].syncmsg, 8);
-	
-	sockfd[0] = games[n].sockfd[0];
-	sockfd[1] = games[n].sockfd[1];
-	
-	memcpy(grid, games[n].grid, sizeof(grid));
-}
-
-static void
-setgame(int n)
-{
-	if(n > sizeof(games) / sizeof(Game))
-		sysfatal("setgame(%d): invalid game", n);
-	
-	/* id got to change when we set game */
-	id = n;
-	games[n].id = n;
-	games[n].difficulty = difficulty;
-	games[n].state = state;
-	games[n].turn = turn;
-
-	games[n].sockfd[0] = sockfd[0];
-	games[n].sockfd[1] = sockfd[1];
-
-	memcpy(games[n].grid, grid, sizeof(grid));
-}
-
-/* player is either 0 or 1, trapper or glenda */
-static void
-clienthandler(void *data)
-{
-	int res, player, game;
-	char *s;
-	
-	game = ((int*)data)[0];
-	player = ((int*)data)[1];
-	
-	for(;;)
-	{
-		/* most of time is spent here */
-		s = input(game, player);
-		
-
-		if(!strcmp(s, ""))
-		{
-			cleanup(game);
-			break;
-		}
-		
-		pthread_mutex_lock(&game_lock);
-		
-		loadgame(game);
-		res = proc(player, s);
-		setgame(game);
-		
-		pthread_mutex_unlock(&game_lock);
-		free(s);
-	}
-}
-
-void
-srv(int listenfd)
-{
-	int clientfd[2], res[2];
-	socklen_t clilen;
-	struct sockaddr_in clientaddr;
-	int tdata[2][2];
-
-	while(gcount < 32)
-	{
-		for(int conns = 0 ; conns < 2 ; conns++)
-		{
-			listen(listenfd, 64);
-			memset(&clientaddr, 0, sizeof(clientaddr));
-	
-			clilen = sizeof(clientaddr);
-			clientfd[conns] = accept(listenfd, (struct sockaddr *) &clientaddr, &clilen);
-		
-			if(clientfd[conns] < 0)
-				error("srv(): failed to accept connection");
-	
-			fprint(clientfd[conns], "CONN %d\n", conns);
-			dprint("game %d: srv(): client %d connected\n", gcount, conns);
-	
-			if(conns == 0)
-				fprint(clientfd[conns], "WAIT\n");
-		}
-		pthread_mutex_lock(&game_lock);
-		gcount++;
-
-		sockfd[0] = clientfd[0];
-		sockfd[1] = clientfd[1];
-
-		initlevel();
-		setgame(gcount);
-
-		if(debug)
-			drawlevel();
-		
-		sendlevel();
-
-		pthread_mutex_unlock(&game_lock);
-
-
-		tdata[0][0] = gcount;
-		tdata[0][1] = 0;
-		
-		tdata[1][0] = gcount;
-		tdata[1][1] = 1;
-		
-		res[0] = pthread_create(&threads[gcount][0], NULL, (void*)clienthandler, (void*)tdata[0]);
-		res[1] = pthread_create(&threads[gcount][1], NULL, (void*)clienthandler, (void*)tdata[1]);
-		
-		if(res[0] || res[1])
-		{
-			dprint("pthread_create() failed: %d\n", res[0] ? res[0] : res[1]);
-			exit(-1);
-		}
-		else
-			dprint("threads for game %d are created\n", gcount);
-	}
-}
-
-int 
-main(int argc, char **argv)
-{
-	/* it might not be a real human */
-	ptype[0] = Human;
-	ptype[1] = Human;
-	
-	listenfd = setuplistener(port);
-	pthread_mutex_init(&game_lock, NULL);
-	
-	/* OpenBSD ignores this */
-	srand(time(nil));
-	
-	srv(listenfd);
-	
-	close(listenfd);
-	pthread_mutex_destroy(&game_lock);
-	pthread_exit(NULL);
-	return 0;
-}