WebView
The WebView system allows server owners to create interactive web-based user interfaces within the game client. It supports both local resource files and remote URLs, providing a powerful way to create rich, modern UIs using HTML, CSS, and JavaScript.
Features
- Multiple WebView Support: Create and manage multiple webview instances simultaneously
- Local Resource Loading: Load HTML files from resource packages using
resource://
URLs - Remote Content: Load external websites and web applications
- Input Management: Full mouse and keyboard input support with focus management
- Z-Order Control: Layer multiple webviews with customizable depth ordering
- Security: Restricted file system access, only resource directories are accessible. All storage APIs are disabled. Microphone and camera access is disabled. WebViews are completely reset when joining a server.
Debugging
To open devtools for your webview, follow these steps:
- Open Google Chrome or another Chromium-based browser
- Go to
chrome://inspect
- Click on "Configure" next to "Discover network targets"
- Add
localhost:9222
to the list - You should see
JC4MP Webview
in the "Remote Targets" section. Click "Inspect" - Inside of the debugger, you will be able to expand and see all of your webviews as iframes.
Configuration Object
WebView configuration is passed as a table with the following properties:
local config = {
url = "resource://myresource/client/index.html", -- URL to load
position = vec2(100, 100), -- Screen position
size = vec2(800, 600), -- WebView dimensions
visible = true, -- Initial visibility
input_enabled = false, -- Disable input handling
z_order = 1 -- Layer depth (higher = front)
}
WebView.Create(id: string, config: table): string
Creates a new WebView instance with the specified configuration.
Parameters:
id
(string): Unique identifier for the WebView instanceconfig
(table): Configuration object with WebView settings
Returns:
string
: The WebView ID if successful, empty string if failed
Example:
local webview_id = WebView.Create("my_ui", {
url = "resource://myresource/client/dashboard.html",
position = vec2(200, 150),
size = vec2(1000, 700),
visible = true,
input_enabled = true,
z_order = 5
})
if webview_id ~= "" then
print("WebView created successfully!")
else
print("Failed to create WebView")
end
WebView.Destroy(id: string): boolean
Destroys an existing WebView instance and frees its resources.
Parameters:
id
(string): The WebView ID to destroy
Returns:
boolean
:true
if successfully destroyed,false
if WebView not found
Example:
if WebView.Destroy("my_ui") then
print("WebView destroyed")
else
print("WebView not found or failed to destroy")
end
WebView.LoadUrl(id: string, url: string): boolean
Navigates the WebView to a new URL. Supports both local resources and remote URLs.
Parameters:
id
(string): The WebView IDurl
(string): URL to navigate to
Returns:
boolean
:true
if navigation started successfully,false
otherwise
URL Formats:
- Local resources:
resource://resource_name/client/path/to/file.html
- Remote URLs:
https://example.com/page.html
Example:
-- Load local resource
WebView.LoadUrl("my_ui", "resource://myresource/client/settings.html")
-- Load remote content
WebView.LoadUrl("my_ui", "https://www.google.com")
-- Load with query parameters
WebView.LoadUrl("my_ui", "resource://myresource/client/player.html?id=123&mode=edit")
WebView.SetPosition(id: string, position: table): boolean
Moves the WebView to a new screen position.
Parameters:
id
(string): The WebView IDposition
(vec2): New position withx
andy
coordinates
Returns:
boolean
:true
if position updated successfully,false
otherwise
Example:
-- Move to top-left corner
WebView.SetPosition("my_ui", vec2(0, 0))
-- Center on screen (assuming 1920x1080)
WebView.SetPosition("my_ui", vec2(460, 240))
-- Animate position over time
local start_x, start_y = 100, 100
local target_x, target_y = 500, 300
local steps = 30
for i = 1, steps do
local progress = i / steps
local current_x = start_x + (target_x - start_x) * progress
local current_y = start_y + (target_y - start_y) * progress
WebView.SetPosition("my_ui", vec2(current_x, current_y))
-- Add delay between frames in real implementation
end
WebView.SetSize(id: string, size: table): boolean
Resizes the WebView to new dimensions.
Parameters:
id
(string): The WebView IDsize
(vec2): New size withx
(width) andy
(height)
Returns:
boolean
:true
if size updated successfully,false
otherwise
Example:
-- Set to standard size
WebView.SetSize("my_ui", vec2(800, 600))
-- Make fullscreen (assuming 1920x1080)
WebView.SetSize("my_ui", vec2(1920, 1080))
-- Responsive sizing based on content
local function resizeForContent(content_type)
if content_type == "chat" then
WebView.SetSize("my_ui", vec2(400, 300))
elseif content_type == "map" then
WebView.SetSize("my_ui", vec2(800, 800))
elseif content_type == "inventory" then
WebView.SetSize("my_ui", vec2(600, 500))
end
end
WebView.SetVisible(id: string, visible: boolean): boolean
Shows or hides the WebView.
Parameters:
id
(string): The WebView IDvisible
(boolean):true
to show,false
to hide
Returns:
boolean
:true
if visibility updated successfully,false
otherwise
Example:
-- Show WebView
WebView.SetVisible("my_ui", true)
-- Hide WebView
WebView.SetVisible("my_ui", false)
-- Toggle visibility
local function toggleWebView(id)
local info = WebView.GetInfo(id)
if info then
WebView.SetVisible(id, not info.visible)
end
end
WebView.Focus(id: string): boolean
Gives keyboard focus to the specified WebView, allowing it to receive input events.
Parameters:
id
(string): The WebView ID to focus
Returns:
boolean
:true
if focused successfully,false
otherwise
Example:
-- Focus a WebView for text input
WebView.Focus("chat_window")
-- Focus the topmost WebView
local function focusTopWebView()
local webviews = {"ui_main", "chat", "map", "inventory"}
local highest_z = -1
local top_webview = nil
for _, id in ipairs(webviews) do
local info = WebView.GetInfo(id)
if info and info.visible and info.z_order > highest_z then
highest_z = info.z_order
top_webview = id
end
end
if top_webview then
WebView.Focus(top_webview)
end
end
WebView.BlurAll(): boolean
Removes focus from all WebViews, preventing them from receiving keyboard input.
Returns:
boolean
:true
if all WebViews were blurred successfully
Example:
-- Remove focus from all WebViews when game needs input
WebView.BlurAll()
-- Blur all when opening game menu
local function openGameMenu()
WebView.BlurAll()
-- Show game menu
end
-- Blur all except specific WebView
local function focusOnly(target_id)
WebView.BlurAll()
WebView.Focus(target_id)
end
WebView.BringToFront(id: string): boolean
Brings the WebView to the front by adjusting its z-order.
Parameters:
id
(string): The WebView ID to bring to front
Returns:
boolean
:true
if z-order updated successfully,false
otherwise
Example:
-- Bring WebView to front when clicked
WebView.BringToFront("notification_panel")
-- Implement window management
local function bringToFrontOnClick(webview_id)
-- This would typically be called from a mouse click handler
WebView.BringToFront(webview_id)
WebView.Focus(webview_id)
end
WebView.SendToBack(id: string): boolean
Sends the WebView to the back by adjusting its z-order.
Parameters:
id
(string): The WebView ID to send to back
Returns:
boolean
:true
if z-order updated successfully,false
otherwise
Example:
-- Send background WebView to back
WebView.SendToBack("background_map")
-- Minimize window effect
local function minimizeWebView(id)
WebView.SendToBack(id)
WebView.SetSize(id, vec2(200, 150))
WebView.SetPosition(id, vec2(10, 10))
end
WebView.SetInputEnabled(id: string, enabled: boolean): boolean
Enables or disables input handling for the WebView. You should set this to true if you want to enable interactions with the WebView, such as clicking on buttons or typing in text fields. Set it to false to make your WebView into a view-only element on the screen, such as a HUD.
If set to true:
- Mouse input will be captured by the WebView and will not be passed to the game.
- Keyboard input will be captured by the WebView and will still be passed to the game, but not JC4MP UI (such as chat)
If set to false:
- Mouse input will be passed to the game.
- Keyboard input will be passed to the game.
- Webview will ignore all mouse and keyboard input but will still be fully visible. (non-interactive, but visible)
If you want to disable keyboard inputs in the game, use Input.SetEnabled(false)
instead. This will compeltely disable all game inputs, including both mouse and keyboard.
Parameters:
id
(string): The WebView IDenabled
(boolean):true
to enable input,false
to disable
Returns:
boolean
:true
if input state updated successfully,false
otherwise
Example:
-- Disable input for background WebViews
WebView.SetInputEnabled("background_video", false)
-- Enable input for interactive elements
WebView.SetInputEnabled("control_panel", true)
-- Toggle input based on game state
local function updateWebViewInput(game_paused)
local interactive_webviews = {"chat", "inventory", "map"}
for _, id in ipairs(interactive_webviews) do
WebView.SetInputEnabled(id, game_paused)
end
end
WebView.ExecuteScript(id: string, script: string): boolean
Executes JavaScript code within the specified WebView's context. This allows you to dynamically manipulate the DOM, update content, call JavaScript functions, and interact with the web page from Lua. Keep in mind that this isn't usually necessary to use if you leverage the messaging system to communicate with your webview, but it can be useful for simple tasks.
Parameters:
id
(string): The WebView IDscript
(string): JavaScript code to execute
Returns:
boolean
:true
if script executed successfully,false
otherwise
Example:
-- Change text content of an element
WebView.ExecuteScript("my_ui", "document.getElementById('player-name').textContent = 'Rico';")
-- Update multiple elements
local player_data = {
name = "PlayerName",
health = 100,
score = 1500
}
local script = string.format([[
document.getElementById('player-name').textContent = '%s';
document.getElementById('health-bar').style.width = '%d%%';
document.getElementById('score-display').textContent = '%d';
]], player_data.name, player_data.health, player_data.score)
WebView.ExecuteScript("hud", script)
-- Call JavaScript functions defined in your HTML
WebView.ExecuteScript("my_ui", "updatePlayerStats(" .. player_data.health .. ", " .. player_data.score .. ");")
-- Show/hide elements dynamically
WebView.ExecuteScript("my_ui", "document.getElementById('loading-screen').style.display = 'none';")
WebView.ExecuteScript("my_ui", "document.getElementById('game-ui').style.display = 'block';")
-- Add CSS classes for styling
WebView.ExecuteScript("my_ui", "document.body.classList.add('in-game');")
-- Update form values
WebView.ExecuteScript("settings_panel", [[
document.getElementById('volume-slider').value = 75;
document.getElementById('graphics-quality').selectedIndex = 2;
]])
-- Inject complex JavaScript functionality
local complex_script = [[
function updateNotification(message, type) {
const notification = document.createElement('div');
notification.className = 'notification ' + type;
notification.textContent = message;
document.getElementById('notifications').appendChild(notification);
setTimeout(() => {
notification.remove();
}, 3000);
}
updateNotification('Player joined the server', 'info');
]]
WebView.ExecuteScript("game_ui", complex_script)
WebView.GetInfo(id: string): table
Retrieves information about a WebView instance.
Parameters:
id
(string): The WebView ID
Returns:
table
: WebView information object, or empty table if not found
Information Object Properties:
url
(string): Current URLposition
(vec2): Current position withx
andy
size
(vec2): Current size withx
andy
visible
(boolean): Current visibility stateinput_enabled
(boolean): Current input statez_order
(number): Current z-order value
Example:
local info = WebView.GetInfo("my_ui")
if info and info.url then
print("WebView Info:")
print(" URL: " .. info.url)
print(" Position: " .. info.position.x .. ", " .. info.position.y)
print(" Size: " .. info.size.x .. "x" .. info.size.y)
print(" Visible: " .. tostring(info.visible))
print(" Input Enabled: " .. tostring(info.input_enabled))
print(" Z-Order: " .. info.z_order)
else
print("WebView not found")
end
-- Save and restore WebView state
local function saveWebViewState(id)
local info = WebView.GetInfo(id)
if info then
-- Save to file or variable
saved_states[id] = info
end
end
local function restoreWebViewState(id)
local state = saved_states[id]
if state then
WebView.SetPosition(id, state.position)
WebView.SetSize(id, state.size)
WebView.SetVisible(id, state.visible)
WebView.SetInputEnabled(id, state.input_enabled)
if state.url ~= "" then
WebView.LoadUrl(id, state.url)
end
end
end