int Server_ReceiveSystemVersion(ServerState *state)
{
unsigned char	opCode;

	Logmsg("Server_ReceiveSystemVersion\n");

	if(Server_TReadDataSync(state->session, 1, (Ptr)&opCode ) != noErr)
		return(kServerFuncAbort);

	if(opCode != msSystemVersion){
		// f****d
		Logmsg("Wrong opCode.  Expected %d, got %d\n", msSystemVersion, opCode);
		return(kServerFuncAbort);
	}
	Server_TReadDataSync( state->session, 2, (Ptr)&state->systemVersionData.length );
	Server_TReadDataSync( state->session, 4, (Ptr)&state->systemVersionData.version );

	if(Server_TCheckError() != noErr)
		return(kServerFuncAbort);

	state->validFlags |= kServerValidFlag_SystemVersion;
	
	Logmsg("length = %d, version = %ld\n", state->systemVersionData.length, state->systemVersionData.version);
	Logmsg("Server_ReceiveSystemVersion done\n");

	return(kServerFuncOK);
}
Пример #2
0
int Server_EndCommunication(ServerState *state)
{
unsigned char opCode;

	Logmsg("Server_EndCommunication\n");

	if(Server_DebugService(state) != kServerFuncOK)
		return(kServerFuncAbort);


	opCode = msEndOfStream;
	Server_TWriteDataSync(state->session, 1, (Ptr)&opCode );
	Server_TReadDataSync( state->session, 1, (Ptr)&opCode );

	if(Server_TCheckError() != noErr)
		return(kServerFuncAbort);

	if(opCode != msEndOfStream)
	{
		//
		// Even though this is end of service, I'll return an abort just for fun.
		//
		Logmsg("Error: Box didn't respond to msEndOfStream with its own msEndOfStream\n");
		return(kServerFuncAbort);
	}

	Logmsg("Server_EndCommunication done\n");

	return(kServerFuncOK);
}
Пример #3
0
int Server_ProcessSendQ(ServerState *state)
{
short 		i;
QItem		*item;
Mail		*mail;
GameResult	*gameResult;

	Logmsg("Server_ProcessSendQ:\n");

	for(i = 0; i < state->sendQData.count; i++)
	{
		item = &state->sendQData.items[i];
//
// there are no types anymore, just a DBID.  8/4/94
//
		switch (item->theID) {
		case kRestartInfoType:
			// dump the crash record for Andy1
			FLogmsg(LOG_CRASH, "RESTART INFO for '%s' (%s) (OS Patch version =%ld) (theID=%ld), size=%ld\n",
				state->loginData.userID.userName,
				state->boxPhoneNumber.phoneNumber,
				state->systemVersionData.version,
				(long)item->theID, (long)item->size);
			PrintCrashRecord(item->data, item->size);
			break;
		case kChatDebugType:
		case kDebugChatScriptConst800:
			// dump the chat script debug for Brian
			if (item->theID == kChatDebugType)
				FLogmsg(LOG_DBUG, "CHAT SCRIPT DEBUG X.25 (theID=%ld, size=%ld)\n",
					(long)item->theID, (long)item->size);
			else
				FLogmsg(LOG_DBUG, "CHAT SCRIPT DEBUG 800 (theID=%ld, size=%ld)\n",
					(long)item->theID, (long)item->size);
			FLogmsg(LOG_DBUG, "SCRIPT INFO for '%s' (%s) (theID=%ld), size=%ld\n",
				state->loginData.userID.userName,
				state->boxPhoneNumber.phoneNumber,
				(long)item->theID, (long)item->size);
			FLoghexdump(LOG_DBUG, item->data, item->size);
			break;
		case kGameResultDataDBID:
			// dump the game results for Steve
			FLogmsg(LOG_GAMERESULT, "GAME RESULTS for '%s' (%s) (theID=%ld), size=%ld\n",
				state->loginData.userID.userName,
				state->boxPhoneNumber.phoneNumber,
				(long)item->theID, (long)item->size);
			DumpJamsStats(item->data, item->size);
			break;
		default:
			// just drop it
			Logmsg("Server_ProcessSendQ: ignored item with ID %ld\n",
				(long)item->theID);
			break;
		}
	}

	Logmsg("Server_ProcessSendQ done\n");
	return(kServerFuncOK);
}
Пример #4
0
void ServerState_PrintUserIdentification(const userIdentification *userID)
{
	Logmsg("  User identification:\n");
		Logmsg("	Box serial number = (%ld,%ld) [%ld]\n",
			userID->box.box, userID->box.region, (long)userID->userID);
		Logmsg("	User name = '%s'\n", userID->userName);
		Logmsg("    User town = '%s'\n", userID->userTown);
		Logmsg("    iconID = %ld, colorTableID = %ld\n",
			(long) userID->ROMIconID, (long)userID->colorTableID);
}
Пример #5
0
void ServerState_Empty(ServerState *state)
{
	Logmsg("ServerState_Empty\n");

	if(state->validFlags & kServerValidFlag_Account)
	{
		ASSERT(state->account);
		
		DataBase_FreeAccount(state->account);
		state->account = NULL;
	}
	
	if(	state->validFlags & kServerValidFlag_SendQ)
	{
		long i;
		
		for(i = 0; i < state->sendQData.count; i++){
			Logmsg("	Item %ld:\n", i);
			Logmsg("		DBID = %ld, Size = %ld\n",
							(long)state->sendQData.items[i].theID,
							state->sendQData.items[i].size);
			free(state->sendQData.items[i].data);
		}
		free(state->sendQData.items);
		state->sendQData.items = NULL;
	}
	
	if(state->validFlags & kServerValidFlag_AddrValidation)
	{
		// BRAIN DAMAGE????
	}
	
	if(state->validFlags & kServerValidFlag_IncomingMail)
	{
		short i;
		
		for(i = 0; i < state->incomingMail.count; i++)
			if(state->incomingMail.mailItems[i].mail)
				free(state->incomingMail.mailItems[i].mail);
		
		if(state->incomingMail.mailItems)
			free(state->incomingMail.mailItems);
		state->incomingMail.mailItems = NULL;
		state->incomingMail.count = 0;
	}
	
	if(state->validFlags & kServerValidFlag_GameResults)
	{
		free((Ptr)state->gameResult);
	}
		
	state->validFlags = kServerValidFlag_None;
}
Пример #6
0
int Server_SendSetBoxPhoneNumber(ServerState *state, phoneNumber *newBoxPhoneNumber)
{
messOut			opCode;
phoneNumber		strippedPhoneNumber;
int				len;

#define STRIP_AREA_CODE
#ifdef STRIP_AREA_CODE
	len = strlen(newBoxPhoneNumber->phoneNumber);
	if (len < 8 || newBoxPhoneNumber->phoneNumber[len-5] != '-') {
		Logmsg("Set box phone number: I can't strip %s!\n",
			newBoxPhoneNumber->phoneNumber);

		// send original
		opCode = msSetBoxPhoneNumber;
		Server_TWriteDataSync(state->session, sizeof(messOut), (Ptr)&opCode);
		Server_TWriteDataSync(state->session, sizeof(phoneNumber), (Ptr)newBoxPhoneNumber);
	} else {
		strippedPhoneNumber = *newBoxPhoneNumber;	// get the extra fields
		strcpy(strippedPhoneNumber.phoneNumber,		// overwrite with last 8
			   newBoxPhoneNumber->phoneNumber +
				   strlen(newBoxPhoneNumber->phoneNumber) - 8);

		opCode = msSetBoxPhoneNumber;
		Server_TWriteDataSync(state->session, sizeof(messOut), (Ptr)&opCode);
		Server_TWriteDataSync(state->session, sizeof(phoneNumber), (Ptr)&strippedPhoneNumber);
	}

#else
	opCode = msSetBoxPhoneNumber;
	Server_TWriteDataSync(state->session, sizeof(messOut), (Ptr)&opCode);
	Server_TWriteDataSync(state->session, sizeof(phoneNumber), (Ptr)newBoxPhoneNumber);
#endif
	return(kServerFuncOK);
}
Пример #7
0
PreformedMessage *DataBase_GetSystemPatch(long version, long patchNum)
{
SDBSystem		*sys;
ListNode		*node;
SDBSystemNode	*sn;

	sys = SDB_GetSystem(gSDB);
	ASSERT(sys);

	ASSERT_MESG(patchNum >= 0, "Negative patch numbers are illegal");

	node = SearchList(sys->list, version);
	if(node)
	{
		sn = (SDBSystemNode *)GetListNodeData(node);
		ASSERT_MESG(patchNum < sn->numPatches, "Requested system patch number is out of range");
		if(patchNum >= sn->numPatches)
			return(NULL);	// big error
		
		return(sn->patches[patchNum]);
	}

	//WARNING_MESG("No such system version?!?");
	Logmsg("No such system version?!?\n");

	return(NULL);
}
Пример #8
0
// Send the player's rankings for every game he has played.
//
int Server_SendRanking(ServerState *state)
{
RankingType	*rankings;
RankingInfo *rankingInfo;
messOut		opCode;
DBID		id;
unsigned short		bodySize;
int i;

	Logmsg("Server_SendRanking\n");

	ASSERT(state->validFlags & kServerValidFlag_Account);
	if (!state->validFlags & kServerValidFlag_Account)
		return (kFucked);

	// For every entry in playerAccount.rankings, send them a description
	// of their rank.
	//
	for (i = 0; i < 2; i++) {		// BRAIN DAMAGE; should walk a list
		rankingInfo = &(state->account->playerAccount.rankingInfo[i]);

		if (!rankingInfo->gameID)
			continue;

		rankings = Server_BuildRanking(state, rankingInfo, &bodySize, &id);

		if (!rankings)
			continue;

		opCode = msReceiveRanking;
		Server_TWriteDataSync(state->session, sizeof(messOut), (Ptr)&opCode);
		Server_TWriteDataSync(state->session, sizeof(DBID), (Ptr)&id);
		Server_TWriteDataSync(state->session, sizeof(unsigned short), (Ptr)&bodySize);
		Server_TWriteDataSync(state->session, (long)bodySize, (Ptr)rankings);

		Logmsg("  Sent rankings for 0x%.8lx (%ld bytes, DBID=%ld)\n",
			rankings->gameID, (long)bodySize, (long)id);
		free(rankings);
	}


	if(Server_TCheckError() != noErr)
		return(kServerFuncAbort);
	Logmsg("Server_SendRanking done\n");

	return(kServerFuncOK);
}
Пример #9
0
//
// Same as Server_EndCommunication, except doesn't wait for the box to respond with own
// msEndOfStream.
//
// Unused 8/13/94
//
int Server_ForceEndCommunication(ServerState *state)
{
unsigned char opCode;

	Logmsg("Server_ForceEndCommunication\n");

	if(Server_DebugService(state) != kServerFuncOK)
		return(kServerFuncAbort);


	opCode = msEndOfStream;
	Server_TWriteDataSync(state->session, 1, (Ptr)&opCode );

	Logmsg("Server_ForceEndCommunication done\n");

	return(kServerFuncOK);
}
Пример #10
0
//
// Send a new problem token
//
int Server_SendProblemToken(ServerState *state)
{
unsigned long token;
unsigned char opCode;

	Logmsg("Server_SendProblemToken\n");

	token = 23;
	opCode = msReceiveProblemToken;
	Server_TWriteDataSync(state->session, 1, (Ptr)&opCode );
	Server_TWriteDataSync(state->session, sizeof(long), (Ptr)&token );

	if(Server_TCheckError() != noErr)
		return(kServerFuncAbort);

	Logmsg("Server_SendProblemToken done\n");

	return(kServerFuncOK);
}
Пример #11
0
int Server_SendDBConstants(ServerState *state, long numConsts, DBID *ids, long *constants)
{
messOut		opCode;

	Logmsg("Server_SendDBConstants\n");

	opCode = msSetConstants;
	Server_TWriteDataSync(state->session, sizeof(messOut), (Ptr)&opCode);

	Server_TWriteDataSync(state->session, sizeof(long), (Ptr)&numConsts);
	Server_TWriteDataSync(state->session, sizeof(DBID) * numConsts, (Ptr)ids);
	Server_TWriteDataSync(state->session, sizeof(long) * numConsts, (Ptr)constants);

	if(Server_TCheckError() != noErr)
		return(kServerFuncAbort);

	Logmsg("Server_SendDBConstants done\n");

	return(kServerFuncOK);
}
Пример #12
0
int Server_SendAddItemToDB(ServerState *state, DBType theType, DBID theID, long length, void *data)
{
messOut		opCode;

	Logmsg("Server_SendAddItemToDB\n");

	opCode = msAddItemToDB;
	Server_TWriteDataSync(state->session, sizeof(messOut), (Ptr)&opCode);

	Server_TWriteDataSync(state->session, sizeof(DBType), (Ptr)&theType);
	Server_TWriteDataSync(state->session, sizeof(DBID), (Ptr)&theID);
	Server_TWriteDataSync(state->session, sizeof(long), (Ptr)&length);
	Server_TWriteDataSync(state->session, length, (Ptr)data);

	if(Server_TCheckError() != noErr)
		return(kServerFuncAbort);

	Logmsg("Server_SendAddItemToDB done\n");

	return(kServerFuncOK);
}
Пример #13
0
long DataBase_GetLatestSystemVersion(void)
{
SDBSystem		*sys;
ListNode		*node;
SDBSystemNode	*sn;

	sys = SDB_GetSystem(gSDB);

	node = GetLastListNode(sys->list);
	if(node)
	{
		sn = (SDBSystemNode *)GetListNodeData(node);
		return(sn->version);
	}

	//WARNING_MESG("No loaded system version?");
	Logmsg("No loaded system version?\n");
	return(1);
}
Пример #14
0
long DataBase_GetSystemNumPatches(long version)
{
SDBSystem		*sys;
ListNode		*node;
SDBSystemNode	*sn;

	sys = SDB_GetSystem(gSDB);

	node = SearchList(sys->list, version);
	if(node)
	{
		sn = (SDBSystemNode *)GetListNodeData(node);
		return(sn->numPatches);
	}

	//WARNING_MESG("No such system version?!?");
	Logmsg("No such system version?!?\n");

	return(0);
}
Пример #15
0
int Server_SendSetLocalAccessPhoneNumber(ServerState *state, phoneNumber *newAccessPhoneNumber, phoneNumber *fallbackAccessPhoneNumber, Boolean redial)
{
messOut				opCode;
short				dialAgainFlag;
	opCode = msSetLocalAccessPhoneNumber;
	Server_TWriteDataSync(state->session, sizeof(messOut), (Ptr)&opCode);
	Server_TWriteDataSync(state->session, sizeof(phoneNumber), (Ptr)newAccessPhoneNumber);
	Server_TWriteDataSync(state->session, sizeof(phoneNumber), (Ptr)fallbackAccessPhoneNumber);

	if(redial)
		dialAgainFlag = kRedialTheNetwork;
	else
		dialAgainFlag = kDontRedialTheNetwork;
	Server_TWriteDataSync(state->session, sizeof(short), (Ptr)&dialAgainFlag);

	Logmsg("Sent LocalAccessNumber %s [%d]  fallback %s [%d]\n",
		newAccessPhoneNumber->phoneNumber, newAccessPhoneNumber->scriptID,
		fallbackAccessPhoneNumber->phoneNumber, fallbackAccessPhoneNumber->scriptID);

	return(kServerFuncOK);
}
Пример #16
0
int Shutdown(int errorcode, struct cfgoptions *arg)
{
	if (arg->options & NOACTION) {
		Logmsg(LOG_DEBUG, "shutdown() errorcode=%i, kexec=%s",
		       errorcode, arg->options & KEXEC ? "true" : "false");
		return 0;
	}

	if (errorcode != WECMDREBOOT && errorcode != WECMDRESET) {
		char buf[64] = { "\0" };
		snprintf(buf, sizeof(buf), "%d\n", errorcode);

		if (Spawn
		    (arg->repairBinTimeout, arg, arg->exepathname,
		     arg->exepathname, buf, NULL) == 0)
			return 0;
	}

	EndDaemon(arg, true);	//point of no return

	return NativeShutdown(errorcode, arg->options & KEXEC ? 1 : 0);
}
Пример #17
0
int Server_SendNGP()
{
/*
unsigned char 	opCode;
long			NGPVersion;

	Server_TReadDataSync( &aGame, 1, (Ptr)&opCode );
	if(opCode != msSendNGPVersion){
		// f****d
		return(kServerFuncAbort);
	}

	Server_TReadDataSync( &aGame, 4, (Ptr)&NGPVersion );


	Logmsg("NGP version = %ld\n", NGPVersion);
	Logmsg("Server_SendNGP done\n");
*/

	Logmsg("Server_SendNGP is totally f****d.  kill it!\n");

	return(kServerFuncOK);
}
Пример #18
0
Err SDBSystem_LoadSystemPatches(void)
{
long		count, version, patchnum;
char		str[kSDB_SystemPatchFilenameLength];
PreformedMessage	*msg;
char		noversion;

	version = 1;
	patchnum = 0;

	noversion = 1;
	count = 0;
	for(;;)
	{
		sprintf(str, "%s.%ld.%ld", kSDB_SystemPatchFilePrefix, version, patchnum);
		msg = PreformedMessage_ReadFromFile(str);
		if(!msg)
		{
			if(noversion)
				break;
			version++;
			patchnum = 0;
			noversion = 1;
			continue;
		}

		DataBase_AddSystemPatch(version, patchnum, msg);	// appropriates the patch... so we don't delete it here.

		patchnum++;
		count++;
		noversion = 0;
	}
	
	Logmsg("Read %ld patches, latest system version is %ld\n", count, version-1);

	return(kNoError);
}
Пример #19
0
long DataBase_GetLatestSystemKeyframeVersion(void)
{
SDBSystem		*sys;
ListNode		*node;
SDBSystemNode	*sn;

	sys = SDB_GetSystem(gSDB);

	// find the latest system version.
	// if it's not a keyframe, work backwards until we find one.
	//
	node = GetLastListNode(sys->list);
	while(node)
	{
		sn = (SDBSystemNode *)GetListNodeData(node);
		if(sn->keyframe == true)
			return(sn->version);
		node = GetPrevListNode(node);
	}

	//WARNING_MESG("No keyframe system version?");
	Logmsg("No keyframe system version?\n");
	return(1);
}
Пример #20
0
void DataBase_ReloadGamePatches(void)
{
	Logmsg("Reloading game patches\n");
	DataBase_LoadGamePatches();
}
Пример #21
0
int Server_StartGamePlay(ServerState *state)
{
	Contestant contestant;
	userIdentification challengeUserID;
	Matchup *matchup;
	RankingInfo *rankingInfo;
	Err err;
	char msg[256];
	int i;

	Logmsg("Server_StartGamePlay\n");

	ASSERT((state->validFlags & kServerValidFlag_Account));
	ASSERT((state->validFlags & kServerValidFlag_ChallengeOrCompete));

	if(state->disallowGameConnect)
	{
		Logmsg("REJECT: Game connect is disallowed.\n");
		return(kServerFuncOK);
	}

	if(state->challengeData.userID.box.box == kDownloadOnlyMailSerialNumber)
	{
		Statusmsg("SunSega: Mail-only connect from '%s' (%s)\n",
			state->loginData.userID.userName,
			state->account->boxAccount.gamePhone.phoneNumber);
		StatusPrintGameResults(state);
		return(kServerFuncOK);
	}


	// Set up the Contestant struct.
	//
	memset(&contestant, 0, sizeof(Contestant));
	contestant.gameID = state->gameIDData.gameID;
	contestant.boxSerialNumber = state->loginData.userID.box;
	contestant.player = state->loginData.userID.userID;
	strcpy(contestant.userName, state->loginData.userID.userName);
	contestant.boxPhoneNumber = state->account->boxAccount.gamePhone;
	if (state->challengeData.userID.box.box !=
		kFindNetworkOpponentSerialNumber)
	{
		contestant.challengeFlags = kSpecificChallenge;
	} else if (state->challengeData.userID.box.box ==
			   kFindNetworkOpponentSerialNumber)
	{
		if (state->account->playerAccount.playerFlags & kPlayerFlags_acceptChallenges)
			contestant.challengeFlags = kAcceptChallenges;
		else
			contestant.challengeFlags = kIgnoreChallenges;
	} else {
		Logmsg("Invalid state->challengeData.userID.box.box\n");
		return (kServerFuncAbort);
	}
	contestant.callLongDistance =
		((state->account->boxAccount.boxFlags & kBoxFlags_dialLongDistance)!=0);
	contestant.romID = state->boxOSState.boxType;	// not used anymore

	// The "opp" fields get the desired opponent's identification if it's
	// a specific match request, or the previous opponent's identification
	// if it's an auto-match request.
	//
	if (contestant.challengeFlags == kSpecificChallenge) {
		// specific request
		//
		contestant.oppBoxSerialNumber = state->challengeData.userID.box;
		contestant.oppPlayer = state->challengeData.userID.userID;

		// he wants to challenge a specific player.
		// check if that is a valid playerID.
		
		if (DataBase_FindUserIdentification(&state->challengeData.userID,
			&challengeUserID) != kNoError)
		{		
			// Barf back to the dude... no such user.
			sprintf(msg, "There is no player named %s on XBAND.  You have not been registered to play.", state->challengeData.userID.userName);
			Server_SendDialog(state, msg, true);
			return(kServerFuncOK);
		}
		
		// Do UserIDs match exactly? (box + player#)
		if (Database_CompareUserIdentifications(&challengeUserID,
			&state->loginData.userID))
		{
			Server_SendDialog(state, "Come on - you can't play yourself!  You have not been registered to play.", true);
			return(kServerFuncOK);
		}
		// Do the BoxSerialNumbers match? (just box)
		if (Database_CompareBoxSerialNumbers(&challengeUserID.box,
			&state->loginData.userID.box))
		{
			Server_SendDialog(state, "You can't play against someone on your own box!  You have not been registered to play.", true);
			return(kServerFuncOK);
		}

		contestant.oppBoxSerialNumber = challengeUserID.box;
		contestant.oppPlayer = challengeUserID.userID;

	} else {
		// auto-match requests
		//
		// BRAIN DAMAGE: fill this in correctly
		contestant.oppBoxSerialNumber.box = -1;
		contestant.oppBoxSerialNumber.region = -1;
		contestant.oppPlayer = -1;
	}

	// The "rankingInfo" field needs the ranking data for this game, if
	// any.  If the user has never played before, we need to pass in a
	// zeroed-out rankingInfo struct with a correct gameID.
	//
	// BRAIN DAMAGE: use the fake rankingInfo stuff for now
	//
	for (i = 0; i < 2; i++) {
		rankingInfo = &(state->account->playerAccount.rankingInfo[i]);

		if (rankingInfo->gameID == contestant.gameID) {
			contestant.rankingInfo = *rankingInfo;
			break;
		}
	}
	if (i == 2) {
		Logmsg("No rankingInfo for gameID 0x%.8lx, passing in empty one\n",
			contestant.gameID);
		memset(&contestant.rankingInfo, 0, sizeof(RankingInfo));
		contestant.rankingInfo.gameID = contestant.gameID;
	}


	// One-stop shopping.
	//
	matchup = RPC_FindMatch(&contestant);

	if (matchup == NULL) {
		// wow
		sprintf(msg, "Player matching appears to be down.  Try again later.");
		Server_SendDialog(state, msg, true);
		return(kServerFuncOK);
	}

	// If we got a phone number back (or even if we didn't), and the
	// "dial 9 to get out" hack is in effect, prepend "9,".
	if (state->account->boxAccount.debug1 & 1) {
		phoneNumber tmpPhoneNumber;
		strcpy(tmpPhoneNumber.phoneNumber, matchup->oppPhoneNumber.phoneNumber);
		strcpy(matchup->oppPhoneNumber.phoneNumber, "9,");
		strcat(matchup->oppPhoneNumber.phoneNumber, tmpPhoneNumber.phoneNumber);
	}


	// Generic errors.
	//
	if (matchup->result == kInvalidArguments) {
		sprintf(msg, "Looks like something is messed up in the server.  Unable to match you with anyone.");
		Server_SendDialog(state, msg, true);
		return(kServerFuncOK);
	}
	if (matchup->result == kInvalidPhoneNumber) {
		sprintf(msg, "Looks like something is messed up in the server.  The matcher can't understand your phone number.");
		Server_SendDialog(state, msg, true);
		return(kServerFuncOK);
	}

	// Handle errors based on what we tried to do.
	//
	if (contestant.challengeFlags == kSpecificChallenge) {
		// Was a specific match request.
		//
		if (matchup->result == kMatchDial)
		{
			Logmsg("*** Sending Opponent Phone Number : %s (cookie=%ld)\n",
				matchup->oppPhoneNumber.phoneNumber, matchup->oppMagicCookie);
			Statusmsg("SunSega: '%s' (%s) told to challenge '%s' (%s) for %s\n",
				contestant.userName,
				contestant.boxPhoneNumber.phoneNumber,
				matchup->oppUserName,
				matchup->oppPhoneNumber.phoneNumber,
				Common_GameName(contestant.gameID));
			StatusPrintGameResults(state);
			Server_SendOpponentNameString(state, matchup->oppUserName);
			return (Server_SendOpponentPhoneNumber(state,
				&matchup->oppPhoneNumber, matchup->oppMagicCookie));
		}
		
		if (matchup->result == kChallengeeWaitingForDifferentGame)
		{		
			sprintf(msg, "You can't play %s, because they have a different game cartridge installed.  You have not been registered to play.", challengeUserID.userName);
			Server_SendDialog(state, msg, true);
			return(kServerFuncOK);
		}
		
		if (matchup->result == kChallengeeWaitingForDifferentUser)
		{
			sprintf(msg, "You can't play %s, because they have registered to play someone else.  You have not been registered to play.", challengeUserID.userName);
			Server_SendDialog(state, msg, true);
			return(kServerFuncOK);
		}
	
		if (matchup->result == kChallengeeWaitingForAutoMatch)
		{
			// BRAIN DAMAGE.  If the other player accepts challenges, we should match you together.
			//
			sprintf(msg, "You can't play %s, because they are waiting to play a challenge game.  You have not been registered to play.", challengeUserID.userName);
			Server_SendLargeDialog(state, msg, true);
			return(kServerFuncOK);
		}

		if (matchup->result == kDifferentRomVersion)
		{
			sprintf(msg, "You can't play %s, because they have a different XBAND ROM revision.", challengeUserID.userName);
			Server_SendDialog(state, msg, true);
			return(kServerFuncOK);
		}

		if (matchup->result != kMatchWait) {
			Logmsg("specific-Matching_FindMatch returned error %ld\n",
				matchup->result);
			sprintf(msg, "Your challenge request could not be completed\n");
			Server_SendDialog(state, msg, true);
			return(kServerFuncOK);
		}
		
		// bummer.  that dude isn't online, fall out into wait handler

	} else {
		// Was an auto-match request.
		//
		if (matchup->result == kMatchDial)
		{
			Logmsg("*** Sending Opponent Phone Number : %s (cookie=%ld)\n",
				matchup->oppPhoneNumber.phoneNumber, matchup->oppMagicCookie);
			Statusmsg("SunSega: '%s' (%s) told to call '%s' (%s) for %s\n",
				contestant.userName,
				contestant.boxPhoneNumber.phoneNumber,
				matchup->oppUserName,
				matchup->oppPhoneNumber.phoneNumber,
				Common_GameName(contestant.gameID));
			StatusPrintGameResults(state);
			Server_SendOpponentNameString(state, matchup->oppUserName);
			return(Server_SendOpponentPhoneNumber(state,
				&matchup->oppPhoneNumber, matchup->oppMagicCookie));
		}

		if (matchup->result != kMatchWait) {
			Logmsg("auto-Matching_FindMatch returned error %ld\n",
				matchup->result);
			sprintf(msg, "Your challenge request could not be completed\n");
			Server_SendDialog(state, msg, true);
			return(kServerFuncOK);
		}
	}

	// Used to be sendwaitforopponent
	//
	if (matchup->result == kMatchWait)
	{		
		// Tell the box to wait for a call.
		//
		Logmsg("@@@ Wait For Opponent (my cookie=%ld)\n", matchup->magicCookie);
		if (contestant.challengeFlags == kSpecificChallenge) {
			Statusmsg("SunSega: '%s' (%s) waiting for %s challenge with %s\n",
				contestant.userName,
				contestant.boxPhoneNumber.phoneNumber,
				Common_GameName(contestant.gameID),
				challengeUserID.userName);
			StatusPrintGameResults(state);
		} else {
			Statusmsg("SunSega: '%s' (%s) waiting for %s\n",
				contestant.userName,
				contestant.boxPhoneNumber.phoneNumber,
				Common_GameName(contestant.gameID));
			StatusPrintGameResults(state);
		}
		err = Server_SendWaitForOpponent(state, matchup->magicCookie);
		if (err == kServerFuncOK)
		{
			char gameName[kGameNameSize];
		
			if (!DataBase_GetGameName(contestant.gameID, gameName))
			{
				Logmsg("Server_StartGamePlay Impl Error: game 0x%.8lx has no name in the DB??\n", contestant.gameID);
				gameName[0] = 0;
			}

			if (contestant.challengeFlags != kSpecificChallenge)
			{
				err = Server_SendRegisterPlayer(state,
					kBoxWaitForOpponentTimeout, gameName);
			}
			else
			{
				err = Server_SendRegisterChallengePlayer(state,
					kBoxWaitForOpponentTimeout, gameName,
					challengeUserID.userName);
			}
			
			return(err);
		}
		else
		{
			Logmsg("Server_SendWaitForOpponent returned error %ld\n", err);
			return(kServerFuncAbort);
		}
	}
}
Пример #22
0
void ServerState_Print(ServerState *state)
{
	if(state->validFlags & kServerValidFlag_Login)
	{
		Logmsg("Login Data:\n");
		ServerState_PrintUserIdentification(&state->loginData.userID);
		Logmsg("	Phone number = %s\n", state->boxPhoneNumber.phoneNumber);
	} else
		Logmsg("Login Data is invalid\n");
	
	if(state->validFlags & kServerValidFlag_ChallengeOrCompete)
	{
		if(state->challengeData.userID.box.box == -3) {
			Logmsg("Mail only connection\n");
			//Statusmsg("SunSega: Mail-only connect from '%s' (%s)\n",
			//	state->loginData.userID.userName,
			//	state->boxPhoneNumber.phoneNumber);
			//StatusPrintGameResults(state);
		} else if(state->challengeData.userID.box.box == -2)
			Logmsg("Normal competitive game request\n");
		else
		{
			Logmsg("Challenge Request:\n");
			ServerState_PrintUserIdentification(&state->challengeData.userID);
		}
	} else
		Logmsg("ChallengeOrCompete is invalid\n");
	
	if(state->validFlags & kServerValidFlag_SystemVersion)
	{
		Logmsg("System Version:\n");
		Logmsg("	length = %d, version = %ld\n", state->systemVersionData.length, state->systemVersionData.version);
	} else
		Logmsg("System Version is invalid\n");

	if(state->validFlags & kServerValidFlag_NGPVersion)
	{
		Logmsg("NGP Version = %ld\n", state->NGPVersion);
	} else
		Logmsg("NGP Version is invalid\n");
	
	if(state->validFlags & kServerValidFlag_GameID)
	{
		Logmsg("Game ID:\n");
		Logmsg("	gameID = 0x%.8lx, version = %ld\n", state->gameIDData.gameID, state->gameIDData.version);
	} else
		Logmsg("Game ID is invalid\n");

	if(	state->validFlags & kServerValidFlag_SendQ)
	{
		long i;
		
		Logmsg("SendQ Count = %d:\n", state->sendQData.count);
		for(i = 0; i < state->sendQData.count; i++){
			Logmsg("	Item %ld:\n", i);
			Logmsg("		Type = %ld, Size = %ld\n",
							(long)state->sendQData.items[i].theID,
							state->sendQData.items[i].size);
		}
	} else 
		Logmsg("SendQ is invalid\n");

	if(state->validFlags & kServerValidFlag_IncomingMail)
	{		
		Logmsg("Incoming Mail count = %ld\n", (long)state->incomingMail.count);
	}

}
Пример #23
0
/*
	This treat can use the info in ServerState to do lookups to send targetted information
	such as:
		ranking specicific mail
		game specific info (eg. realtime NBA scores and stats)
		ads
	
*/
int Server_DownloadKoolStuff(ServerState *state)
{
PreformedMessage	*preformed;
ServerNewsPage		*page;
long				numPages, a, b;
OSErr				err;
DBType				pagetype;
DBID				id;
long				countdown;
Boolean				sentNews = false;

	Logmsg("Server_DownloadKoolStuff\n");
	if(Server_DebugService(state) != kServerFuncOK)
		return(kServerFuncAbort);


//
/////////////////////////////////////////
//
// BRAIN DAMAGE.
// Set some DBConstants for ted.  These should be done by Topping's tool.
//
	id = kListenCallWaitingTimeConst;
	countdown = 5;
	if(Server_SendDBConstants(state, 1, &id, &countdown) != kServerFuncOK)
		return(kServerFuncAbort);

	id = kDBTransportTickleConst;
	countdown = 5;
	if(Server_SendDBConstants(state, 1, &id, &countdown) != kServerFuncOK)
		return(kServerFuncAbort);
//
/////////////////////////////////////////
//





	Server_SetTransportHold(true);

	id = kNewsCountdownConst;
	countdown = 60L << 16;	// ticks per count
	countdown |= 30;		// the count value (30 sec)
	if(Server_SendDBConstants(state, 1, &id, &countdown) != kServerFuncOK)
		return(kServerFuncAbort);

	//
	// Send the general daily news (everyone gets this)
	// Send the targetted Other news (game specific, etc)
	//
//abort();	// makes TransportLayer blow up cuz TUUnthread never called if error is found by TIndication

	for(b = 0; b < 2; b++)
	{
		if(b == 1)
			pagetype = kOtherNews;
		else
			pagetype = kDailyNews;

		numPages = DataBase_GetNumNewsPages(pagetype);
		if (numPages < 0 || numPages > 64) {
			Logmsg("ERROR: got bogus numPages %ld in Server_DownloadKoolStuff\n",
				numPages);
			return (kServerFuncAbort);
		}

		for(a = 0; a < numPages; a++)
		{
			sentNews = true;

			page = DataBase_GetNewsPage(a, pagetype);
	
			ASSERT(page);
			if(!a)
				err = Server_SendFirstNewsPage( state, page);
			else
				err = Server_SendNewsPage(state, page);
		
			DataBase_ReleaseServerNewsPage( page);
			
			if(err != kServerFuncOK)
				return(kServerFuncAbort);
		}
	}

	if(!sentNews)
		Server_SendNoNewsPage(state, kDailyNews);	// Box doesn't care about the pagetype, so anything will do.


	//
	// If you want to speed up the countdown, you can change the ticks per count.
	// The count value cannot be changed after the timer starts.
	//
	countdown = 60L << 16;	// ticks per count (you would change this to change tick speed)
	countdown |= 120;		// the count value (ignored after timer is started)
	if(Server_SendDBConstants(state, 1, &id, &countdown) != kServerFuncOK)
		return(kServerFuncAbort);


	Server_SetTransportHold(false);

/*
	preformed = DataBase_GetKoolStuff();
	if(preformed)
	{
// BROKEN NOGGIN.... 
//		Server_SendPreformedMessage(state, preformed);
		DataBase_ReleasePreformedMessage(preformed);
	}
*/

	return(kServerFuncOK);
}
Пример #24
0
// Given the player's current standings, generate the ranking data.
// Returns a pointer to newly malloc()ed memory, which must be freed
// by the caller.
//
// Returns NULL if unable to complete the request.
//
RankingType *Server_BuildRanking(ServerState *state, RankingInfo *rankingInfo, unsigned short *bodySize, DBID *idp)
{
	RankingType *rankings, metric;
	GameInfo *gameInfo;
	long numGames, gameID;
	int i, gm, rk, nextrk;
	char numBuf1[11], numBuf2[11], strBuf[64];
	char *vector[kNumRankStrings];
	unsigned char *ucp, *metric1, *metric2;
	unsigned short *usp;
	unsigned short size;

	if ((gameInfo = Common_GetGameInfo(&numGames)) == NULL) {
		Logmsg("WHOA: couldn't get GameInfo; Very Bad\n");
		return (NULL);
	}

	gameID = rankingInfo->gameID;		// ID to search for; affected by aliases

	for (gm = 0; gm < numGames; gm++) {
		if (gameInfo[gm].gameID == gameID) {
			if (gameInfo[gm].alias != 0) {
				// found an alias; change gameID and start over
				gameID = gameInfo[gm].alias;
				gm = -1;
				continue;
			}

			// found the game, find the right rank
			for (rk = 0; rk < gameInfo[gm].numRanks; rk++) {
				if (gameInfo[gm].ranks[rk].xpoints > rankingInfo->xpoints) {
					// we passed it, use the previous one
					nextrk = rk;
					rk--;
					break;
				}
			}
			if (rk == gameInfo[gm].numRanks) {	// highest rank?
				rk--;			// make this equal highest rank
				nextrk = rk;	// can't go any higher
			}

			break;
		}
	}
	if (gm == numGames) {
		Logmsg("Unable to find rank chart for %.8lx\n", rankingInfo->gameID);
		goto bail;
	}

	// XBAND Points
	sprintf(numBuf1, "%d", rankingInfo->xpoints);

	// Points Needed
	if (rk == nextrk)
		strcpy(numBuf2, "---");		// can't go no higher
	else
		sprintf(numBuf2, "%d",
			gameInfo[gm].ranks[nextrk].xpoints - rankingInfo->xpoints);

	vector[0] = gameInfo[gm].gameName;
	vector[1] = gameInfo[gm].ranks[rk].rankName;
	vector[2] = numBuf1;
	if (rk == nextrk)
		vector[3] = "---";			// that's all, folks!
	else
		vector[3] = gameInfo[gm].ranks[nextrk].rankName;
	vector[4] = numBuf2;

	Logmsg("Rank for 0x%.8lx: %s %s %s %s %s\n", rankingInfo->gameID,
		vector[0], vector[1], vector[2], vector[3], vector[4]);

	size = 0;
	for(i = 0; i < kNumRankStrings; i++)
		size += strlen(vector[i]) + 1;
	//size += sizeof(RankingType) - 1;
	// sizeof won't work; it's a 7 byte structure, but sizeof tells us
	// that it's 8 to keep things happy
	metric1 = (unsigned char *)&metric;
	metric2 = (unsigned char *)&(metric.rankData[0]);
	size += (metric2 - metric1);

	rankings = (RankingType *)malloc((long)size + kSecretChunk);

	rankings->gameID = 			gameID;		// use aliased gameID here
	rankings->userID = 			state->loginData.userID.userID;

	PackStrings(rankings->rankData, kNumRankStrings, vector);

	// Set up the secret rankings.  Right now, every game gets two.  All
	// of this stuff has to fit within kSecretChunk bytes.
	//
	rankings->numHiddenStats = 2;
	if (rankings->gameID == kNBAJamGameID || rankings->gameID == 0x39677bdb)
		rankings->numHiddenStats++;		// ATM

	// first secret rank: total points
	size += (size & 1);		// 16-bit word-align
	ucp = (unsigned char *)rankings;
	ucp += size;

	*ucp++ = 2, size++;		// make it a two-key sequence
	*ucp++ = 0, size++;		// pad
	usp = (unsigned short *) ucp;
	*usp++ = kUP, size += 2;
	*usp++ = kUP, size += 2;
	ucp = (unsigned char *) usp;
	sprintf(strBuf, "Total points for: %ld, against: %ld",
		rankingInfo->pointsFor, rankingInfo->pointsAgainst);
	strcpy((char *)ucp, strBuf);
	ucp += strlen(strBuf) +1, size += strlen(strBuf) +1;
	size += (size & 1);		// 16-bit word-align

	// second secret rank: win/loss, and my opinion
	size += (size & 1);		// 16-bit word-align
	ucp = (unsigned char *)rankings;
	ucp += size;

	*ucp++ = 2, size++;		// make it a two-key sequence
	*ucp++ = 0, size++;		// pad
	usp = (unsigned short *) ucp;
	*usp++ = kUP, size += 2;
	*usp++ = kDOWN, size += 2;
	ucp = (unsigned char *) usp;
	sprintf(strBuf, "Total wins: %ld, losses: %ld",
		rankingInfo->wins, rankingInfo->losses);
	if (rankingInfo->wins > rankingInfo->losses)
		strcat(strBuf, " (you rewl)");
	else
		strcat(strBuf, " (you suck)");
	strcpy((char *)ucp, strBuf);
	ucp += strlen(strBuf) +1, size += strlen(strBuf) +1;
	size += (size & 1);		// 16-bit word-align

	// third secret rank: only for NBA Jam
	if (rankings->numHiddenStats > 2) {
		size += (size & 1);		// 16-bit word-align
		ucp = (unsigned char *)rankings;
		ucp += size;

		*ucp++ = 7, size++;		// try 7 keys; max is 16 (up/down only sucks)
		*ucp++ = 0, size++;		// pad
		usp = (unsigned short *) ucp;
		//*usp++ = kDOWN, size += 2;
		*usp++ = kDOWN | kLEFT, size += 2;
		*usp++ = kDOWN, size += 2;
		*usp++ = kDOWN, size += 2;
		*usp++ = kDOWN, size += 2;
		*usp++ = kDOWN, size += 2;
		*usp++ = kDOWN, size += 2;
		*usp++ = kUP, size += 2;
		ucp = (unsigned char *) usp;
		strcpy(strBuf, "Dave, Brian, & Andy2 were here");
		strcpy((char *)ucp, strBuf);
		ucp += strlen(strBuf) +1, size += strlen(strBuf) +1;
		size += (size & 1);		// 16-bit word-align
	}

	// All done!
	*bodySize = size;
	*idp = gameInfo[gm].gameID;
	Common_FreeGameInfo(gameInfo);
	return (rankings);

bail:
	Common_FreeGameInfo(gameInfo);
	return (NULL);
}
Пример #25
0
//
// Load game patches
//
void DataBase_LoadGamePatches(void)
{
	PreformedMessage	msg;
	PatchDescriptor		descr;
	GameInfo		*gameInfo;
	SDBGameNode		*game;
	unsigned char	*start, *end;
	FILE		*fp = NULL;
	messOut		opCode;
	char		buf[32], *cp;
	long 		hdrLength, fullLength;
	long		numGames;
	int			i;

	if ((fp = fopen(kSDB_GamePatchFile, "rb")) == NULL) {
		Logmsg("Unable to open game patch file '%s'\n", kSDB_GamePatchFile);
		goto nofile;
	}

	if ((gameInfo = Common_GetGameInfo(&numGames)) == NULL) {
		// this is Very Bad
		Logmsg("Unable to get GameInfo\n");
		return;
	}

	// don't use sizeof(PatchDescriptor); has dangler on end
	start = (unsigned char *) &descr;
	end = (unsigned char *) &descr.data;

	while (1) {
		// This ought to be done in PreformedMessage.c, somehow.
		//
		if (fread(&opCode, sizeof(opCode), 1, fp) != 1)
			break;
		if (feof(fp))
			break;
		if (opCode != msGamePatch) {
			Logmsg("Wrong opCode in game patch file!  Wanted %ld, got %ld\n",
				(long)msGamePatch, (long)opCode);
			goto nofile;
		}
		if (fread(&descr, end-start, 1, fp) != 1) {
			Logmsg("Unexpected EOF in game patch read\n");
			goto nofile;
		}

		// find the game's name
		cp = NULL;
		for (i = 0; i < numGames; i++) {
			if (descr.gameID == gameInfo[i].gameID) {
				cp = gameInfo[i].gameName;
				break;
			}
		}
		if (i < numGames) {
			gameInfo[i].patchVersion = descr.patchVersion;
			if (!gameInfo[i].patchVersion)
				Logmsg("WHOA: found a game patch with version 0, ID = 0x%.8lx\n",
					descr.gameID);
		} else {
				sprintf(buf, "Unknown 0x%.8lx", descr.gameID);
				cp = buf;
		}

		hdrLength = sizeof(messOut) + end-start;
		fullLength = descr.codeSize + hdrLength;
		msg.message = (Ptr)malloc((size_t)fullLength);
		ASSERT(msg.message);

		// copy the header bits over
		memcpy(msg.message, &opCode, sizeof(messOut));
		memcpy(msg.message + sizeof(messOut), &descr, end-start);

		// read what's left; set length to whole thing
		msg.length = fullLength;
		if (fread(msg.message + hdrLength, descr.codeSize, 1, fp) != 1) {
			Logmsg("Unexpected EOF in game Patch read\n");
			goto nofile;
		}

		if ((game = Database_FindGame(descr.gameID, true)) == NULL) {
			// haven't seen this before
			DataBase_NewGame(descr.gameID, descr.patchVersion, cp, &msg);
			Logmsg("Added patch for 0x%.8lx (%s) version %ld (length = %ld)\n",
				descr.gameID, cp, (long)descr.patchVersion,
				(long)descr.codeSize);
		} else {
			// been there, done that, just replace the patch if it needs it
			if (descr.patchVersion > game->version) {
				DataBase_AddGamePatch(descr.gameID, descr.patchVersion, &msg);
				Logmsg("Replaced patch for 0x%.8lx (%s) version %ld (length = %ld)\n",
					descr.gameID, cp, (long)descr.patchVersion,
					(long)descr.codeSize);
			} else {
				Logmsg("Patch for 0x%.8lx (%s) version %ld is current\n",
					descr.gameID, cp, (long)descr.patchVersion);
			}
		}

		free(msg.message);
	}


nofile:		// get here if no file to read, or file was hosed

	if (fp != NULL)
		fclose(fp);

	// Now we need to call DataBase_NewGame on all the games that *don't*
	// have patches and therefore weren't initialized above.
	//
	for (i = 0; i < numGames; i++) {
		if (!gameInfo[i].patchVersion) {
			if ((game = Database_FindGame(gameInfo[i].gameID, true)) == NULL) {
				DataBase_NewGame(gameInfo[i].gameID, 1, gameInfo[i].gameName, NULL);
				Logmsg("No patch for 0x%.8lx (%s), assigned version %ld\n",
					gameInfo[i].gameID, gameInfo[i].gameName, 1);
			} else {
				Logmsg("No patch for 0x%.8lx (%s) version %ld\n",
					gameInfo[i].gameID, gameInfo[i].gameName, game->version);
			}
		}
	}

	Common_FreeGameInfo(gameInfo);
}