mirror of
				https://github.com/KartKrewDev/RingRacers.git
				synced 2025-10-30 08:01:28 +00:00 
			
		
		
		
	Merge branch 'dedi-final' into 'master'
Final work for Dedicated Servers See merge request KartKrew/Kart!2275
This commit is contained in:
		
						commit
						25e728fd33
					
				
					 8 changed files with 161 additions and 74 deletions
				
			
		|  | @ -3382,8 +3382,7 @@ void SV_ResetServer(void) | |||
| 
 | ||||
| 	// Copy our unlocks to a place where net material can grab at/overwrite them safely.
 | ||||
| 	// (permits all unlocks in dedicated)
 | ||||
| 	for (i = 0; i < MAXUNLOCKABLES; i++) | ||||
| 		netUnlocked[i] = (dedicated || gamedata->unlocked[i]); | ||||
| 	M_SetNetUnlocked(); | ||||
| 
 | ||||
| 	expectChallenge = false; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1538,6 +1538,19 @@ void D_SRB2Main(void) | |||
| 
 | ||||
| 	// for dedicated server
 | ||||
| 	dedicated = M_CheckParm("-dedicated") != 0; | ||||
| 	if (dedicated) | ||||
| 	{ | ||||
| 		p = M_CheckParm("-spoilers"); | ||||
| 		if (p && M_IsNextParm()) | ||||
| 		{ | ||||
| 			usedTourney = M_TryExactPassword(M_GetNextParm(), "XpsOixVTZSW0cwbiYAVgzokAmWfeYNq5mEckVsktheq4GOUWQecF5lWTkGNBJtoYX9vUMprFzraSovOSCeQ96Q=="); | ||||
| 
 | ||||
| 			if (usedTourney) | ||||
| 			{ | ||||
| 				CONS_Printf(M_GetText("Spoiler mode ON.\n")); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (devparm) | ||||
| 		CONS_Printf(M_GetText("Development mode ON.\n")); | ||||
|  | @ -1932,7 +1945,7 @@ void D_SRB2Main(void) | |||
| 		} | ||||
| 
 | ||||
| 		{ | ||||
| 			if (!M_CheckParm("-server") && !M_CheckParm("-dedicated")) | ||||
| 			if (!M_CheckParm("-server") && !dedicated) | ||||
| 			{ | ||||
| 				G_SetUsedCheats(); | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										40
									
								
								src/g_game.c
									
										
									
									
									
								
							
							
						
						
									
										40
									
								
								src/g_game.c
									
										
									
									
									
								
							|  | @ -3640,12 +3640,12 @@ static INT32 TOLMaps(UINT8 pgametype) | |||
| 				// Not completed
 | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 			if (M_MapLocked(i + 1) == true) | ||||
| 			{ | ||||
| 				// We haven't earned this one.
 | ||||
| 				continue; | ||||
| 			} | ||||
| 		if (M_MapLocked(i + 1) == true) | ||||
| 		{ | ||||
| 			// We haven't earned this one.
 | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		num++; | ||||
|  | @ -3753,12 +3753,12 @@ tryAgain: | |||
| 				// Not completed
 | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 			if (M_MapLocked(i + 1) == true) | ||||
| 			{ | ||||
| 				// We haven't earned this one.
 | ||||
| 				continue; | ||||
| 			} | ||||
| 		if (M_MapLocked(i + 1) == true) | ||||
| 		{ | ||||
| 			// We haven't earned this one.
 | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if (ignoreBuffers == false) | ||||
|  | @ -4331,12 +4331,12 @@ void G_GetNextMap(void) | |||
| 							// Not completed
 | ||||
| 							continue; | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 						if (M_MapLocked(cm + 1) == true) | ||||
| 						{ | ||||
| 							// We haven't earned this one.
 | ||||
| 							continue; | ||||
| 						} | ||||
| 					if (M_MapLocked(cm + 1) == true) | ||||
| 					{ | ||||
| 						// We haven't earned this one.
 | ||||
| 						continue; | ||||
| 					} | ||||
| 
 | ||||
| 					// If the map is in multiple cups, only consider the first one valid.
 | ||||
|  | @ -4416,12 +4416,12 @@ void G_GetNextMap(void) | |||
| 						// Not completed
 | ||||
| 						continue; | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 					if (M_MapLocked(cm + 1) == true) | ||||
| 					{ | ||||
| 						// We haven't earned this one.
 | ||||
| 						continue; | ||||
| 					} | ||||
| 				if (M_MapLocked(cm + 1) == true) | ||||
| 				{ | ||||
| 					// We haven't earned this one.
 | ||||
| 					continue; | ||||
| 				} | ||||
| 
 | ||||
| 				break; | ||||
|  |  | |||
							
								
								
									
										73
									
								
								src/m_cond.c
									
										
									
									
									
								
							
							
						
						
									
										73
									
								
								src/m_cond.c
									
										
									
									
									
								
							|  | @ -734,8 +734,7 @@ void M_ClearSecrets(void) | |||
| 	memset(gamedata->collected, 0, sizeof(gamedata->collected)); | ||||
| 	memset(gamedata->unlocked, 0, sizeof(gamedata->unlocked)); | ||||
| 	memset(gamedata->unlockpending, 0, sizeof(gamedata->unlockpending)); | ||||
| 	if (!dedicated) | ||||
| 		memset(netUnlocked, 0, sizeof(netUnlocked)); | ||||
| 	memset(netUnlocked, 0, sizeof(netUnlocked)); | ||||
| 	memset(gamedata->achieved, 0, sizeof(gamedata->achieved)); | ||||
| 
 | ||||
| 	Z_Free(gamedata->spraycans); | ||||
|  | @ -1281,6 +1280,66 @@ void M_FinaliseGameData(void) | |||
| 	M_UpdateUnlockablesAndExtraEmblems(false, true); | ||||
| } | ||||
| 
 | ||||
| void M_SetNetUnlocked(void) | ||||
| { | ||||
| 	UINT16 i; | ||||
| 
 | ||||
| 	// Use your gamedata as baseline
 | ||||
| 	for (i = 0; i < MAXUNLOCKABLES; i++) | ||||
| 	{ | ||||
| 		netUnlocked[i] = gamedata->unlocked[i]; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!dedicated) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	// Dedicated spoiler password - tournament mode equivalent.
 | ||||
| 	if (usedTourney) | ||||
| 	{ | ||||
| 		for (i = 0; i < MAXUNLOCKABLES; i++) | ||||
| 		{ | ||||
| 			if (unlockables[i].conditionset == 55) | ||||
| 				continue; | ||||
| 
 | ||||
| 			netUnlocked[i] = true; | ||||
| 		} | ||||
| 
 | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	// Okay, now it's dedicated first-week spoilerless behaviour.
 | ||||
| 	for (i = 0; i < MAXUNLOCKABLES; i++) | ||||
| 	{ | ||||
| 		if (netUnlocked[i]) | ||||
| 			continue; | ||||
| 
 | ||||
| 		switch (unlockables[i].type) | ||||
| 		{ | ||||
| 			case SECRET_CUP: | ||||
| 			{ | ||||
| 				// Give the first seven Cups for free.
 | ||||
| 				cupheader_t *cup = M_UnlockableCup(&unlockables[i]); | ||||
| 				if (cup && cup->id < 7) | ||||
| 					netUnlocked[i] = true; | ||||
| 
 | ||||
| 				break; | ||||
| 			} | ||||
| 			case SECRET_ADDONS: | ||||
| 			{ | ||||
| 				netUnlocked[i] = true; | ||||
| 				break; | ||||
| 			} | ||||
| 			default: | ||||
| 			{ | ||||
| 				// Most stuff isn't given to dedis for free
 | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // ----------------------
 | ||||
| // Condition set checking
 | ||||
| // ----------------------
 | ||||
|  | @ -3404,11 +3463,6 @@ boolean M_SecretUnlocked(INT32 type, boolean local) | |||
| 
 | ||||
| boolean M_CupLocked(cupheader_t *cup) | ||||
| { | ||||
| 	// Don't lock maps in dedicated servers.
 | ||||
| 	// That just makes hosts' lives hell.
 | ||||
| 	if (dedicated) | ||||
| 		return false; | ||||
| 
 | ||||
| 	// No skipping over any part of your marathon.
 | ||||
| 	if (marathonmode) | ||||
| 		return false; | ||||
|  | @ -3464,11 +3518,6 @@ boolean M_CupSecondRowLocked(void) | |||
| 
 | ||||
| boolean M_MapLocked(UINT16 mapnum) | ||||
| { | ||||
| 	// Don't lock maps in dedicated servers.
 | ||||
| 	// That just makes hosts' lives hell.
 | ||||
| 	if (dedicated) | ||||
| 		return false; | ||||
| 
 | ||||
| 	// No skipping over any part of your marathon.
 | ||||
| 	if (marathonmode) | ||||
| 		return false; | ||||
|  |  | |||
|  | @ -443,6 +443,7 @@ void M_ClearConditionSet(UINT16 set); | |||
| void M_ClearSecrets(void); | ||||
| void M_ClearStats(void); | ||||
| void M_FinaliseGameData(void); | ||||
| void M_SetNetUnlocked(void); | ||||
| 
 | ||||
| boolean M_NotFreePlay(void); | ||||
| UINT16 M_CheckCupEmeralds(UINT8 difficulty); | ||||
|  |  | |||
							
								
								
									
										33
									
								
								src/m_pw.cpp
									
										
									
									
									
								
							
							
						
						
									
										33
									
								
								src/m_pw.cpp
									
										
									
									
									
								
							|  | @ -43,22 +43,21 @@ namespace | |||
| 
 | ||||
| constexpr const UINT8 kRRSalt[17] = "0L4rlK}{9ay6'VJS"; | ||||
| 
 | ||||
| std::array<UINT8, M_PW_BUF_SIZE> decode_hash(std::string encoded) | ||||
| { | ||||
| 	std::array<UINT8, M_PW_BUF_SIZE> decoded; | ||||
| 	if (modp::b64_decode(encoded).size() != decoded.size()) | ||||
| 		throw std::invalid_argument("hash is incorrectly sized"); | ||||
| 	std::copy(encoded.begin(), encoded.end(), decoded.begin()); | ||||
| 	return decoded; | ||||
| } | ||||
| 
 | ||||
| struct Pw | ||||
| { | ||||
| 	Pw(void (*cb)(), const char *encoded_hash) : cb_(cb), hash_(decode_hash(encoded_hash)) {} | ||||
| 
 | ||||
| 	void (*cb_)(); | ||||
| 	const std::array<UINT8, M_PW_BUF_SIZE> hash_; | ||||
| 
 | ||||
| private: | ||||
| 	static std::array<UINT8, M_PW_BUF_SIZE> decode_hash(std::string encoded) | ||||
| 	{ | ||||
| 		std::array<UINT8, M_PW_BUF_SIZE> decoded; | ||||
| 		if (modp::b64_decode(encoded).size() != decoded.size()) | ||||
| 			throw std::invalid_argument("hash is incorrectly sized"); | ||||
| 		std::copy(encoded.begin(), encoded.end(), decoded.begin()); | ||||
| 		return decoded; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| std::vector<Pw> passwords; | ||||
|  | @ -342,6 +341,20 @@ try_password_e M_TryPassword(const char *password, boolean conditions) | |||
| 	return return_code; | ||||
| } | ||||
| 
 | ||||
| boolean M_TryExactPassword(const char *password, const char *encodedhash) | ||||
| { | ||||
| 	// Normalize input casing
 | ||||
| 	std::string key = password; | ||||
| 	strlwr(key.data()); | ||||
| 
 | ||||
| 	UINT8 key_hash[M_PW_HASH_SIZE]; | ||||
| 	M_HashPassword(key_hash, key.c_str(), kRRSalt); | ||||
| 
 | ||||
| 	auto hash = decode_hash(encodedhash); | ||||
| 
 | ||||
| 	return (memcmp(key_hash, hash.data(), M_PW_HASH_SIZE) == 0); | ||||
| } | ||||
| 
 | ||||
| #ifdef DEVELOP | ||||
| void Command_Crypt_f(void) | ||||
| { | ||||
|  |  | |||
|  | @ -27,6 +27,7 @@ try_password_e; | |||
| 
 | ||||
| void M_PasswordInit(void); | ||||
| try_password_e M_TryPassword(const char *password, boolean challenges); | ||||
| boolean M_TryExactPassword(const char *password, const char *encodedhash); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } // extern "C"
 | ||||
|  |  | |||
|  | @ -8373,30 +8373,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) | |||
| 	// will be set by player think.
 | ||||
| 	players[consoleplayer].viewz = 1; | ||||
| 
 | ||||
| 	// Cancel all d_main.c fadeouts (keep fade in though).
 | ||||
| 	if (reloadinggamestate) | ||||
| 		wipegamestate = gamestate; // Don't fade if reloading the gamestate
 | ||||
| 	// Encore mode fade to pink to white
 | ||||
| 	// This is handled BEFORE sounds are stopped.
 | ||||
| 	else if (encoremode && !prevencoremode && modeattacking == ATTACKING_NONE && !demo.rewinding) | ||||
| 	{ | ||||
| 		if (rendermode != render_none) | ||||
| 		{ | ||||
| 			tic_t locstarttime, endtime, nowtime; | ||||
| 	// (This define might be useful for other areas of code? Not sure)
 | ||||
| 	tic_t locstarttime, endtime, nowtime; | ||||
| 
 | ||||
| 			Music_StopAll(); // er, about that...
 | ||||
| 
 | ||||
| 			// Fade to an inverted screen, with a circle fade...
 | ||||
| 			F_WipeStartScreen(); | ||||
| 
 | ||||
| 			V_EncoreInvertScreen(); | ||||
| 			F_WipeEndScreen(); | ||||
| 
 | ||||
| 			S_StartSound(NULL, sfx_ruby1); | ||||
| 			F_RunWipe(wipe_encore_toinvert, wipedefs[wipe_encore_toinvert], false, NULL, false, false); | ||||
| 
 | ||||
| 			// Hold on invert for extra effect.
 | ||||
| 			// (This define might be useful for other areas of code? Not sure)
 | ||||
| #define WAIT(timetowait) \ | ||||
| 	locstarttime = nowtime = lastwipetic; \ | ||||
| 	endtime = locstarttime + timetowait; \ | ||||
|  | @ -8415,6 +8394,28 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) | |||
| 		NetKeepAlive(); \ | ||||
| 	} \ | ||||
| 
 | ||||
| 	// Cancel all d_main.c fadeouts (keep fade in though).
 | ||||
| 	if (reloadinggamestate) | ||||
| 		wipegamestate = gamestate; // Don't fade if reloading the gamestate
 | ||||
| 	// Encore mode fade to pink to white
 | ||||
| 	// This is handled BEFORE sounds are stopped.
 | ||||
| 	else if (encoremode && !prevencoremode && modeattacking == ATTACKING_NONE && !demo.rewinding) | ||||
| 	{ | ||||
| 		if (rendermode != render_none) | ||||
| 		{ | ||||
| 			Music_StopAll(); // er, about that...
 | ||||
| 
 | ||||
| 			// Fade to an inverted screen, with a circle fade...
 | ||||
| 			F_WipeStartScreen(); | ||||
| 
 | ||||
| 			V_EncoreInvertScreen(); | ||||
| 			F_WipeEndScreen(); | ||||
| 
 | ||||
| 			S_StartSound(NULL, sfx_ruby1); | ||||
| 			F_RunWipe(wipe_encore_toinvert, wipedefs[wipe_encore_toinvert], false, NULL, false, false); | ||||
| 
 | ||||
| 			// Hold on invert for extra effect.
 | ||||
| 
 | ||||
| 			WAIT((3*TICRATE)/2); | ||||
| 			S_StartSound(NULL, sfx_ruby2); | ||||
| 
 | ||||
|  | @ -8441,9 +8442,15 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) | |||
| 		{ | ||||
| 			// dedicated servers can call this now, to wait the appropriate amount of time for clients to wipe
 | ||||
| 			F_RunWipe(wipe_encore_towhite, wipedefs[wipe_encore_towhite], false, "FADEMAP1", false, true); | ||||
| 
 | ||||
| 			WAIT((3*TICRATE)/2); | ||||
| 
 | ||||
| 			F_RunWipe(wipe_level_toblack, wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false); | ||||
| 
 | ||||
| 			WAIT((3*TICRATE)/4); | ||||
| 		} | ||||
| 	} | ||||
| #undef WAIT | ||||
| 
 | ||||
| 	// Special stage & record attack retry fade to white
 | ||||
| 	// This is handled BEFORE sounds are stopped.
 | ||||
|  | @ -9135,15 +9142,19 @@ UINT8 P_InitMapData(void) | |||
| 		// Okay, it does...
 | ||||
| 		{ | ||||
| 			ret |= MAPRET_ADDED; | ||||
| 			CONS_Printf("%s\n", name); | ||||
| 
 | ||||
| 			if (basenummapheaders && mapheaderinfo[i]->lumpnum != LUMPERROR) | ||||
| 			if (basenummapheaders) | ||||
| 			{ | ||||
| 				G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you
 | ||||
| 				CONS_Printf("%s\n", name); | ||||
| 
 | ||||
| 				//If you replaced the map you're on, end the level when done.
 | ||||
| 				if (i == gamemap - 1) | ||||
| 					ret |= MAPRET_CURRENTREPLACED; | ||||
| 				if (mapheaderinfo[i]->lumpnum != LUMPERROR) | ||||
| 				{ | ||||
| 					G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you
 | ||||
| 
 | ||||
| 					//If you replaced the map you're on, end the level when done.
 | ||||
| 					if (i == gamemap - 1) | ||||
| 						ret |= MAPRET_CURRENTREPLACED; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			mapheaderinfo[i]->lumpnum = maplump; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 toaster
						toaster