Snakegold Posted October 5, 2023 Share Posted October 5, 2023 hello i have a problem in this script local rulesTable = { ['1.1'] = 'speaking non-english in global chat', ['2.1'] = 'annoying', ['3.1'] = 'offending', ['3.2'] = 'offending the server or its staff', } local mutedPlayers = {} function createMuteTable() executeSQLQuery("CREATE TABLE IF NOT EXISTS action (playername TEXT, punishername TEXT, reason TEXT, duration NUMERIC)") end function findPlayerByPartialName(partialName) local matchedPlayer = nil for _, player in ipairs(getElementsByType("player")) do local playerName = getPlayerName(player) if string.find(playerName:lower(), partialName:lower()) then if matchedPlayer then return nil -- More than one player matches the partial name else matchedPlayer = player end end end return matchedPlayer end function handlePunishment(punisherName, partialName, ruleNumber) local targetPlayer = findPlayerByPartialName(partialName) if not targetPlayer then outputChatBox("Player not found or multiple players match the partial name.") return end local ruleDescription = rulesTable[ruleNumber] if ruleDescription then local duration = calculateDuration(ruleNumber) if ruleNumber == '9.1' then kickPlayer(targetPlayer, punisherName, "Disturbing events") outputChatBox("#00FF00".. getPlayerName(targetPlayer) .. " has been kicked by #FFFFFF" .. punisherName .. " #006600[#FFFFFFReason: RULE #" .. ruleNumber .. ": " .. ruleDescription .. "#006600]", getRootElement(), 255, 255, 255, true) elseif ruleNumber == '10.1' then banPlayer(targetPlayer, true, true, true, getRootElement(), "Harming the server") outputChatBox("#00FF00".. getPlayerName(targetPlayer) .. " has been banned by #FFFFFF" .. punisherName .. " #006600[#FFFFFFReason: RULE #" .. ruleNumber .. ": " .. ruleDescription .. "#006600]", getRootElement(), 255, 255, 255, true) elseif ruleNumber == '1.1' or ruleNumber == '2.1' or ruleNumber == '3.1' or ruleNumber == '3.2' then mutePlayer(targetPlayer, punisherName, ruleNumber, ruleDescription, duration) else outputChatBox("Invalid rule number") return end else outputChatBox("Invalid rule number") end end function calculateDuration(ruleNumber) if ruleNumber == '1.1' then return 300 -- 5 minutes elseif ruleNumber == '2.1' then return 300 -- 5 minutes elseif ruleNumber == '3.1' then return 900 -- 15 minutes elseif ruleNumber == '3.2' then return 3600 -- 1 hour else return 300 -- Default to 5 minutes if rule number is not found end end function mutePlayer(player, punisherName, ruleNumber, ruleDescription, duration) local playerName = getPlayerName(player) if mutedPlayers[playerName] then local remainingDuration = mutedPlayers[playerName].duration - (getRealTime().timestamp - mutedPlayers[playerName].startTime) if remainingDuration <= 0 then unmutePlayer(player, punisherName, ruleNumber, ruleDescription) return end if mutedPlayers[playerName].unmuteTimer then killTimer(mutedPlayers[playerName].unmuteTimer) end mutedPlayers[playerName].unmuteTimer = setTimer(unmutePlayer, remainingDuration * 1000, 1, player, punisherName, ruleNumber, ruleDescription) outputChatBox("#FFFFFF".. playerName .. " #006600mute duration extended by #FFFFFF" .. punisherName .. " #006600[Additional Duration: #FFFFFF" .. formatTime(remainingDuration) .. ". Total Duration: #FFFFFF" .. formatTime(mutedPlayers[playerName].duration) .. ". Reason: #FFFFFF" .. ruleDescription .. "#006600]", getRootElement(), 255, 255, 255, true) else setPlayerMuted(player, true) mutedPlayers[playerName] = { duration = duration, startTime = getRealTime().timestamp } mutedPlayers[playerName].unmuteTimer = setTimer(unmutePlayer, duration * 1000, 1, player, punisherName, ruleNumber, ruleDescription) outputChatBox("#FFFFFF".. playerName .. " #006600has been muted by #FFFFFF" .. punisherName .. " #006600[#FFFFFFReason: RULE #" .. ruleNumber .. ": " .. ruleDescription .. ". Duration:#FFFFFF " .. formatTime(duration) .. " #006600]", getRootElement(), 255, 255, 255, true) end -- Insert the muted player into the database executeSQLQuery("INSERT INTO action (playername, punishername, reason, duration) VALUES (?, ?, ?, ?)", playerName, punisherName, ruleNumber, duration) end function unmutePlayer(player, punisherName, ruleNumber, ruleDescription) local playerName = getPlayerName(player) setPlayerMuted(player, false) mutedPlayers[playerName] = nil outputChatBox("#00FF00".. playerName .. " has been unmuted by #FFFFFFConsole #006600[#FFFFFFReason: RULE #" .. ruleNumber .. ": " .. ruleDescription .. "#006600]", getRootElement(), 255, 255, 255, true) executeSQLQuery("DELETE FROM action WHERE playername = ?", playerName) end function formatTime(totalSeconds) local minutes = math.floor(totalSeconds / 60) return string.format("%d minutes", minutes) end function handleAUnmute(punisherName, playerName) local targetPlayer = findPlayerByPartialName(playerName) if not targetPlayer then outputChatBox("Player not found or multiple players match the partial name.") return end local playerName = getPlayerName(targetPlayer) if mutedPlayers[playerName] then if mutedPlayers[playerName].unmuteTimer then killTimer(mutedPlayers[playerName].unmuteTimer) end setPlayerMuted(targetPlayer, false) mutedPlayers[playerName] = nil executeSQLQuery("DELETE FROM action WHERE playername = ?", playerName) outputChatBox("#00FF00" .. playerName .. " has been unmuted by #FFFFFF" .. punisherName .. " #006600[#FFFFFFReason: Manual unmute#006600]", getRootElement(), 255, 255, 255, true) else outputChatBox(playerName .. " is not currently muted.", getRootElement(), 255, 255, 255, true) end end addCommandHandler("aunmute", function(player, _, playerName) local punisherName = getPlayerName(player) handleAUnmute(punisherName, playerName) end) addCommandHandler("action", function(player, _, playerName, ruleNumber) local punisherName = getPlayerName(player) handlePunishment(punisherName, playerName, ruleNumber) end) addEventHandler("onPlayerJoin", root, function() local playerName = getPlayerName(source) local query = executeSQLQuery("SELECT * FROM action WHERE playername = ?", playerName) if query then for i, row in ipairs(query) do local totalDuration = tonumber(row.duration) local ruleNumber = row.reason local ruleDescription = rulesTable[ruleNumber] setPlayerMuted(source, true) local remainingDuration = totalDuration - (getRealTime().timestamp - row.timestamp) if remainingDuration > 0 then mutedPlayers[playerName] = { duration = totalDuration, startTime = row.timestamp } mutedPlayers[playerName].unmuteTimer = setTimer(unmutePlayer, remainingDuration * 1000, 1, source, row.punishername, ruleNumber, ruleDescription) outputChatBox("#FFFFFF".. getPlayerName(source) .. " has been muted by #FFFFFFConsole. Reason: RULE #" .. ruleNumber .. ": " .. ruleDescription .. ". Duration: " .. formatTime(remainingDuration), getRootElement(), 255, 255, 255, true) else executeSQLQuery("DELETE FROM action WHERE playername = ?", playerName) outputChatBox("#00FF00".. getPlayerName(source) .. " has been unmuted by #FFFFFFConsole #006600[#FFFFFFReason: RULE #" .. ruleNumber .. ": " .. ruleDescription .. "#006600]", getRootElement(), 255, 255, 255, true) end end end end) THE PROBLEM IS HERE ------------------------------------ outputChatBox("#FFFFFF".. getPlayerName(source) .. " has been muted by #FFFFFFConsole. Reason: RULE #" .. ruleNumber .. ": " .. ruleDescription .. ". Duration: " .. formatTime(remainingDuration), getRootElement(), 255, 255, 255, true) ------------------------------------- THIS MESSAGE IS NOT APPEARING IN THE CHATBOX AFTER THE PLAYER RECONNECTS Link to comment
Moderators IIYAMA Posted October 5, 2023 Moderators Share Posted October 5, 2023 2 hours ago, Snakegold said: THIS MESSAGE IS NOT APPEARING IN THE CHATBOX AFTER THE PLAYER RECONNECTS Don't use playername, use serial. And don't pass the player to this function: function unmutePlayer(player, punisherName, ruleNumber, ruleDescription) Pass over it's serial function unmutePlayer(serial, punisherName, ruleNumber, ruleDescription) local player = getPlayerFromSerial ( serial ) -- utility function copy from: https://wiki.multitheftauto.com/wiki/GetPlayerFromSerial if player then -- is the player in the server? -- inform the player that he has been unmuted end 1 Link to comment
Snakegold Posted October 5, 2023 Author Share Posted October 5, 2023 6 hours ago, IIYAMA said: Don't use playername, use serial. And don't pass the player to this function: function unmutePlayer(player, punisherName, ruleNumber, ruleDescription) Pass over it's serial function unmutePlayer(serial, punisherName, ruleNumber, ruleDescription) local player = getPlayerFromSerial ( serial ) -- utility function copy from: https://wiki.multitheftauto.com/wiki/GetPlayerFromSerial if player then -- is the player in the server? -- inform the player that he has been unmuted end local rulesTable = { ['1.1'] = 'speaking non-english in global chat', ['2.1'] = 'annoying', ['3.1'] = 'offending', ['3.2'] = 'offending the server or its staff', } local mutedPlayers = {} executeSQLQuery("CREATE TABLE IF NOT EXISTS punishments (serial TEXT, punishername TEXT, reason TEXT, duration NUMERIC)") function findPlayerByPartialName(partialName) local matchedPlayer = nil for _, player in ipairs(getElementsByType("player")) do local playerName = getPlayerName(player) if string.find(playerName:lower(), partialName:lower()) then if matchedPlayer then return nil -- More than one player matches the partial name else matchedPlayer = player end end end return matchedPlayer end function handlePunishment(punisherName, partialName, ruleNumber) local targetPlayer = findPlayerByPartialName(partialName) if not targetPlayer then outputChatBox("Player not found or multiple players match the partial name.") return end local ruleDescription = rulesTable[ruleNumber] if ruleDescription then local duration = calculateDuration(ruleNumber) if ruleNumber == '9.1' then kickPlayer(targetPlayer, punisherName, "Disturbing events") outputChatBox("#00FF00".. getPlayerName(targetPlayer) .. " has been kicked by #FFFFFF" .. punisherName .. " #006600[#FFFFFFReason: RULE #" .. ruleNumber .. ": " .. ruleDescription .. "#006600]", getRootElement(), 255, 255, 255, true) elseif ruleNumber == '10.1' then banPlayer(targetPlayer, true, true, true, getRootElement(), "Harming the server") outputChatBox("#00FF00".. getPlayerName(targetPlayer) .. " has been banned by #FFFFFF" .. punisherName .. " #006600[#FFFFFFReason: RULE #" .. ruleNumber .. ": " .. ruleDescription .. "#006600]", getRootElement(), 255, 255, 255, true) elseif ruleNumber == '1.1' or ruleNumber == '2.1' or ruleNumber == '3.1' or ruleNumber == '3.2' then mutePlayer(targetPlayer, punisherName, ruleNumber, ruleDescription, duration) else outputChatBox("Invalid rule number") return end else outputChatBox("Invalid rule number") end end function calculateDuration(ruleNumber) if ruleNumber == '1.1' then return 300 -- 5 minutes elseif ruleNumber == '2.1' then return 300 -- 5 minutes elseif ruleNumber == '3.1' then return 900 -- 15 minutes elseif ruleNumber == '3.2' then return 3600 -- 1 hour else return 300 -- Default to 5 minutes if rule number is not found end end function mutePlayer(player, punisherName, ruleNumber, ruleDescription, duration) local playerSerial = getPlayerSerial(player) local playerName = getPlayerName(player) if mutedPlayers[playerSerial] then local remainingDuration = mutedPlayers[playerSerial].duration - (getRealTime().timestamp - mutedPlayers[playerSerial].startTime) if remainingDuration <= 0 then unmutePlayer(playerSerial, punisherName, ruleNumber, ruleDescription) return end if mutedPlayers[playerSerial].unmuteTimer then killTimer(mutedPlayers[playerSerial].unmuteTimer) end mutedPlayers[playerSerial].unmuteTimer = setTimer(unmutePlayer, remainingDuration * 1000, 1, playerSerial, punisherName, ruleNumber, ruleDescription) outputChatBox("#FFFFFF".. playerName .. "'s #006600mute duration extended by #FFFFFF" .. punisherName .. " #006600[Additional Duration: #FFFFFF" .. formatTime(remainingDuration) .. ". Total Duration: #FFFFFF" .. formatTime(mutedPlayers[playerSerial].duration) .. ". Reason: #FFFFFF" .. ruleDescription .. "#006600]", getRootElement(), 255, 255, 255, true) return else setPlayerMuted(player, true) mutedPlayers[playerSerial] = { duration = duration, startTime = getRealTime().timestamp } outputChatBox("#FFFFFF".. playerName .. " #006600has been muted by #FFFFFF" .. punisherName .. " #006600[#FFFFFFReason: RULE #" .. ruleNumber .. ": " .. ruleDescription .. ". Duration: " .. formatTime(duration) .. " #006600]", getRootElement(), 255, 255, 255, true) executeSQLQuery("INSERT INTO punishments (serial, punishername, reason, duration) VALUES (?, ?, ?, ?)", playerSerial, punisherName, ruleNumber, duration) end end function unmutePlayer(serial, punisherName, ruleNumber, ruleDescription) local player = getPlayerFromSerial(serial) if player then local playerName = getPlayerName(player) if mutedPlayers[serial] then if mutedPlayers[serial].unmuteTimer then killTimer(mutedPlayers[serial].unmuteTimer) end setPlayerMuted(player, false) mutedPlayers[serial] = nil executeSQLQuery("DELETE FROM punishments WHERE serial = ?", serial) outputChatBox("#00FF00" .. playerName .. " has been unmuted by #FFFFFF" .. punisherName .. " #006600[#FFFFFFReason: Manual unmute#006600]", getRootElement(), 255, 255, 255, true) else outputChatBox(playerName .. " is not currently muted.", getRootElement(), 255, 255, 255, true) end end end function formatTime(totalSeconds) local minutes = math.floor(totalSeconds / 60) return string.format("%d minutes", minutes) end function handleAUnmute(punisherName, playerName) local targetPlayer = findPlayerByPartialName(playerName) if not targetPlayer then outputChatBox("Player not found or multiple players match the partial name.") return end local playerNameTarget = getPlayerName(targetPlayer) local playerSerial = getPlayerSerial(targetPlayer) if mutedPlayers[playerSerial] then if mutedPlayers[playerSerial].unmuteTimer then killTimer(mutedPlayers[playerSerial].unmuteTimer) end setPlayerMuted(targetPlayer, false) mutedPlayers[playerSerial] = nil executeSQLQuery("DELETE FROM punishments WHERE serial = ?", playerSerial) outputChatBox("#00FF00" .. playerNameTarget .. " has been unmuted by #FFFFFF" .. punisherName .. " #006600[#FFFFFFReason: Manual unmute#006600]", getRootElement(), 255, 255, 255, true) else outputChatBox(playerNameTarget .. " is not currently muted.", getRootElement(), 255, 255, 255, true) end end addCommandHandler("aunmute", function(player, _, playerName) local punisherName = getPlayerName(player) handleAUnmute(punisherName, playerName) end) addCommandHandler("action", function(player, _, playerName, ruleNumber) local punisherName = getPlayerName(player) handlePunishment(punisherName, playerName, ruleNumber) end) addEventHandler("onPlayerJoin", root, function() local player = source local playerName = getPlayerName(player) local playerSerial = getPlayerSerial(player) local query = executeSQLQuery("SELECT * FROM punishments WHERE serial = ?", playerSerial) if query then for i, row in ipairs(query) do local totalDuration = tonumber(row.duration) local ruleNumber = row.reason local ruleDescription = rulesTable[ruleNumber] local remainingDuration = totalDuration - (getRealTime().timestamp - row.timestamp) if remainingDuration <= 0 then executeSQLQuery("DELETE FROM punishments WHERE serial = ?", playerSerial) else setPlayerMuted(player, true) mutedPlayers[playerSerial] = { duration = remainingDuration, startTime = row.timestamp } mutedPlayers[playerSerial].unmuteTimer = setTimer(unmutePlayer, remainingDuration * 1000, 1, playerSerial, "Console", ruleNumber, ruleDescription) outputChatBox("#FFFFFF".. playerName .. " has been muted by #FFFFFFConsole. Reason: RULE #" .. ruleNumber .. ": " .. ruleDescription .. ". Duration: " .. formatTime(remainingDuration), getRootElement(), 255, 255, 255, true) end end end end) STILL THE SAME PROBLEM THE PLAYER AFTER RECONNECTING HE GETS UNMUTED AND THE OUTPUTCHATBOX PLAYER HAS BEEN MUTED BY CONSOLE DOESNT APPEAR Link to comment
Moderators IIYAMA Posted October 6, 2023 Moderators Share Posted October 6, 2023 To solve this problem, you have to use debug lines(iprint) to get to the problem. I fixed here a logic issue, where the player is not removed from the database when he is not ingame. function unmutePlayer(serial, punisherName, ruleNumber, ruleDescription) local player = getPlayerFromSerial(serial) iprint( "<unmutePlayer> mutedPlayers[serial]:", mutedPlayers[serial], ", player:", player ) if mutedPlayers[serial] then if mutedPlayers[serial].unmuteTimer then killTimer(mutedPlayers[serial].unmuteTimer) end mutedPlayers[serial] = nil iprint("<unmutePlayer> remove from database") executeSQLQuery("DELETE FROM punishments WHERE serial = ?", serial) if player then local playerName = getPlayerName(player) setPlayerMuted(player, false) outputChatBox("#00FF00" .. playerName .. " has been unmuted by #FFFFFF" .. punisherName .. " #006600[#FFFFFFReason: Manual unmute#006600]", getRootElement(), 255, 255, 255, true) end elseif player then local playerName = getPlayerName(player) outputChatBox(playerName .. " is not currently muted.", getRootElement(), 255, 255, 255, true) end end And here I added some debug lines, tweaked the select query and removed the loop. addEventHandler("onPlayerJoin", root, function() local player = source local playerName = getPlayerName(player) local playerSerial = getPlayerSerial(player) local query = executeSQLQuery("SELECT * FROM punishments WHERE serial = ? LIMIT 1", playerSerial) iprint('<onPlayerJoin> query:', query) if query and #query > 0 then local row = query[1] local totalDuration = tonumber(row.duration) local ruleNumber = row.reason local ruleDescription = rulesTable[ruleNumber] iprint('<onPlayerJoin>', "totalDuration:", totalDuration, ", difference:", (getRealTime().timestamp - row.timestamp), ", remaining:", totalDuration - (getRealTime().timestamp - row.timestamp)) local remainingDuration = totalDuration - (getRealTime().timestamp - row.timestamp) if remainingDuration <= 0 then executeSQLQuery("DELETE FROM punishments WHERE serial = ?", playerSerial) else setPlayerMuted(player, true) mutedPlayers[playerSerial] = { duration = remainingDuration, startTime = row.timestamp } mutedPlayers[playerSerial].unmuteTimer = setTimer(unmutePlayer, remainingDuration * 1000, 1, playerSerial, "Console", ruleNumber, ruleDescription) outputChatBox("#FFFFFF".. playerName .. " has been muted by #FFFFFFConsole. Reason: RULE #" .. ruleNumber .. ": " .. ruleDescription .. ". Duration: " .. formatTime(remainingDuration), getRootElement(), 255, 255, 255, true) end end end) Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now