Fix chat issues: lobby visibility, event errors, message display, and text alignment

- Remove event.preventDefault() calls as these events are not cancellable in GTA Connected
- Add in-game detection using localPlayer to hide chat when in lobby
- Change network event parameters from objects to individual args for compatibility
- Fix text alignment with consistent font sizes and proper vertical centering
- Rename to "Revolution chat" per user preference
This commit is contained in:
Claude
2026-01-26 10:04:19 +00:00
parent 7943aba360
commit 2b62ce56ce
2 changed files with 92 additions and 76 deletions

View File

@@ -63,6 +63,9 @@ let lastMessageTime = 0;
let chatFadeDelay = 10000; // 10 seconds before fade let chatFadeDelay = 10000; // 10 seconds before fade
let chatFadeSpeed = 0.02; let chatFadeSpeed = 0.02;
// Track if player is in game (spawned)
let isPlayerInGame = false;
// Welcome/Leave notification queue // Welcome/Leave notification queue
let notifications = []; let notifications = [];
let notificationDuration = 5000; // 5 seconds let notificationDuration = 5000; // 5 seconds
@@ -75,8 +78,12 @@ const chat = {
messageHeight: 22, messageHeight: 22,
maxVisibleMessages: 12, maxVisibleMessages: 12,
padding: 12, padding: 12,
inputHeight: 36, inputHeight: 32,
borderRadius: 4 borderRadius: 4,
// Font sizes for consistent text alignment
fontSize: 10,
timestampSize: 10,
inputFontSize: 10
}; };
// ============================================================================ // ============================================================================
@@ -104,19 +111,25 @@ addEventHandler("OnResourceStart", function(event, resource) {
// ============================================================================ // ============================================================================
// NETWORK EVENTS - Receive messages from server // NETWORK EVENTS - Receive messages from server
// ============================================================================ // ============================================================================
addNetworkHandler("chatMessage", function(messageData) { addNetworkHandler("chatMessage", function(text, type, playerName) {
addChatMessage(messageData.text, messageData.type || "normal", messageData.playerName || null); // Receives individual parameters instead of object for better compatibility
console.log("[Chat] Received message: " + text + " type: " + type + " from: " + playerName);
addChatMessage(text, type || "normal", playerName || null);
}); });
addNetworkHandler("playerJoined", function(data) { addNetworkHandler("playerJoined", function(playerName) {
addNotification(data.name + " joined the server", "join"); // Receives player name directly
addChatMessage(data.name + " has joined the server", "system"); console.log("[Chat] Player joined: " + playerName);
addNotification(playerName + " joined the server", "join");
addChatMessage(playerName + " has joined the server", "system");
}); });
addNetworkHandler("playerLeft", function(data) { addNetworkHandler("playerLeft", function(playerName, reason) {
let reason = data.reason || "Disconnected"; // Receives individual parameters
addNotification(data.name + " left the server", "leave"); console.log("[Chat] Player left: " + playerName + " reason: " + reason);
addChatMessage(data.name + " has left the server (" + reason + ")", "system"); let reasonText = reason || "Disconnected";
addNotification(playerName + " left the server", "leave");
addChatMessage(playerName + " has left the server (" + reasonText + ")", "system");
}); });
// ============================================================================ // ============================================================================
@@ -217,6 +230,9 @@ function drawText(text, x, y, colour, size) {
addEventHandler("OnDrawnHUD", function(event) { addEventHandler("OnDrawnHUD", function(event) {
animTime += 0.016; // ~60fps animTime += 0.016; // ~60fps
// Update player in-game state
isPlayerInGame = checkIfPlayerInGame();
let screenWidth = 1920; let screenWidth = 1920;
let screenHeight = 1080; let screenHeight = 1080;
try { try {
@@ -224,6 +240,15 @@ addEventHandler("OnDrawnHUD", function(event) {
screenHeight = game.height || 1080; screenHeight = game.height || 1080;
} catch(e) {} } catch(e) {}
// Don't render anything if player is in lobby (not spawned)
if (!isPlayerInGame) {
// Close chat input if it was open when entering lobby
if (chatInputActive) {
closeChatInput();
}
return;
}
// Update fade // Update fade
if (Date.now() - lastMessageTime > chatFadeDelay && !chatInputActive) { if (Date.now() - lastMessageTime > chatFadeDelay && !chatInputActive) {
chatFadeAlpha = Math.max(0.3, chatFadeAlpha - chatFadeSpeed); chatFadeAlpha = Math.max(0.3, chatFadeAlpha - chatFadeSpeed);
@@ -277,13 +302,16 @@ addEventHandler("OnDrawnHUD", function(event) {
let headerBg = toColour(UI.bgPanel.r, UI.bgPanel.g, UI.bgPanel.b, bgAlpha); let headerBg = toColour(UI.bgPanel.r, UI.bgPanel.g, UI.bgPanel.b, bgAlpha);
drawRect(chat.x, chat.y + 2, chat.width, headerHeight, headerBg); drawRect(chat.x, chat.y + 2, chat.width, headerHeight, headerBg);
// Calculate vertical centering for header text
let headerTextY = chat.y + Math.floor((headerHeight + 4 - 11) / 2);
// Header text // Header text
let headerTextCol = toColour(UI.accent.r, UI.accent.g, UI.accent.b, alpha); let headerTextCol = toColour(UI.accent.r, UI.accent.g, UI.accent.b, alpha);
drawText("CHAT", chat.x + chat.padding, chat.y + 8, headerTextCol, 11); drawText("CHAT", chat.x + chat.padding, headerTextY, headerTextCol, 11);
// Online count (placeholder - can be updated via network) // Online count (placeholder - can be updated via network)
let onlineCol = toColour(UI.textSecondary.r, UI.textSecondary.g, UI.textSecondary.b, alpha); let onlineCol = toColour(UI.textSecondary.r, UI.textSecondary.g, UI.textSecondary.b, alpha);
drawText("Press T to chat", chat.x + chat.width - 120, chat.y + 9, onlineCol, 9); drawText("Press T to chat", chat.x + chat.width - 115, headerTextY + 1, onlineCol, chat.fontSize);
// Header bottom border // Header bottom border
let headerBorder = toColour(UI.border.r, UI.border.g, UI.border.b, Math.floor(100 * chatFadeAlpha)); let headerBorder = toColour(UI.border.r, UI.border.g, UI.border.b, Math.floor(100 * chatFadeAlpha));
@@ -311,23 +339,27 @@ addEventHandler("OnDrawnHUD", function(event) {
let msgColor = getMessageColor(msg.type); let msgColor = getMessageColor(msg.type);
let textCol = toColour(msgColor.r, msgColor.g, msgColor.b, alpha); let textCol = toColour(msgColor.r, msgColor.g, msgColor.b, alpha);
// Calculate vertical centering offset for text in message row
let textY = msgY + Math.floor((chat.messageHeight - chat.fontSize) / 2) - 2;
// Draw timestamp // Draw timestamp
let time = new Date(msg.timestamp); let time = new Date(msg.timestamp);
let timeStr = "[" + padZero(time.getHours()) + ":" + padZero(time.getMinutes()) + "]"; let timeStr = "[" + padZero(time.getHours()) + ":" + padZero(time.getMinutes()) + "]";
let timeCol = toColour(UI.textMuted.r, UI.textMuted.g, UI.textMuted.b, Math.floor(alpha * 0.7)); let timeCol = toColour(UI.textMuted.r, UI.textMuted.g, UI.textMuted.b, Math.floor(alpha * 0.7));
drawText(timeStr, chat.x + chat.padding, msgY, timeCol, 9); drawText(timeStr, chat.x + chat.padding, textY, timeCol, chat.timestampSize);
// Draw message text // Draw message text - timestamp takes approximately 50 pixels
let textX = chat.x + chat.padding + 55; let textX = chat.x + chat.padding + 52;
if (msg.playerName && msg.type === "normal") { if (msg.playerName && msg.type === "normal") {
// Player name in accent color // Player name in accent color
let nameCol = toColour(UI.playerName.r, UI.playerName.g, UI.playerName.b, alpha); let nameCol = toColour(UI.playerName.r, UI.playerName.g, UI.playerName.b, alpha);
drawText(msg.playerName + ":", textX, msgY, nameCol, 10); drawText(msg.playerName + ":", textX, textY, nameCol, chat.fontSize);
// Message text // Message text - use consistent character width calculation (6 pixels per char for size 10)
drawText(msg.text, textX + (msg.playerName.length * 7) + 12, msgY, textCol, 10); let nameWidth = (msg.playerName.length + 1) * 6 + 8;
drawText(msg.text, textX + nameWidth, textY, textCol, chat.fontSize);
} else { } else {
drawText(msg.text, textX, msgY, textCol, 10); drawText(msg.text, textX, textY, textCol, chat.fontSize);
} }
} }
@@ -368,15 +400,18 @@ addEventHandler("OnDrawnHUD", function(event) {
drawRect(chat.x, inputY, 2, chat.inputHeight, inputBorder); drawRect(chat.x, inputY, 2, chat.inputHeight, inputBorder);
drawRect(chat.x + chat.width - 2, inputY, 2, chat.inputHeight, inputBorder); drawRect(chat.x + chat.width - 2, inputY, 2, chat.inputHeight, inputBorder);
// Input label // Calculate vertical centering for input text
let labelCol = toColour(UI.textMuted.r, UI.textMuted.g, UI.textMuted.b, 255); let inputTextY = inputY + Math.floor((chat.inputHeight - chat.inputFontSize) / 2) - 1;
drawText("Say:", chat.x + chat.padding, inputY + 10, labelCol, 10);
// Input text with cursor // Input label "Say:" with consistent positioning
let labelCol = toColour(UI.textMuted.r, UI.textMuted.g, UI.textMuted.b, 255);
drawText("Say:", chat.x + chat.padding, inputTextY, labelCol, chat.inputFontSize);
// Input text with cursor - "Say:" takes about 30 pixels
let cursorBlink = Math.floor(animTime * 2) % 2 === 0; let cursorBlink = Math.floor(animTime * 2) % 2 === 0;
let inputTextCol = toColour(UI.textPrimary.r, UI.textPrimary.g, UI.textPrimary.b, 255); let inputTextCol = toColour(UI.textPrimary.r, UI.textPrimary.g, UI.textPrimary.b, 255);
let displayText = chatInputText + (cursorBlink ? "|" : ""); let displayText = chatInputText + (cursorBlink ? "|" : "");
drawText(displayText, chat.x + chat.padding + 40, inputY + 10, inputTextCol, 10); drawText(displayText, chat.x + chat.padding + 36, inputTextY, inputTextCol, chat.inputFontSize);
} }
// ======================================== // ========================================
@@ -467,6 +502,17 @@ function padZero(num) {
return num < 10 ? "0" + num : num.toString(); return num < 10 ? "0" + num : num.toString();
} }
// Check if player is spawned in game (not in lobby)
function checkIfPlayerInGame() {
try {
// localPlayer is null/undefined when player is not spawned (in lobby)
if (typeof localPlayer !== 'undefined' && localPlayer != null) {
return true;
}
} catch(e) {}
return false;
}
// ============================================================================ // ============================================================================
// KEY CODE CONSTANTS (in case they're not predefined) // KEY CODE CONSTANTS (in case they're not predefined)
// SDL key codes use ASCII values for letters (lowercase) // SDL key codes use ASCII values for letters (lowercase)
@@ -484,7 +530,8 @@ const KEY_PAGEDOWN = typeof SDLK_PAGEDOWN !== 'undefined' ? SDLK_PAGEDOWN : 1073
// Bind T key to open chat // Bind T key to open chat
bindKey(KEY_T, KEYSTATE_UP, function(event) { bindKey(KEY_T, KEYSTATE_UP, function(event) {
if (!chatInputActive) { // Only allow opening chat if player is in game (not in lobby)
if (!chatInputActive && isPlayerInGame) {
openChatInput(); openChatInput();
} }
}); });
@@ -528,14 +575,12 @@ addEventHandler("OnKeyUp", function(event, key, scancode, mods) {
// Escape to close chat // Escape to close chat
if ((key === KEY_ESCAPE || key === SDLK_ESCAPE) && chatInputActive) { if ((key === KEY_ESCAPE || key === SDLK_ESCAPE) && chatInputActive) {
closeChatInput(); closeChatInput();
event.preventDefault();
return; return;
} }
// Enter to send message // Enter to send message
if ((key === KEY_RETURN || key === SDLK_RETURN) && chatInputActive) { if ((key === KEY_RETURN || key === SDLK_RETURN) && chatInputActive) {
sendChatMessage(); sendChatMessage();
event.preventDefault();
return; return;
} }
@@ -559,7 +604,7 @@ addEventHandler("OnCharacter", function(event, character) {
if (character.charCodeAt(0) >= 32) { if (character.charCodeAt(0) >= 32) {
chatInputText += character; chatInputText += character;
} }
event.preventDefault(); // Note: OnCharacter event is not cancellable in GTA Connected
} }
}); });
@@ -569,11 +614,8 @@ addEventHandler("OnKeyDown", function(event, key, scancode, mods) {
// Backspace // Backspace
if ((key === KEY_BACKSPACE || key === SDLK_BACKSPACE) && chatInputText.length > 0) { if ((key === KEY_BACKSPACE || key === SDLK_BACKSPACE) && chatInputText.length > 0) {
chatInputText = chatInputText.slice(0, -1); chatInputText = chatInputText.slice(0, -1);
event.preventDefault();
} }
// Note: OnKeyDown event is not cancellable in GTA Connected
// Block other keys from reaching the game while typing
event.preventDefault();
}); });
// ============================================================================ // ============================================================================
@@ -627,9 +669,9 @@ addEventHandler("OnResourceReady", function(event, resource) {
console.log("[Chat] Could not disable default chat: " + e); console.log("[Chat] Could not disable default chat: " + e);
} }
// Add a test message to verify the chat is working // Add a welcome message - will only show when player is in game
addChatMessage("Custom chat loaded! Press T to type.", "system"); addChatMessage("Revolution chat loaded! Press T to type.", "system");
} }
}); });
console.log("[Chat] Client script loaded - Custom glossy UI enabled"); console.log("[Chat] Revolution chat loaded - Custom glossy UI enabled");

View File

@@ -41,14 +41,10 @@ addEventHandler("OnResourceStart", function(event, resource) {
addEventHandler("OnPlayerJoined", function(event, client) { addEventHandler("OnPlayerJoined", function(event, client) {
// Broadcast join notification to all clients // Broadcast join notification to all clients
let joinData = { // Send player name directly for better compatibility
name: client.name
};
// Send to all connected clients
let clients = getClients(); let clients = getClients();
for (let i = 0; i < clients.length; i++) { for (let i = 0; i < clients.length; i++) {
triggerNetworkEvent("playerJoined", clients[i], joinData); triggerNetworkEvent("playerJoined", clients[i], client.name);
} }
// Log to console // Log to console
@@ -63,15 +59,11 @@ addEventHandler("OnPlayerQuit", function(event, client, reason) {
let reasonText = getDisconnectReason(reason); let reasonText = getDisconnectReason(reason);
// Broadcast leave notification to all remaining clients // Broadcast leave notification to all remaining clients
let leaveData = { // Send individual parameters for better compatibility
name: client.name,
reason: reasonText
};
let clients = getClients(); let clients = getClients();
for (let i = 0; i < clients.length; i++) { for (let i = 0; i < clients.length; i++) {
if (clients[i].index !== client.index) { if (clients[i].index !== client.index) {
triggerNetworkEvent("playerLeft", clients[i], leaveData); triggerNetworkEvent("playerLeft", clients[i], client.name, reasonText);
} }
} }
@@ -102,15 +94,10 @@ function getDisconnectReason(reason) {
addEventHandler("OnPlayerChat", function(event, client, messageText) { addEventHandler("OnPlayerChat", function(event, client, messageText) {
// Broadcast to all clients via custom network event // Broadcast to all clients via custom network event
let chatData = { // Send individual parameters for better compatibility
text: messageText,
type: "normal",
playerName: client.name
};
let clients = getClients(); let clients = getClients();
for (let i = 0; i < clients.length; i++) { for (let i = 0; i < clients.length; i++) {
triggerNetworkEvent("chatMessage", clients[i], chatData); triggerNetworkEvent("chatMessage", clients[i], messageText, "normal", client.name);
} }
// Log to history // Log to history
@@ -124,6 +111,8 @@ addEventHandler("OnPlayerChat", function(event, client, messageText) {
addNetworkHandler("chatSendMessage", function(client, messageText) { addNetworkHandler("chatSendMessage", function(client, messageText) {
if (!messageText || messageText.length === 0) return; if (!messageText || messageText.length === 0) return;
console.log("[Chat] Received message from " + client.name + ": " + messageText);
// Check if it's a command // Check if it's a command
if (messageText.charAt(0) === '/') { if (messageText.charAt(0) === '/') {
// Parse command // Parse command
@@ -136,15 +125,10 @@ addNetworkHandler("chatSendMessage", function(client, messageText) {
} }
// Regular chat message - broadcast to all clients // Regular chat message - broadcast to all clients
let chatData = { // Send individual parameters for better compatibility
text: messageText,
type: "normal",
playerName: client.name
};
let clients = getClients(); let clients = getClients();
for (let i = 0; i < clients.length; i++) { for (let i = 0; i < clients.length; i++) {
triggerNetworkEvent("chatMessage", clients[i], chatData); triggerNetworkEvent("chatMessage", clients[i], messageText, "normal", client.name);
} }
// Log to history // Log to history
@@ -250,26 +234,16 @@ function handleCommand(client, cmd, params) {
// ============================================================================ // ============================================================================
function broadcastChatMessage(text, type, senderName) { function broadcastChatMessage(text, type, senderName) {
let chatData = { // Send individual parameters for better compatibility
text: text,
type: type || "normal",
playerName: senderName || null
};
let clients = getClients(); let clients = getClients();
for (let i = 0; i < clients.length; i++) { for (let i = 0; i < clients.length; i++) {
triggerNetworkEvent("chatMessage", clients[i], chatData); triggerNetworkEvent("chatMessage", clients[i], text, type || "normal", senderName || "");
} }
} }
function sendChatMessage(client, text, type, playerName) { function sendChatMessage(client, text, type, playerName) {
let chatData = { // Send individual parameters for better compatibility
text: text, triggerNetworkEvent("chatMessage", client, text, type || "normal", playerName || "");
type: type || "normal",
playerName: playerName || null
};
triggerNetworkEvent("chatMessage", client, chatData);
} }
function sendSystemMessage(client, text) { function sendSystemMessage(client, text) {