104 lines
2.6 KiB
Lua
104 lines
2.6 KiB
Lua
---@class RuntimeI18n
|
|
local i18n = {}
|
|
|
|
local default_locale = "zh-Hans"
|
|
local current_locale = default_locale
|
|
|
|
local messages = {
|
|
["zh-Hans"] = {
|
|
title = "Lua 飞行棋",
|
|
roll_button = "掷骰子",
|
|
dice_empty = "骰子: -",
|
|
dice_value = "骰子: {value}",
|
|
current_player = "当前玩家: {player}",
|
|
["player.red"] = "红方",
|
|
["player.blue"] = "蓝方",
|
|
["toast.move_first"] = "请先移动棋子",
|
|
["toast.no_movable_piece"] = "无可移动棋子",
|
|
["toast.invalid_piece"] = "该棋子不能移动"
|
|
},
|
|
en = {
|
|
title = "Lua Ludo",
|
|
roll_button = "Roll",
|
|
dice_empty = "Dice: -",
|
|
dice_value = "Dice: {value}",
|
|
current_player = "Current player: {player}",
|
|
["player.red"] = "Red",
|
|
["player.blue"] = "Blue",
|
|
["toast.move_first"] = "Move a piece first",
|
|
["toast.no_movable_piece"] = "No movable pieces",
|
|
["toast.invalid_piece"] = "This piece cannot move"
|
|
}
|
|
}
|
|
|
|
---@param locale? string
|
|
---@return string
|
|
local function normalize_locale(locale)
|
|
if type(locale) ~= "string" or locale == "" then
|
|
return default_locale
|
|
end
|
|
locale = string.gsub(locale, "_", "-")
|
|
if messages[locale] ~= nil then
|
|
return locale
|
|
end
|
|
|
|
local language = string.match(locale, "^([A-Za-z]+)")
|
|
if language ~= nil and messages[language] ~= nil then
|
|
return language
|
|
end
|
|
return default_locale
|
|
end
|
|
|
|
---@param value string
|
|
---@return string
|
|
local function escape_pattern(value)
|
|
return string.gsub(value, "([%(%)%.%%%+%-%*%?%[%]%^%$])", "%%%1")
|
|
end
|
|
|
|
---@param template string
|
|
---@param vars? table<string, string|number>
|
|
---@return string
|
|
local function interpolate(template, vars)
|
|
if vars == nil then
|
|
return template
|
|
end
|
|
|
|
local result = template
|
|
for key, value in pairs(vars) do
|
|
result = string.gsub(result, "{" .. escape_pattern(key) .. "}", tostring(value))
|
|
end
|
|
return result
|
|
end
|
|
|
|
---@param ctx? RuntimeContext
|
|
function i18n.configure(ctx)
|
|
local locale = nil
|
|
if ctx ~= nil and ctx.locale ~= nil then
|
|
locale = ctx.locale.resolved or ctx.locale.requested or ctx.locale.default
|
|
end
|
|
current_locale = normalize_locale(locale)
|
|
end
|
|
|
|
---@return string
|
|
function i18n.locale()
|
|
return current_locale
|
|
end
|
|
|
|
---@param key string
|
|
---@param vars? table<string, string|number>
|
|
---@return string
|
|
function i18n.t(key, vars)
|
|
local bundle = messages[current_locale] or messages[default_locale]
|
|
local fallback = messages[default_locale]
|
|
local value = bundle[key] or fallback[key] or key
|
|
return interpolate(value, vars)
|
|
end
|
|
|
|
---@param color PlayerColor
|
|
---@return string
|
|
function i18n.player(color)
|
|
return i18n.t("player." .. color)
|
|
end
|
|
|
|
return i18n
|