⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server.cc

📁 国外一套很好的游戏代码,款经典的小游戏 希望大家提出宝贵意见 让我们一起进步
💻 CC
📖 第 1 页 / 共 2 页
字号:
/*	server.cc		(c) Richard Thrippleton	Licensing terms are in the 'LICENSE' file	If that file is not included with this source then permission is not given to use this source in any way whatsoever.*/#include <string.h>#include <stdio.h>#include <stdarg.h>#include "sockhelper.h"#include "calc.h"#include "error.h"#include "protocol.h"#include "ship.h"#include "frag.h"#include "planet.h"#include "alliance.h"#include "constants.h"#include "player.h"#include "os.h"#include "server.h"struct octets //Structure for extraction of octets from an IP{	unsigned char o1;	unsigned char o2;	unsigned char o3;	unsigned char o4;};void server::init(){	for(int i=0;i<ISIZE;i++)		connections[i]=NULL;	lstn=NULL;}void server::start(bool locg){	IPaddress serv; //Server listening interface	tcks=0;	qsig=false;	try	{		logf=os::openpersonal("log","a");	}	catch(error it)	{		logf=stdout;	}		SDLNet_ResolveHost(&serv,NULL,PORT);	lstn=SDLNet_TCP_Open(&serv);	if(!lstn)		throw error("Can't open listening socket");	fprintf(logf,"%s: Server started listening on port %hd\n",os::gettime(),PORT);	fflush(logf);	server::locg=locg;	locl=false;}void server::stop(){	for(int i=0;i<ISIZE;i++)		if(connections[i])			delete connections[i];	if(lstn!=NULL)	{		SDLNet_TCP_Close(lstn);		lstn=NULL;		fprintf(logf,"%s: Server shutdown\n",os::gettime());		fflush(logf);	}	if(logf && logf!=stdout)		fclose(logf);}void server::cycle(){	TCPsocket sock; //Sample socket	tcks++;	if(tcks>32766)		tcks=1;	sock=NULL;	if(!locl)		sock=SDLNet_TCP_Accept(lstn);	if(sock)	{		for(int i=0;i<ISIZE;i++)		{			if(!connections[i])			{				connections[i]=new server(i,sock);				if(locg)					locl=true;				break;			}		}	}	for(int i=0;i<ISIZE;i++)	{		if(connections[i])		{			try			{				connections[i]->poll();				connections[i]->uploads();			}			catch(error it)			{				connections[i]->log("Dropped from the game: %s",it.str);				delete connections[i];			}		}	}	if(qsig)		throw error("Server caught quit signal");}void server::notifydelete(player* ply){	for(int i=0;i<ISIZE;i++)		if(connections[i] && connections[i]->ply==ply)			connections[i]->ply=NULL;}void server::notifykill(player* ply){	for(int i=0;i<ISIZE;i++)		if(connections[i] && connections[i]->ply==ply && connections[i]->ply->in)			connections[i]->kill();}void server::hail(player* fr,player* to,char* msg){	char txt[256]; //Communications text	char* frnm; //Name of from	if(!to)		return;	frnm=NULL;	if(fr)	{		frnm=fr->nam;		if(!frnm)			if(fr->in)				frnm=fr->in->cls;			else				frnm="";		sprintf(txt,"%s: %s",frnm,msg);	}	else		sprintf(txt,"%s",msg);	for(int i=0;i<ISIZE;i++)	{			if(connections[i] && (connections[i]->ply==to || (fr && connections[i]->ply==fr)))		{			if(fr && fr->in)				connections[i]->hilight(fr->in);			connections[i]->printtomesg("%s",txt);			if(connections[i]->ply==to)			{				if(connections[i]->ply->in)					server::registersound(connections[i]->ply->in,SND_COMM);				connections[i]->log("Received hail \"%s\"",txt);			}		}	}}void server::bulletin(char* fmt,...){	char buf[132]; //Outgoing buffer	va_list fmts;	if(fmt[0]!='\0')	{		va_start(fmts,fmt);		vsprintf(buf,fmt,fmts);		va_end(fmts);		for(int i=0;i<ISIZE;i++)			if(connections[i])				connections[i]->printtomesg("%s",buf);				fprintf(logf,"%s: Bulletin - %s\n",os::gettime(),buf);		fflush(logf);	}}void server::registernoise(ship* fr,int snd){	unsigned char buf[SERV_NOISE_SZ]; //Buffer for sending sound	for(int i=0;i<ISIZE;i++)	{		if(connections[i] && connections[i]->ply && connections[i]->ply->in && connections[i]->lsnd!=snd && connections[i]->ply->in->see(fr))		{				connections[i]->lsnd=snd;				buf[0]=SERV_NOISE;			calc::inttodat(snd,buf+1);			calc::inttodat(ship2pres(fr->self),buf+3);			connections[i]->hlpr->send(buf,SERV_NOISE_SZ);		}	}}void server::registersound(ship* to,int snd){	unsigned char buf[SERV_SND_SZ]; //Buffer for sending sound	for(int i=0;i<ISIZE;i++)	{		if(connections[i] && connections[i]->ply && connections[i]->ply->in==to && connections[i]->lsnd!=snd)		{			connections[i]->lsnd=snd;			buf[0]=SERV_SND;			calc::inttodat(snd,buf+1);			connections[i]->hlpr->send(buf,SERV_SND_SZ);		}	}}void server::registershake(ship* to,int mag){	unsigned char buf[SERV_SHAKE_SZ]; //Buffer for sending shake	for(int i=0;i<ISIZE;i++)	{		if(connections[i] && connections[i]->ply && connections[i]->ply->in==to)		{			buf[0]=SERV_SHAKE;			calc::inttodat(mag,buf+1);			connections[i]->hlpr->send(buf,SERV_SHAKE_SZ);		}	}}void server::quitsignal(int sig){	qsig=true;}server::server(int self,TCPsocket sock){	unsigned long ip; //ip of connecting client	octets* oip; //Ip as octets, for writing to Ip record	this->self=self;	this->sock=sock;	hlpr=NULL;	hlpr=new sockhelper(sock);	hlpr->pump();	auth=false;	lsnd=-1;	inpb[0]='\0';	ply=NULL;	foc=-1;	shpu=new bool[ship::ISIZE];	for(int i=0;i<ship::ISIZE;i++)		shpu[i]=false;	plnu=new bool[planet::ISIZE];	for(int i=0;i<planet::ISIZE;i++)		plnu[i]=false;	frgu=new bool[frag::ISIZE];	for(int i=0;i<frag::ISIZE;i++)		frgu[i]=false;	log("Connection opened");	urat=10;	ip=SDLNet_TCP_GetPeerAddress(sock)->host;	oip=(octets*)&ip;	if(oip->o1==127 && oip->o2==0 && oip->o3==0 && oip->o4==1)		cbnd=999999999;	else		cbnd=0;	tout=0;}server::~server(){	if(ply)		ply->logout();	log("Connection terminated");	connections[self]=NULL;	if(hlpr)		delete hlpr;	SDLNet_TCP_Close(sock);}void server::log(char* fmt,...){	unsigned long ip; //ip of connecting client	octets* oip; //Ip as octets, for writing to Ip record	va_list fmts; //For resolving the format string	fprintf(logf,"%s: ",os::gettime());	fprintf(logf,"[%hd] ",self);	if(ply)		fprintf(logf,"%s ",ply->nam);	else		fprintf(logf," ");	ip=SDLNet_TCP_GetPeerAddress(sock)->host;	oip=(octets*)&ip;	fprintf(logf,"(%hd.%hd.%hd.%hd) ",(int)oip->o1,(short)oip->o2,(short)oip->o3,(short)oip->o4);	va_start(fmts,fmt);	vfprintf(logf,fmt,fmts);	va_end(fmts);	fprintf(logf,"\n");	fflush(logf);}void server::poll(){	int typ,opr; //Action description	unsigned char* buf; //Incoming data buffer	long sbnd; //Server bandwidth used by this player	unsigned char fldb[SERV_FLOOD_SZ]; //Flooding buffer	hlpr->pump();	tout++;	if(tout>200)		throw error("Activity timeout");	if(auth)	{		lsnd=-1;		for(int i=0;i<32;i++)			acth[i]=false;		for(int i=0;i<4;i++)		{			buf=hlpr->request(3);			if(buf)			{				typ=((int)buf[0]);				opr=calc::dattoint(buf+1);				if(typ>=0 && typ<32)				{					if(typ==CLIENT_CHAR || !acth[typ])					{						action(typ,opr);						hlpr->suck();					}					acth[typ]=true;				}				else					hlpr->suck();			}			else				break;			tout=0;		}	}	else	{		buf=hlpr->request(6);		if(buf)		{			if(calc::dateq((unsigned char*)SIGN,buf,6))				auth=true;			else				throw error("Using incorrect protocol");			hlpr->suck();			fldb[0]=SERV_FLOOD;			for(int i=1;i<SERV_FLOOD_SZ;i++)				fldb[i]=0;			for(int i=0;i<110;i++)				hlpr->send(fldb,SERV_FLOOD_SZ);			changecmod(CMOD_NAME);		}	}	if(tcks%24==0)	{		sbnd=hlpr->getcount();		if(sbnd>(cbnd/2))			urat+=6;		if(sbnd<(cbnd/2))			urat-=2;		if(urat<10)			urat=10;		if(urat>70)			urat=70;	}}void server::action(int typ,short opr){	if((typ==CLIENT_CONS || typ==CLIENT_CHAR || typ==CLIENT_BANDWIDTH) || (ply && ply->in))	{		try		{			switch(typ)			{				case CLIENT_ACCEL:				ply->in->aity=ship::AI_NULL;				if(opr==-2)					ply->in->accel(-1,true);					if(opr==-1)					ply->in->accel(-1,false);					if(opr==1)						ply->in->accel(+1,false);					if(opr==2)						ply->in->accel(+1,true);					break;				case CLIENT_TURN:				ply->in->aity=ship::AI_NULL;				if(opr==-1)					ply->in->turn(-1);				if(opr==+1)					ply->in->turn(+1);				break;				case CLIENT_SHOOT:				if(opr==0)					ply->in->shoot(false);				if(opr==1)					ply->in->shoot(true);				break;				case CLIENT_TRG:				ply->in->aity=ship::AI_NULL;				ply->in->enem=NULL;				ply->in->frnd=NULL;				ply->in->plnt=NULL;				if(opr>=0 && opr<(planet::ISIZE+ship::ISIZE))				{					if(opr<planet::ISIZE)						ply->in->plnt=planet::get(opr);					else					{						ply->in->enem=ship::get(opr-planet::ISIZE);						if(ply->in->enem==ply->in)							ply->in->enem=NULL;						if(ply->in->enem)							if(ply->in->all->opposes(ply->in->enem->all))								registersound(ply->in,SND_PROXIMITY);							else								registersound(ply->in,SND_BEEP2);					}				}				if(cmod==CMOD_SCAN || cmod==CMOD_HAIL || cmod==CMOD_WHOIS)					changecmod(cmod);				if(cmod==CMOD_REFIT)					changecmod(CMOD_HAIL);				break;				case CLIENT_CMOD:				switch(opr)				{					case REQ_STAT:					changecmod(CMOD_STAT);					break;					case REQ_EQUIP:					changecmod(CMOD_EQUIP);					break;					case REQ_SCAN:					changecmod(CMOD_SCAN);					break;					case REQ_HAIL:					changecmod(CMOD_HAIL);					break;					case REQ_CHAT:					changecmod(CMOD_CHAT);					break;					case REQ_WHOIS:					changecmod(CMOD_WHOIS);					break;					case REQ_HACK:					changecmod(CMOD_HACK);					break;				}				break;				case CLIENT_CONS:				cons(opr);				break;				case CLIENT_CHAR:				if(opr==0)				{					input();					inpb[0]='\0';				}				if(opr>=32 && opr<127)				{					if(opr>=65 && opr<=90)						opr+=32;					for(int i=0;i<64;i++)					{						if(inpb[i]=='\0')						{							inpb[i]=opr;							inpb[i+1]='\0';							break;						}					}				}				break;				case CLIENT_BANDWIDTH:				if(opr>cbnd)				{					cbnd=opr;					log("Bandwidth exploration reports %ld maximum",cbnd);				}				break;				default:				break;			}		}		catch(error it)		{			printtomesg(it.str);			changecmod(cmod);		}	}}void server::changecmod(int opr){	char* txtp;	char txt[1024]; //Text buffer for constructing output	alliance* tali; //Alliance for possible choosing	int spr; //Sprite to spritetocons with	cmod=opr;	txtp=txt;	spr=-1;	txt[0]='\0';	if(ply && ply->in)		registersound(ply->in,SND_BEEP1);	if(cmod!=CMOD_NAME && cmod!=CMOD_PASS && cmod!=CMOD_CHOOSE && !(ply && ply->in))		return;	switch(opr)	{		case CMOD_NAME:		printtocons("Choose player name\n");		requestline(false);		break;		case CMOD_PASS:		printtocons("Player name currently exists\nPlease input player password");		requestline(true);		break;		case CMOD_CHOOSE:		txtp+=sprintf(txtp,"Choose alliance\n");		for(int i=0;i<alliance::LIBSIZE;i++)		{			tali=alliance::get(i);			if(tali)				txtp+=sprintf(txtp,"[%hd] %s\n",i,tali->nam);		}		printtocons(txt);		break;		case CMOD_STAT:		spr=ply->in->interact(txt,CMOD_STAT,-1,ply->in);		printtocons(txt);		spritetocons(spr);		break;		case CMOD_EQUIP:		ply->in->interact(txt,CMOD_EQUIP,-1,ply->in);		printtocons(txt);		break;		case CMOD_SCAN:		if(ply->in->enem)		{			spr=ply->in->enem->interact(txt,CMOD_SCAN,-1,ply->in);			printtocons(txt);			spritetocons(spr);		}		else		{			if(ply->in->plnt)			{				spr=ply->in->plnt->interact(txt,CMOD_SCAN,-1,ply->in);				printtocons(txt);				spritetocons(spr);			}			else			{				printtocons("No target");			}		}		break;		case CMOD_HAIL:		if(ply->in->enem)		{			ply->in->enem->interact(txt,CMOD_HAIL,-1,ply->in);			printtocons(txt);		}		else		{			if(ply->in->plnt)			{				ply->in->plnt->interact(txt,CMOD_HAIL,-1,ply->in);				printtocons(txt);			}			else			{				printtocons("No target");			}		}		break;				case CMOD_REFIT:		if(ply->in->plnt)		{			ply->in->plnt->interact(txt,CMOD_REFIT,-1,ply->in);			printtocons(txt);		}		break;		case CMOD_CHAT:		txtp+=sprintf(txtp,"Messaging\n\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -