<commit_before>part of metabolics;

class MetabolicsEndpoint {
	static bool simulateMood = false,
		simulateEnergy = false;
	static Timer moodTimer = new Timer.periodic(new Duration(seconds: 60), (Timer timer) => simulateMood = true);
	static Timer energyTimer = new Timer.periodic(new Duration(seconds: 90), (Timer timer) => simulateEnergy = true);
	static Timer simulateTimer = new Timer.periodic(new Duration(seconds: 5), (Timer timer) => simulate());
	static Map<String, WebSocket> userSockets = {};

	static void trackNewDays() {
		// Refill everyone's energy on the start of a new day
		Clock clock = new Clock();
		clock.onNewDay.listen((_) => MetabolicsEndpoint.refillAllEnergy());
	}

	static Future refillAllEnergy() async {
		PostgreSql dbConn = await dbManager.getConnection();
		String query = "UPDATE metabolics SET energy = max_energy, quoins_collected = 0";
		dbConn.execute(query);
		dbManager.closeConnection(dbConn);
	}

	static void handle(WebSocket ws) {
		moodTimer.isActive;
		energyTimer.isActive;
		simulateTimer.isActive;

		ws.listen((message) => processMessage(ws, message),
			          onError: (error) => cleanupList(ws), onDone: () => cleanupList(ws));
	}

	static void cleanupList(WebSocket ws) {
		String leavingUser;

		userSockets.forEach((String username, WebSocket socket) {
			if (ws == socket) {
				socket = null;
				leavingUser = username;
			}
		});

		userSockets.remove(leavingUser);
	}

	static void processMessage(WebSocket ws, String message) {
		Map map = JSON.decode(message);
		String username = map['username'];

		if (!userSockets.containsKey(username)) {
			userSockets[username] = ws;
		}
	}

	static void simulate() {
		userSockets.forEach((String username, WebSocket ws) async {
			try {
				Metabolics m = await getMetabolics(username: username);

				if (simulateMood) {
					_calcAndSetMood(m);
				}

				if (m.mood < m.max_mood ~/ 10) {
					String email = await User.getEmailFromUsername(username);
					QuestEndpoint.questLogCache[email]?.offerQuest('Q10');
				}

				if (simulateEnergy) {
					_calcAndSetEnergy(m);
				}

				Identifier userIdentifier = PlayerUpdateHandler.users[username];

				if (userIdentifier != null) {
					updateDeath(userIdentifier, m);
				}

				//store current street and position
				if (userIdentifier != null) {
					m.current_street = userIdentifier.tsid;
					m.current_street_x = userIdentifier.currentX;
					m.current_street_y = userIdentifier.currentY;

					//store the metabolics back to the database
					int result = await setMetabolics(m);
					if (result > 0) {
						//send the metabolics back to the user
						ws.add(JSON.encode(encode(m)));
					}
				}
			} catch (e, st) {
				Log.error('Metabolics simulation failed', e, st);
			}
		});
	}

	/// Supply m to speed it up, and init to only check energy (in case they left the game while in Hell)
	static Future updateDeath(Identifier userIdentifier, [Metabolics m, bool init = false]) async {
		final String HELL_ONE = 'GA5PPFP86NF2FOS';
		final String CEBARKUL = 'GIF12PMQ5121D68';
		final int NARAKA = 40;

		if (userIdentifier == null) {
			return;
		}

		if (m == null) {
			m = await getMetabolics(username: userIdentifier.username);
		}

		if (
			m.energy == 0 // Dead
			&& (m.undead_street == null || init) // Not in Hell (or just connecting)
		) {
			// Save undead street
			m.dead = true;

			// Go to Hell
			userIdentifier.webSocket.add(JSON.encode({
				"gotoStreet": "true",
				"tsid": HELL_ONE
			}));
		} else {
			Map<String, dynamic> street = getStreetByTsid(m.current_street);
			if (
				m.energy >= HellGrapes.ENERGY_REQ // Enough energy to be alive
				&& (street == null) || ((street['hub_id'] ?? NARAKA) == NARAKA) // In Hell
			) {
				// Return to world
				userIdentifier.webSocket.add(JSON.encode({
					"gotoStreet": "true",
					"tsid": m.undead_street ?? CEBARKUL
				}));

				m.dead = false;
			}
		}
	}

	static Future<bool> addToLocationHistory(String username, String email, String TSID) async {
		Metabolics m = await getMetabolics(username: username);<commit_msg>order of calls optimization that seems to have fixed the hell issue somehow<commit_after>part of metabolics;

class MetabolicsEndpoint {
	static bool simulateMood = false,
		simulateEnergy = false;
	static Timer moodTimer = new Timer.periodic(new Duration(seconds: 60), (Timer timer) => simulateMood = true);
	static Timer energyTimer = new Timer.periodic(new Duration(seconds: 90), (Timer timer) => simulateEnergy = true);
	static Timer simulateTimer = new Timer.periodic(new Duration(seconds: 5), (Timer timer) => simulate());
	static Map<String, WebSocket> userSockets = {};

	static void trackNewDays() {
		// Refill everyone's energy on the start of a new day
		Clock clock = new Clock();
		clock.onNewDay.listen((_) => MetabolicsEndpoint.refillAllEnergy());
	}

	static Future refillAllEnergy() async {
		PostgreSql dbConn = await dbManager.getConnection();
		String query = "UPDATE metabolics SET energy = max_energy, quoins_collected = 0";
		dbConn.execute(query);
		dbManager.closeConnection(dbConn);
	}

	static void handle(WebSocket ws) {
		moodTimer.isActive;
		energyTimer.isActive;
		simulateTimer.isActive;

		ws.listen((message) => processMessage(ws, message),
			          onError: (error) => cleanupList(ws), onDone: () => cleanupList(ws));
	}

	static void cleanupList(WebSocket ws) {
		String leavingUser;

		userSockets.forEach((String username, WebSocket socket) {
			if (ws == socket) {
				socket = null;
				leavingUser = username;
			}
		});

		userSockets.remove(leavingUser);
	}

	static void processMessage(WebSocket ws, String message) {
		Map map = JSON.decode(message);
		String username = map['username'];

		if (!userSockets.containsKey(username)) {
			userSockets[username] = ws;
		}
	}

	static void simulate() {
		userSockets.forEach((String username, WebSocket ws) async {
			try {
				Metabolics m = await getMetabolics(username: username);

				if (simulateMood) {
					_calcAndSetMood(m);
				}

				if (m.mood < m.max_mood ~/ 10) {
					String email = await User.getEmailFromUsername(username);
					QuestEndpoint.questLogCache[email]?.offerQuest('Q10');
				}

				if (simulateEnergy) {
					_calcAndSetEnergy(m);
				}

				Identifier userIdentifier = PlayerUpdateHandler.users[username];

				if (userIdentifier != null) {
					updateDeath(userIdentifier, m);
				}

				//store current street and position
				if (userIdentifier != null) {
					m.current_street = userIdentifier.tsid;
					m.current_street_x = userIdentifier.currentX;
					m.current_street_y = userIdentifier.currentY;

					//store the metabolics back to the database
					int result = await setMetabolics(m);
					if (result > 0) {
						//send the metabolics back to the user
						ws.add(JSON.encode(encode(m)));
					}
				}
			} catch (e, st) {
				Log.error('Metabolics simulation failed', e, st);
			}
		});
	}

	/// Supply m to speed it up, and init to only check energy (in case they left the game while in Hell)
	static Future updateDeath(Identifier userIdentifier, [Metabolics m, bool init = false]) async {
		final String HELL_ONE = 'GA5PPFP86NF2FOS';
		final String CEBARKUL = 'GIF12PMQ5121D68';
		final int NARAKA = 40;

		if (userIdentifier == null) {
			return;
		}

		if (m == null) {
			m = await getMetabolics(username: userIdentifier.username);
		}

		if (
			m.energy == 0 // Dead
			&& (m.undead_street == null || init) // Not in Hell (or just connecting)
		) {
			// Save undead street
			m.dead = true;

			// Go to Hell One
			userIdentifier.webSocket.add(JSON.encode({
				"gotoStreet": "true",
				"tsid": HELL_ONE
			}));
		} else if (m.energy >= HellGrapes.ENERGY_REQ) {
			// Enough energy to be alive

			Map<String, dynamic> street = getStreetByTsid(m.current_street);
			if ((street == null) || ((street['hub_id'] ?? NARAKA) == NARAKA)) {
				// In Naraka, Return to world
				userIdentifier.webSocket.add(JSON.encode({
					"gotoStreet": "true",
					"tsid": m.undead_street ?? CEBARKUL
				}));

				m.dead = false;
			}
		}
	}

	static Future<bool> addToLocationHistory(String username, String email, String TSID) async {
		Metabolics m = await getMetabolics(username: username);
{'fraction_non_alphanumeric': 0.12181441287647848, 'fraction_numerical': 0.0063406901597366176, 'mean_word_length': 3.5415282392026577, 'pattern_counts': {'":': 8, '<': 11, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6432944', 'n_tokens_mistral': 3198, 'n_tokens_neox': 2576, 'n_words': 693}