Diff
checker
Text
Text
Images
Documents
Excel
Folders
Legal
Enterprise
Desktop
Pricing
Sign in
Download Diffchecker Desktop
Compare text
Find the difference between two text files
Tools
History
Real-time editor
Hide whitespace changes
Hide unchanged lines
Disable line wrap
Layout
Split
Unified
Diff precision
Smart
Word
Char
Text styles
Change appearance
Syntax highlighting
Choose syntax
Ignore
Transform text
Go to first change
Edit input
Diffchecker Desktop
The most secure way to run Diffchecker. Get the Diffchecker Desktop app: your diffs never leave your computer!
Get Desktop
Chat
Created
4 years ago
Diff never expires
Clear
Export
Share
Explain
3 removals
Lines
Total
Removed
Characters
Total
Removed
To continue using this feature, upgrade to
Diff
checker
Pro
View Pricing
308 lines
Copy
35 additions
Lines
Total
Added
Characters
Total
Added
To continue using this feature, upgrade to
Diff
checker
Pro
View Pricing
309 lines
Copy
local isRDR = not TerraingridActivate and true or false
local isRDR = not TerraingridActivate and true or false
local chatInputActive = false
local chatInputActive = false
local chatInputActivating = false
local chatInputActivating = false
local chatLoaded = false
local chatLoaded = false
RegisterNetEvent('chatMessage')
RegisterNetEvent('chatMessage')
RegisterNetEvent('chat:addTemplate')
RegisterNetEvent('chat:addTemplate')
RegisterNetEvent('chat:addMessage')
RegisterNetEvent('chat:addMessage')
RegisterNetEvent('chat:addSuggestion')
RegisterNetEvent('chat:addSuggestion')
RegisterNetEvent('chat:addSuggestions')
RegisterNetEvent('chat:addSuggestions')
RegisterNetEvent('chat:addMode')
RegisterNetEvent('chat:addMode')
RegisterNetEvent('chat:removeMode')
RegisterNetEvent('chat:removeMode')
RegisterNetEvent('chat:removeSuggestion')
RegisterNetEvent('chat:removeSuggestion')
RegisterNetEvent('chat:clear')
RegisterNetEvent('chat:clear')
-- internal events
-- internal events
RegisterNetEvent('__cfx_internal:serverPrint')
RegisterNetEvent('__cfx_internal:serverPrint')
RegisterNetEvent('_chat:messageEntered')
RegisterNetEvent('_chat:messageEntered')
--deprecated, use chat:addMessage
--deprecated, use chat:addMessage
AddEventHandler('chatMessage', function(author, color, text)
AddEventHandler('chatMessage', function(author, color, text)
local args = { text }
local args = { text }
if author ~= "" then
if author ~= "" then
table.insert(args, 1, author)
table.insert(args, 1, author)
end
end
SendNUIMessage({
SendNUIMessage({
type = 'ON_MESSAGE',
type = 'ON_MESSAGE',
message = {
message = {
color = color,
color = color,
multiline = true,
multiline = true,
args = args
args = args
}
}
})
})
end)
end)
AddEventHandler('__cfx_internal:serverPrint', function(msg)
AddEventHandler('__cfx_internal:serverPrint', function(msg)
print(msg)
print(msg)
SendNUIMessage({
SendNUIMessage({
type = 'ON_MESSAGE',
type = 'ON_MESSAGE',
message = {
message = {
templateId = 'print',
templateId = 'print',
multiline = true,
multiline = true,
args = { msg },
args = { msg },
mode = '_global'
mode = '_global'
}
}
})
})
end)
end)
-- addMessage
-- addMessage
local addMessage = function(message)
local addMessage = function(message)
if type(message) == 'string' then
if type(message) == 'string' then
message = {
message = {
args = { message }
args = { message }
}
}
end
end
SendNUIMessage({
SendNUIMessage({
type = 'ON_MESSAGE',
type = 'ON_MESSAGE',
message = message
message = message
})
})
end
end
exports('addMessage', addMessage)
exports('addMessage', addMessage)
AddEventHandler('chat:addMessage', addMessage)
AddEventHandler('chat:addMessage', addMessage)
-- addSuggestion
-- addSuggestion
local addSuggestion = function(name, help, params)
local addSuggestion = function(name, help, params)
SendNUIMessage({
SendNUIMessage({
type = 'ON_SUGGESTION_ADD',
type = 'ON_SUGGESTION_ADD',
suggestion = {
suggestion = {
name = name,
name = name,
help = help,
help = help,
params = params or nil
params = params or nil
}
}
})
})
end
end
exports('addSuggestion', addSuggestion)
exports('addSuggestion', addSuggestion)
AddEventHandler('chat:addSuggestion', addSuggestion)
AddEventHandler('chat:addSuggestion', addSuggestion)
AddEventHandler('chat:addSuggestions', function(suggestions)
AddEventHandler('chat:addSuggestions', function(suggestions)
for _, suggestion in ipairs(suggestions) do
for _, suggestion in ipairs(suggestions) do
SendNUIMessage({
SendNUIMessage({
type = 'ON_SUGGESTION_ADD',
type = 'ON_SUGGESTION_ADD',
suggestion = suggestion
suggestion = suggestion
})
})
end
end
end)
end)
AddEventHandler('chat:removeSuggestion', function(name)
AddEventHandler('chat:removeSuggestion', function(name)
SendNUIMessage({
SendNUIMessage({
type = 'ON_SUGGESTION_REMOVE',
type = 'ON_SUGGESTION_REMOVE',
name = name
name = name
})
})
end)
end)
AddEventHandler('chat:addMode', function(mode)
AddEventHandler('chat:addMode', function(mode)
SendNUIMessage({
SendNUIMessage({
type = 'ON_MODE_ADD',
type = 'ON_MODE_ADD',
mode = mode
mode = mode
})
})
end)
end)
AddEventHandler('chat:removeMode', function(name)
AddEventHandler('chat:removeMode', function(name)
SendNUIMessage({
SendNUIMessage({
type = 'ON_MODE_REMOVE',
type = 'ON_MODE_REMOVE',
name = name
name = name
})
})
end)
end)
AddEventHandler('chat:addTemplate', function(id, html)
AddEventHandler('chat:addTemplate', function(id, html)
SendNUIMessage({
SendNUIMessage({
type = 'ON_TEMPLATE_ADD',
type = 'ON_TEMPLATE_ADD',
template = {
template = {
id = id,
id = id,
html = html
html = html
}
}
})
})
end)
end)
AddEventHandler('chat:clear', function(name)
AddEventHandler('chat:clear', function(name)
SendNUIMessage({
SendNUIMessage({
type = 'ON_CLEAR'
type = 'ON_CLEAR'
})
})
end)
end)
RegisterNUICallback('chatResult', function(data, cb)
RegisterNUICallback('chatResult', function(data, cb)
chatInputActive = false
chatInputActive = false
SetNuiFocus(false)
SetNuiFocus(false)
if not data.canceled then
if not data.canceled then
local id = PlayerId()
local id = PlayerId()
--deprecated
--deprecated
local r, g, b = 0, 0x99, 255
local r, g, b = 0, 0x99, 255
if data.message:sub(1, 1) == '/' then
if data.message:sub(1, 1) == '/' then
ExecuteCommand(data.message:sub(2))
ExecuteCommand(data.message:sub(2))
else
else
TriggerServerEvent('_chat:messageEntered', GetPlayerName(id), { r, g, b }, data.message, data.mode)
TriggerServerEvent('_chat:messageEntered', GetPlayerName(id), { r, g, b }, data.message, data.mode)
end
end
end
end
cb('ok')
cb('ok')
end)
end)
local function refreshCommands()
local function refreshCommands()
if GetRegisteredCommands then
if GetRegisteredCommands then
local registeredCommands = GetRegisteredCommands()
local registeredCommands = GetRegisteredCommands()
local suggestions = {}
local suggestions = {}
for _, command in ipairs(registeredCommands) do
for _, command in ipairs(registeredCommands) do
if IsAceAllowed(('command.%s'):format(command.name)) and command.name ~= 'toggleChat' then
if IsAceAllowed(('command.%s'):format(command.name)) and command.name ~= 'toggleChat' then
table.insert(suggestions, {
table.insert(suggestions, {
name = '/' .. command.name,
name = '/' .. command.name,
help = ''
help = ''
})
})
end
end
end
end
TriggerEvent('chat:addSuggestions', suggestions)
TriggerEvent('chat:addSuggestions', suggestions)
end
end
end
end
local function refreshThemes()
local function refreshThemes()
local themes = {}
local themes = {}
for resIdx = 0, GetNumResources() - 1 do
for resIdx = 0, GetNumResources() - 1 do
local resource = GetResourceByFindIndex(resIdx)
local resource = GetResourceByFindIndex(resIdx)
if GetResourceState(resource) == 'started' then
if GetResourceState(resource) == 'started' then
local numThemes = GetNumResourceMetadata(resource, 'chat_theme')
local numThemes = GetNumResourceMetadata(resource, 'chat_theme')
if numThemes > 0 then
if numThemes > 0 then
local themeName = GetResourceMetadata(resource, 'chat_theme')
local themeName = GetResourceMetadata(resource, 'chat_theme')
local themeData = json.decode(GetResourceMetadata(resource, 'chat_theme_extra') or 'null')
local themeData = json.decode(GetResourceMetadata(resource, 'chat_theme_extra') or 'null')
if themeName and themeData then
if themeName and themeData then
themeData.baseUrl = 'nui://' .. resource .. '/'
themeData.baseUrl = 'nui://' .. resource .. '/'
themes[themeName] = themeData
themes[themeName] = themeData
end
end
end
end
end
end
end
end
SendNUIMessage({
SendNUIMessage({
type = 'ON_UPDATE_THEMES',
type = 'ON_UPDATE_THEMES',
themes = themes
themes = themes
})
})
end
end
AddEventHandler('onClientResourceStart', function(resName)
AddEventHandler('onClientResourceStart', function(resName)
Wait(500)
Wait(500)
Copy
Copied
Copy
Copied
SetTextChatEnabled(true)
refreshCommands()
--
refreshCommands()
refreshThemes()
--
refreshThemes()
end)
end)
AddEventHandler('onClientResourceStop', function(resName)
AddEventHandler('onClientResourceStop', function(resName)
Wait(500)
Wait(500)
Copy
Copied
Copy
Copied
refreshCommands()
--
refreshCommands()
refreshThemes()
--
refreshThemes()
end)
end)
RegisterNUICallback('loaded', function(data, cb)
RegisterNUICallback('loaded', function(data, cb)
Copy
Copied
Copy
Copied
TriggerServerEvent('chat:init')
--
TriggerServerEvent('chat:init')
Copy
Copied
Copy
Copied
refreshCommands()
--
refreshCommands()
refreshThemes()
--
refreshThemes()
chatLoaded = true
chatLoaded = true
cb('ok')
cb('ok')
end)
end)
local CHAT_HIDE_STATES = {
local CHAT_HIDE_STATES = {
SHOW_WHEN_ACTIVE = 0,
SHOW_WHEN_ACTIVE = 0,
ALWAYS_SHOW = 1,
ALWAYS_SHOW = 1,
ALWAYS_HIDE = 2
ALWAYS_HIDE = 2
}
}
local kvpEntry = GetResourceKvpString('hideState')
local kvpEntry = GetResourceKvpString('hideState')
local chatHideState = kvpEntry and tonumber(kvpEntry) or CHAT_HIDE_STATES.SHOW_WHEN_ACTIVE
local chatHideState = kvpEntry and tonumber(kvpEntry) or CHAT_HIDE_STATES.SHOW_WHEN_ACTIVE
local isFirstHide = true
local isFirstHide = true
Copy
Copied
Copy
Copied
if not isRDR then
--
if not isRDR then
if RegisterKeyMapping then
--
if RegisterKeyMapping then
RegisterKeyMapping('toggleChat', 'Toggle chat', 'keyboard', 'l')
--
RegisterKeyMapping('toggleChat', 'Toggle chat', 'keyboard', 'l')
end
--
end
--
RegisterCommand('toggleChat', function()
--
RegisterCommand('toggleChat', function()
if chatHideState == CHAT_HIDE_STATES.SHOW_WHEN_ACTIVE then
--
if chatHideState == CHAT_HIDE_STATES.SHOW_WHEN_ACTIVE then
chatHideState = CHAT_HIDE_STATES.ALWAYS_SHOW
--
chatHideState = CHAT_HIDE_STATES.ALWAYS_SHOW
elseif chatHideState == CHAT_HIDE_STATES.ALWAYS_SHOW then
--
elseif chatHideState == CHAT_HIDE_STATES.ALWAYS_SHOW then
chatHideState = CHAT_HIDE_STATES.ALWAYS_HIDE
--
chatHideState = CHAT_HIDE_STATES.ALWAYS_HIDE
elseif chatHideState == CHAT_HIDE_STATES.ALWAYS_HIDE then
--
elseif chatHideState == CHAT_HIDE_STATES.ALWAYS_HIDE then
chatHideState = CHAT_HIDE_STATES.SHOW_WHEN_ACTIVE
--
chatHideState = CHAT_HIDE_STATES.SHOW_WHEN_ACTIVE
end
--
end
--
isFirstHide = false
--
isFirstHide = false
--
SetResourceKvp('hideState', tostring(chatHideState))
--
SetResourceKvp('hideState', tostring(chatHideState))
end, false)
--
end, false)
end
--
end
--
Citizen.CreateThread(function()
Citizen.CreateThread(function()
SetTextChatEnabled(false)
SetTextChatEnabled(false)
SetNuiFocus(false)
SetNuiFocus(false)
local lastChatHideState = -1
local lastChatHideState = -1
local origChatHideState = -1
local origChatHideState = -1
while true do
while true do
Wait(0)
Wait(0)
if not chatInputActive then
if not chatInputActive then
if IsControlPressed(0, isRDR and `INPUT_MP_TEXT_CHAT_ALL` or 245) --[[ INPUT_MP_TEXT_CHAT_ALL ]] then
if IsControlPressed(0, isRDR and `INPUT_MP_TEXT_CHAT_ALL` or 245) --[[ INPUT_MP_TEXT_CHAT_ALL ]] then
Copy
Copied
Copy
Copied
chatInputActive =
true
chatInputActive =
false
chatInputActivating =
true
chatInputActivating =
false
Copy
Copied
Copy
Copied
SendNUIMessage({
--
SendNUIMessage({
type = 'ON_OPEN'
--
type = 'ON_OPEN'
})
--
})
end
end
end
end
if chatInputActivating then
if chatInputActivating then
if not IsControlPressed(0, isRDR and `INPUT_MP_TEXT_CHAT_ALL` or 245) then
if not IsControlPressed(0, isRDR and `INPUT_MP_TEXT_CHAT_ALL` or 245) then
Copy
Copied
Copy
Copied
SetNuiFocus(
true
)
SetNuiFocus(
false
)
chatInputActivating = false
chatInputActivating = false
end
end
end
end
if chatLoaded then
if chatLoaded then
local forceHide = IsScreenFadedOut() or IsPauseMenuActive()
local forceHide = IsScreenFadedOut() or IsPauseMenuActive()
local wasForceHide = false
local wasForceHide = false
if chatHideState ~= CHAT_HIDE_STATES.ALWAYS_HIDE then
if chatHideState ~= CHAT_HIDE_STATES.ALWAYS_HIDE then
if forceHide then
if forceHide then
origChatHideState = chatHideState
origChatHideState = chatHideState
chatHideState = CHAT_HIDE_STATES.ALWAYS_HIDE
chatHideState = CHAT_HIDE_STATES.ALWAYS_HIDE
end
end
elseif not forceHide and origChatHideState ~= -1 then
elseif not forceHide and origChatHideState ~= -1 then
chatHideState = origChatHideState
chatHideState = origChatHideState
origChatHideState = -1
origChatHideState = -1
wasForceHide = true
wasForceHide = true
end
end
if chatHideState ~= lastChatHideState then
if chatHideState ~= lastChatHideState then
lastChatHideState = chatHideState
lastChatHideState = chatHideState
SendNUIMessage({
SendNUIMessage({
type = 'ON_SCREEN_STATE_CHANGE',
type = 'ON_SCREEN_STATE_CHANGE',
hideState = chatHideState,
hideState = chatHideState,
fromUserInteraction = not forceHide and not isFirstHide and not wasForceHide
fromUserInteraction = not forceHide and not isFirstHide and not wasForceHide
})
})
isFirstHide = false
isFirstHide = false
end
end
end
end
end
end
end)
end)
Copy
Copied
Copy
Copied
Saved diffs
Original text
Open file
local isRDR = not TerraingridActivate and true or false local chatInputActive = false local chatInputActivating = false local chatLoaded = false RegisterNetEvent('chatMessage') RegisterNetEvent('chat:addTemplate') RegisterNetEvent('chat:addMessage') RegisterNetEvent('chat:addSuggestion') RegisterNetEvent('chat:addSuggestions') RegisterNetEvent('chat:addMode') RegisterNetEvent('chat:removeMode') RegisterNetEvent('chat:removeSuggestion') RegisterNetEvent('chat:clear') -- internal events RegisterNetEvent('__cfx_internal:serverPrint') RegisterNetEvent('_chat:messageEntered') --deprecated, use chat:addMessage AddEventHandler('chatMessage', function(author, color, text) local args = { text } if author ~= "" then table.insert(args, 1, author) end SendNUIMessage({ type = 'ON_MESSAGE', message = { color = color, multiline = true, args = args } }) end) AddEventHandler('__cfx_internal:serverPrint', function(msg) print(msg) SendNUIMessage({ type = 'ON_MESSAGE', message = { templateId = 'print', multiline = true, args = { msg }, mode = '_global' } }) end) -- addMessage local addMessage = function(message) if type(message) == 'string' then message = { args = { message } } end SendNUIMessage({ type = 'ON_MESSAGE', message = message }) end exports('addMessage', addMessage) AddEventHandler('chat:addMessage', addMessage) -- addSuggestion local addSuggestion = function(name, help, params) SendNUIMessage({ type = 'ON_SUGGESTION_ADD', suggestion = { name = name, help = help, params = params or nil } }) end exports('addSuggestion', addSuggestion) AddEventHandler('chat:addSuggestion', addSuggestion) AddEventHandler('chat:addSuggestions', function(suggestions) for _, suggestion in ipairs(suggestions) do SendNUIMessage({ type = 'ON_SUGGESTION_ADD', suggestion = suggestion }) end end) AddEventHandler('chat:removeSuggestion', function(name) SendNUIMessage({ type = 'ON_SUGGESTION_REMOVE', name = name }) end) AddEventHandler('chat:addMode', function(mode) SendNUIMessage({ type = 'ON_MODE_ADD', mode = mode }) end) AddEventHandler('chat:removeMode', function(name) SendNUIMessage({ type = 'ON_MODE_REMOVE', name = name }) end) AddEventHandler('chat:addTemplate', function(id, html) SendNUIMessage({ type = 'ON_TEMPLATE_ADD', template = { id = id, html = html } }) end) AddEventHandler('chat:clear', function(name) SendNUIMessage({ type = 'ON_CLEAR' }) end) RegisterNUICallback('chatResult', function(data, cb) chatInputActive = false SetNuiFocus(false) if not data.canceled then local id = PlayerId() --deprecated local r, g, b = 0, 0x99, 255 if data.message:sub(1, 1) == '/' then ExecuteCommand(data.message:sub(2)) else TriggerServerEvent('_chat:messageEntered', GetPlayerName(id), { r, g, b }, data.message, data.mode) end end cb('ok') end) local function refreshCommands() if GetRegisteredCommands then local registeredCommands = GetRegisteredCommands() local suggestions = {} for _, command in ipairs(registeredCommands) do if IsAceAllowed(('command.%s'):format(command.name)) and command.name ~= 'toggleChat' then table.insert(suggestions, { name = '/' .. command.name, help = '' }) end end TriggerEvent('chat:addSuggestions', suggestions) end end local function refreshThemes() local themes = {} for resIdx = 0, GetNumResources() - 1 do local resource = GetResourceByFindIndex(resIdx) if GetResourceState(resource) == 'started' then local numThemes = GetNumResourceMetadata(resource, 'chat_theme') if numThemes > 0 then local themeName = GetResourceMetadata(resource, 'chat_theme') local themeData = json.decode(GetResourceMetadata(resource, 'chat_theme_extra') or 'null') if themeName and themeData then themeData.baseUrl = 'nui://' .. resource .. '/' themes[themeName] = themeData end end end end SendNUIMessage({ type = 'ON_UPDATE_THEMES', themes = themes }) end AddEventHandler('onClientResourceStart', function(resName) Wait(500) refreshCommands() refreshThemes() end) AddEventHandler('onClientResourceStop', function(resName) Wait(500) refreshCommands() refreshThemes() end) RegisterNUICallback('loaded', function(data, cb) TriggerServerEvent('chat:init') refreshCommands() refreshThemes() chatLoaded = true cb('ok') end) local CHAT_HIDE_STATES = { SHOW_WHEN_ACTIVE = 0, ALWAYS_SHOW = 1, ALWAYS_HIDE = 2 } local kvpEntry = GetResourceKvpString('hideState') local chatHideState = kvpEntry and tonumber(kvpEntry) or CHAT_HIDE_STATES.SHOW_WHEN_ACTIVE local isFirstHide = true if not isRDR then if RegisterKeyMapping then RegisterKeyMapping('toggleChat', 'Toggle chat', 'keyboard', 'l') end RegisterCommand('toggleChat', function() if chatHideState == CHAT_HIDE_STATES.SHOW_WHEN_ACTIVE then chatHideState = CHAT_HIDE_STATES.ALWAYS_SHOW elseif chatHideState == CHAT_HIDE_STATES.ALWAYS_SHOW then chatHideState = CHAT_HIDE_STATES.ALWAYS_HIDE elseif chatHideState == CHAT_HIDE_STATES.ALWAYS_HIDE then chatHideState = CHAT_HIDE_STATES.SHOW_WHEN_ACTIVE end isFirstHide = false SetResourceKvp('hideState', tostring(chatHideState)) end, false) end Citizen.CreateThread(function() SetTextChatEnabled(false) SetNuiFocus(false) local lastChatHideState = -1 local origChatHideState = -1 while true do Wait(0) if not chatInputActive then if IsControlPressed(0, isRDR and `INPUT_MP_TEXT_CHAT_ALL` or 245) --[[ INPUT_MP_TEXT_CHAT_ALL ]] then chatInputActive = true chatInputActivating = true SendNUIMessage({ type = 'ON_OPEN' }) end end if chatInputActivating then if not IsControlPressed(0, isRDR and `INPUT_MP_TEXT_CHAT_ALL` or 245) then SetNuiFocus(true) chatInputActivating = false end end if chatLoaded then local forceHide = IsScreenFadedOut() or IsPauseMenuActive() local wasForceHide = false if chatHideState ~= CHAT_HIDE_STATES.ALWAYS_HIDE then if forceHide then origChatHideState = chatHideState chatHideState = CHAT_HIDE_STATES.ALWAYS_HIDE end elseif not forceHide and origChatHideState ~= -1 then chatHideState = origChatHideState origChatHideState = -1 wasForceHide = true end if chatHideState ~= lastChatHideState then lastChatHideState = chatHideState SendNUIMessage({ type = 'ON_SCREEN_STATE_CHANGE', hideState = chatHideState, fromUserInteraction = not forceHide and not isFirstHide and not wasForceHide }) isFirstHide = false end end end end)
Changed text
Open file
local isRDR = not TerraingridActivate and true or false local chatInputActive = false local chatInputActivating = false local chatLoaded = false RegisterNetEvent('chatMessage') RegisterNetEvent('chat:addTemplate') RegisterNetEvent('chat:addMessage') RegisterNetEvent('chat:addSuggestion') RegisterNetEvent('chat:addSuggestions') RegisterNetEvent('chat:addMode') RegisterNetEvent('chat:removeMode') RegisterNetEvent('chat:removeSuggestion') RegisterNetEvent('chat:clear') -- internal events RegisterNetEvent('__cfx_internal:serverPrint') RegisterNetEvent('_chat:messageEntered') --deprecated, use chat:addMessage AddEventHandler('chatMessage', function(author, color, text) local args = { text } if author ~= "" then table.insert(args, 1, author) end SendNUIMessage({ type = 'ON_MESSAGE', message = { color = color, multiline = true, args = args } }) end) AddEventHandler('__cfx_internal:serverPrint', function(msg) print(msg) SendNUIMessage({ type = 'ON_MESSAGE', message = { templateId = 'print', multiline = true, args = { msg }, mode = '_global' } }) end) -- addMessage local addMessage = function(message) if type(message) == 'string' then message = { args = { message } } end SendNUIMessage({ type = 'ON_MESSAGE', message = message }) end exports('addMessage', addMessage) AddEventHandler('chat:addMessage', addMessage) -- addSuggestion local addSuggestion = function(name, help, params) SendNUIMessage({ type = 'ON_SUGGESTION_ADD', suggestion = { name = name, help = help, params = params or nil } }) end exports('addSuggestion', addSuggestion) AddEventHandler('chat:addSuggestion', addSuggestion) AddEventHandler('chat:addSuggestions', function(suggestions) for _, suggestion in ipairs(suggestions) do SendNUIMessage({ type = 'ON_SUGGESTION_ADD', suggestion = suggestion }) end end) AddEventHandler('chat:removeSuggestion', function(name) SendNUIMessage({ type = 'ON_SUGGESTION_REMOVE', name = name }) end) AddEventHandler('chat:addMode', function(mode) SendNUIMessage({ type = 'ON_MODE_ADD', mode = mode }) end) AddEventHandler('chat:removeMode', function(name) SendNUIMessage({ type = 'ON_MODE_REMOVE', name = name }) end) AddEventHandler('chat:addTemplate', function(id, html) SendNUIMessage({ type = 'ON_TEMPLATE_ADD', template = { id = id, html = html } }) end) AddEventHandler('chat:clear', function(name) SendNUIMessage({ type = 'ON_CLEAR' }) end) RegisterNUICallback('chatResult', function(data, cb) chatInputActive = false SetNuiFocus(false) if not data.canceled then local id = PlayerId() --deprecated local r, g, b = 0, 0x99, 255 if data.message:sub(1, 1) == '/' then ExecuteCommand(data.message:sub(2)) else TriggerServerEvent('_chat:messageEntered', GetPlayerName(id), { r, g, b }, data.message, data.mode) end end cb('ok') end) local function refreshCommands() if GetRegisteredCommands then local registeredCommands = GetRegisteredCommands() local suggestions = {} for _, command in ipairs(registeredCommands) do if IsAceAllowed(('command.%s'):format(command.name)) and command.name ~= 'toggleChat' then table.insert(suggestions, { name = '/' .. command.name, help = '' }) end end TriggerEvent('chat:addSuggestions', suggestions) end end local function refreshThemes() local themes = {} for resIdx = 0, GetNumResources() - 1 do local resource = GetResourceByFindIndex(resIdx) if GetResourceState(resource) == 'started' then local numThemes = GetNumResourceMetadata(resource, 'chat_theme') if numThemes > 0 then local themeName = GetResourceMetadata(resource, 'chat_theme') local themeData = json.decode(GetResourceMetadata(resource, 'chat_theme_extra') or 'null') if themeName and themeData then themeData.baseUrl = 'nui://' .. resource .. '/' themes[themeName] = themeData end end end end SendNUIMessage({ type = 'ON_UPDATE_THEMES', themes = themes }) end AddEventHandler('onClientResourceStart', function(resName) Wait(500) SetTextChatEnabled(true) -- refreshCommands() -- refreshThemes() end) AddEventHandler('onClientResourceStop', function(resName) Wait(500) -- refreshCommands() -- refreshThemes() end) RegisterNUICallback('loaded', function(data, cb) -- TriggerServerEvent('chat:init') -- refreshCommands() -- refreshThemes() chatLoaded = true cb('ok') end) local CHAT_HIDE_STATES = { SHOW_WHEN_ACTIVE = 0, ALWAYS_SHOW = 1, ALWAYS_HIDE = 2 } local kvpEntry = GetResourceKvpString('hideState') local chatHideState = kvpEntry and tonumber(kvpEntry) or CHAT_HIDE_STATES.SHOW_WHEN_ACTIVE local isFirstHide = true -- if not isRDR then -- if RegisterKeyMapping then -- RegisterKeyMapping('toggleChat', 'Toggle chat', 'keyboard', 'l') -- end -- -- RegisterCommand('toggleChat', function() -- if chatHideState == CHAT_HIDE_STATES.SHOW_WHEN_ACTIVE then -- chatHideState = CHAT_HIDE_STATES.ALWAYS_SHOW -- elseif chatHideState == CHAT_HIDE_STATES.ALWAYS_SHOW then -- chatHideState = CHAT_HIDE_STATES.ALWAYS_HIDE -- elseif chatHideState == CHAT_HIDE_STATES.ALWAYS_HIDE then -- chatHideState = CHAT_HIDE_STATES.SHOW_WHEN_ACTIVE -- end -- -- isFirstHide = false -- -- SetResourceKvp('hideState', tostring(chatHideState)) -- end, false) -- end -- Citizen.CreateThread(function() SetTextChatEnabled(false) SetNuiFocus(false) local lastChatHideState = -1 local origChatHideState = -1 while true do Wait(0) if not chatInputActive then if IsControlPressed(0, isRDR and `INPUT_MP_TEXT_CHAT_ALL` or 245) --[[ INPUT_MP_TEXT_CHAT_ALL ]] then chatInputActive = false chatInputActivating = false -- SendNUIMessage({ -- type = 'ON_OPEN' -- }) end end if chatInputActivating then if not IsControlPressed(0, isRDR and `INPUT_MP_TEXT_CHAT_ALL` or 245) then SetNuiFocus(false) chatInputActivating = false end end if chatLoaded then local forceHide = IsScreenFadedOut() or IsPauseMenuActive() local wasForceHide = false if chatHideState ~= CHAT_HIDE_STATES.ALWAYS_HIDE then if forceHide then origChatHideState = chatHideState chatHideState = CHAT_HIDE_STATES.ALWAYS_HIDE end elseif not forceHide and origChatHideState ~= -1 then chatHideState = origChatHideState origChatHideState = -1 wasForceHide = true end if chatHideState ~= lastChatHideState then lastChatHideState = chatHideState SendNUIMessage({ type = 'ON_SCREEN_STATE_CHANGE', hideState = chatHideState, fromUserInteraction = not forceHide and not isFirstHide and not wasForceHide }) isFirstHide = false end end end end)
Find difference