1
0
mirror of https://github.com/metrostroi-repo/MetrostroiAddon.git synced 2026-05-02 00:42:29 +00:00
Files
MetrostroiAddon/lua/metrostroi/cl_language.lua
2021-01-02 15:32:05 +03:00

457 lines
19 KiB
Lua

---[=[
local function removeSpaces(str)
return str:gsub("#[.*#]",""):gsub("([^\\#])#.*$","%1"):gsub("\\#","#"):gsub("^[ \t]+",""):gsub("[ \t]+$","")
end
--local LangTable = {}
--]=]
Metrostroi.Languages = Metrostroi.Languages or {}
Metrostroi.ChoosedLang = GetConVarString("metrostroi_language")
function Metrostroi.GetPhrase(phrase)
if Metrostroi.CurrentLanguageTable and not Metrostroi.CurrentLanguageTable[phrase] then
MsgC(Color(255,0,0),"No phrase:",Color(0,255,0),phrase,"\n")
end
return
Metrostroi.CurrentLanguageTable and Metrostroi.CurrentLanguageTable[phrase] or phrase
end
function Metrostroi.HasPhrase(phrase)
if Metrostroi.CurrentLanguageTable and not Metrostroi.CurrentLanguageTable[phrase] then
MsgC(Color(255,0,0),"No phrase:",Color(0,255,0),phrase,"\n")
end
return
Metrostroi.CurrentLanguageTable and Metrostroi.CurrentLanguageTable[phrase]
end
if not file.Exists("metrostroi_data","DATA") then file.CreateDir("metrostroi_data") end
if not file.Exists("metrostroi_data/languages","DATA") then file.CreateDir("metrostroi_data/languages") end
local function debugmsg(...)
if GetConVarNumber("metrostroi_drawdebug") > 0 then
MsgC(...)
MsgC("\n")
end
end
local function errmsg(...)
MsgC(...)
ErrorNoHalt("\n")
end
function Metrostroi.LoadLanguage(lang,force)
if not Metrostroi.Languages[lang] then return end
local ENTl = list.GetForEdit("SpawnableEntities")
local SWEPl = list.GetForEdit("Weapon")
Metrostroi.CurrentLanguageTable = Metrostroi.Languages[lang] or {}
for id,phrase in pairs(Metrostroi.CurrentLanguageTable) do
if id == "lang" then continue end
if id:sub(1,9) == "Entities." then
local tbl = string.Explode(".",id:sub(10,-1))
if tbl[1] == "Category" then
local cat = tbl[2]
debugmsg(Color(255,0,255),"Add language ",lang," phrase:\t",Color(0,255,0),id,"=",phrase,Color(255,0,255)," for class ",Color(0,255,0),class)
continue
end
local class = tbl[1]
local ENT = scripted_ents.GetStored(class)
if not ENT then
errmsg(Color(255,0,0),"No entity ",Color(255,0,255),class,Color(255,0,0)," for phrase:",Color(0,255,0),id)
continue
else
ENT = ENT.t
end
if tbl[2] == "Name" then
if not ENTl[class] then
if ENT.Spawner then
ENT.Spawner.Name = phrase
else
errmsg(Color(255,0,0),"No spawnmenu for entity ",Color(255,0,255),class,Color(255,0,0)," for phrase:",Color(0,255,0),id)
end
continue
end
ENTl[class].PrintName = phrase
debugmsg(Color(255,0,255),"Add language ",lang," phrase:\t",Color(0,255,0),id,"=",phrase,Color(255,0,255)," for class ",Color(0,255,0),class)
elseif tbl[2] == "Buttons" then
if not ENT.ButtonMap[tbl[3]] then
ErrorNoHalt("Check translation for "..id.."! Can't find panel named "..tbl[3].."\n")
continue
end
if not ENT.ButtonMap[tbl[3]].buttons then
ErrorNoHalt("Check translation for "..id.."! Can't find buttons in panel named "..tbl[3].."\n")
end
local button
for k,v in pairs(ENT.ButtonMap[tbl[3]].buttons) do
if v.ID == tbl[4] then
v.tooltip = phrase
button = v
break
end
end
if not button then
ErrorNoHalt("Check translation for "..id.."! Can't find button named "..tbl[4].." in panel "..tbl[3].."\n")
end
elseif tbl[2] == "Spawner" then
if not ENT.Spawner then
errmsg(Color(255,0,0),"No spawner table for entity ",Color(255,0,255),class,Color(255,0,0)," for phrase:",Color(0,255,0),id)
continue
end
for i,v in pairs(ENT.Spawner) do
if type(v) == "function" then continue end
if v[1] == tbl[3] then
if tbl[4] == "Name" then
v[2] = phrase
elseif v[3] == "List" and v[4] then
local numb = tonumber(tbl[4])
if numb and type(v[4]) ~= "function" and v[4][numb] then
v[4][numb] = phrase
else
errmsg(Color(255,0,0),"No spawner list table for entity ",Color(255,0,255),class,Color(255,0,0)," for phrase:",Color(0,255,0),id)
end
else
errmsg(Color(255,0,0),"Spawner translate error for entity ",Color(255,0,255),class,Color(255,0,0)," for phrase:",Color(0,255,0),id)
end
end
end
end
elseif id:sub(1,8) == "Weapons." then
local tbl = string.Explode(".",id:sub(9,-1))
local class = tbl[1]
local SWEP = weapons.GetStored(class)
if not SWEP then
errmsg(Color(255,0,0),"No weapon ",Color(255,0,255),class,Color(255,0,0)," for phrase:",Color(0,255,0),id)
continue
end
if tbl[2] == "Name" then
SWEP.PrintName = phrase
SWEPl[class].PrintName = phrase
elseif tbl[2] == "Purpose" then
SWEP.Purpose = phrase
--SWEPl[class].Purpose = phrase
elseif tbl[2] == "Instructions" then
SWEP.Instructions = phrase
--SWEPl[class].Instructions = phrase
end
debugmsg(Color(255,0,255),"Add language ",lang," phrase:\t",Color(0,255,0),id,"=",phrase,Color(255,0,255)," for class ",Color(0,255,0),class)
else
debugmsg(Color(255,0,255),"Add language ",lang," phrase:\t",Color(0,255,0),id,Color(255,0,255),"=",Color(0,255,0),phrase)
end
end
if force or GetConVarNumber("metrostroi_language_softreload")~=1 then
RunConsoleCommand("spawnmenu_reload")
hook.Run( "GameContentChanged" )
end
end
cvars.AddChangeCallback("metrostroi_language", function(cvar, old, value)
Metrostroi.LoadLanguage(value,true)
end, "language")
local function parseLangFile(filename,txt)
local currlang
local i = 0
local ignoring = false
for line in txt:gmatch("[^\n\r]+") do
i = i + 1
if line:find("%][^\\]?#") then ignoring = false continue end
if ignoring then continue end
if line:find("[^\\]?#%[") then ignoring = true end
local lang,founded = removeSpaces(line):gsub("^%[([%w]+)%]$","%1")
if founded > 0 then
print("Selected lang",lang)
currlang = lang
Metrostroi.Languages[lang] = Metrostroi.Languages[lang] or {}
continue
end
local founded = line:gsub("^%[([%w]+)%]$","%1")
local k,v = line:match("([^=]+)=([^=]+)")
if k and v then
if not currlang then
ErrorNoHalt("Metrostroi: Language not selected\n")
break
end
Metrostroi.Languages[currlang][removeSpaces(k)] = removeSpaces(v):gsub("\\n","\n"):gsub("\\t","\t")
continue
end
if #line > 0 and line[1] ~="#" then
ErrorNoHalt(Format("Metrostroi: Language parse error in line %d: %s [%s]\n",i,line,filename))
break
end
end
end
local function exportLangJSON(filename,txt)
local langs = {}
local currlang
local i = 0
local ignoring = false
for line in txt:gmatch("[^\n\r]+") do
i = i + 1
if line:find("%][^\\]?#") then ignoring = false continue end
if ignoring then continue end
if line:find("[^\\]?#%[") then ignoring = true end
local lang,founded = removeSpaces(line):gsub("^%[([%w]+)%]$","%1")
if founded > 0 then
print("Selected lang",lang)
currlang = lang
if not langs[currlang] then langs[currlang] = "{" end
continue
end
local founded = line:gsub("^%[([%w]+)%]$","%1")
local k,v = line:match("([^=]+)=([^=]+)")
if k and v then
if not currlang then
ErrorNoHalt("Metrostroi: Language not selected\n")
break
end
local str,addstr = langs[currlang],Format('\n\t"%s": "%s"',removeSpaces(k),removeSpaces(string.JavascriptSafe(v):gsub("\\\\([tn])","\\%1")))
if langs[currlang] == "{" then
langs[currlang] = str..addstr
else
langs[currlang] = str..","..addstr
end
continue
end
if #line > 0 and line[1] ~="#" then
ErrorNoHalt(Format("Metrostroi: Language parse error in line %d: %s [%s]\n",i,line,filename))
break
end
end
local str = ""
for k,v in pairs(langs) do
str = str.."["..k.."]\n"..v.."\n}"
end
SetClipboardText(str)
end
concommand.Add("metrostroi_language_exportjson", function(_, _, args)
if not args[1] then return end
print("metrostroi_data/languages/"..args[1]..".lua")
exportLangJSON(args[1],include("metrostroi_data/languages/"..args[1]..".lua"))
end)
local function reloadLang()
if not GAMEMODE or not Metrostroi then return end
Metrostroi.Languages = {en = {}}
--Load builtin default languages
--[[ if Metrostroi.BuiltinLanguages then
for k, lang in pairs(Metrostroi.BuiltinLanguages) do
local JSON = util.JSONToTable(lang)
if not JSON then ErrorNoHalt("Metrostroi: Error loading default language file: ",k,"\n") continue end
if not Metrostroi.Languages[JSON.Lang] then Metrostroi.Languages[JSON.Lang] = {} end
for id,phrase in pairs(JSON) do
Metrostroi.Languages[JSON.Lang][id] = phrase
end
end
end--]]
--Load builtin lua languages
for k, filename in pairs(file.Find("metrostroi_data/languages/*_base.lua","LUA")) do
local lang = include("metrostroi_data/languages/"..filename)
if not lang then continue end
parseLangFile(filename,lang)
end
--Load client languages
for k, filename in pairs(file.Find( "metrostroi_data/languages/*_base.txt", "DATA")) do
local lang = file.Read("metrostroi_data/languages/"..filename)
parseLangFile(filename,lang)
end
--Load builtin lua languages
for k, filename in pairs(file.Find("metrostroi_data/languages/*.lua","LUA")) do
if filename:find("_base.lua") then continue end
local lang = include("metrostroi_data/languages/"..filename)
if not lang then continue end
parseLangFile(filename,lang)
end
--Load client languages
for k, filename in pairs(file.Find( "metrostroi_data/languages/*.txt", "DATA")) do
if filename:find("_base.txt") then continue end
local lang = file.Read("metrostroi_data/languages/"..filename)
parseLangFile(filename,lang)
end
--shitcode yay(repace missing phrase with english)
for lang,langtbl in pairs(Metrostroi.Languages) do
if lang == "en" then continue end
for id,phrase in pairs(Metrostroi.Languages.en) do
if not langtbl[id] then
langtbl[id] = phrase
debugmsg(Color(255,0,0),"Founded missing phrase ",Color(255,0,255),id,Color(255,0,0)," in ",lang," translation! Replaced with en.")
end
end
end
for lang,tbl in pairs(Metrostroi.Languages) do
for id,str in pairs(tbl) do
local pos = 1
local iter = 1
repeat
local start_pos,end_pos = str:find("@%[[^]]+%]",pos)
if not start_pos then break end
local repstr = tbl[str:match("@%[([^]]+)%]")]
if not repstr then
pos = end_pos+1
continue
end
str = str:sub(1,start_pos-1)..repstr..str:sub(end_pos+1,-1)
iter = iter + 1
until iter > 1000
if iter > 1 then tbl[id] = str end
end
end
Metrostroi.LoadLanguage(Metrostroi.ChoosedLang)
if not Metrostroi.CurrentLanguageTable then
Metrostroi.ChoosedLang = GetConVarString("gmod_language")
if not Metrostroi.Languages[Metrostroi.ChoosedLang] then Metrostroi.ChoosedLang = "en" end
RunConsoleCommand("metrostroi_language",Metrostroi.ChoosedLang)
end
end
hook.Add("OnGamemodeLoaded","MetrostroiLanguageSystem",reloadLang)
concommand.Add("metrostroi_language_reload",reloadLang)
reloadLang()
concommand.Add("metrostroi_language_checktranslation", function(_, _, args)
if not Metrostroi.CurrentLanguageTable then return end
local str = "[langname]\nlang=Langname\n\n"
for class, t in pairs(scripted_ents.GetList()) do
local ENT = t.t
if ENT.ButtonMap or ENT.Cameras or ENT.Spawner then
str = str.."#"..class.."\n"
end
if ENT.ButtonMap then
str = str.."#Buttons:\n"
for panelname, panel in pairs(ENT.ButtonMap) do
if panel.buttons then
for buttonname, button in pairs(panel.buttons) do
if button.tooltip then
if not button.ID and args[1] then
MsgC(Color(255, 0, 0), ENT.ClassName, " ", (button.tooltip or "nil"):Replace("\n", "\\n"):Replace("\t", "\\t"):Replace("\"", "\\\""), "\n")
elseif button.ID and not args[1] then
local id = Format("Entities.%s.Buttons.%s.%s", class, panelname, button.ID)
--elseif button.ID and args[1] == "all" then
--print(Format("\"Entities.%s.Buttons.%s.%s\": \"%s\",",class,panelname,button.ID,button.tooltip:Replace("\n","\\n"):Replace("\t","\\t"):Replace("\"","\\\"")))
if not Metrostroi.CurrentLanguageTable[id] then
local name = Format("%s = %s\n", id,button.tooltip:JavascriptSafe())
MsgC(Color(255, 0, 0), name)
str = str .. name
end
end
end
end
end
end
end
--Format("Entities.%s.Buttons.%s.%s",class,panelname,button.ID)
if ENT.Cameras then
str = str.."#Cameras:\n"
for i, cam in pairs(ENT.Cameras) do
if not cam[3] or type(cam[3])~="string" then continue end
local id = cam[3]:JavascriptSafe()
if not Metrostroi.CurrentLanguageTable[id] then
MsgC(Color(255, 0, 0), Format("%s = %s\n", id, id))
str = str .. Format("%s = %s\n", id, id)
end
end
end
--end
--for class, t in pairs(scripted_ents.GetList()) do
--local ENT = t.t
if ENT.Spawner then
str = str.."#Spawner:\n"
for i, tbl in ipairs(ENT.Spawner) do
if not args[1] and not Metrostroi.CurrentLanguageTable[Format("Entities.%s.Spawner.%s.Name", class, tbl[1])] and tbl[2] then
local name = tbl[2]
if name:sub(1, 8) == "Spawner." then
name = Metrostroi.GetPhrase(name)
end
name = name:JavascriptSafe()
print(Format("Entities.%s.Spawner.%s.Name = %s", class, tbl[1], name))
str = str .. Format("Entities.%s.Spawner.%s.Name = %s\n", class, tbl[1], name)
end
if tbl[3] == "List" and type(tbl[4])=="table" then
for k, v in ipairs(tbl[4]) do
if type(v) == "string" and not args[1] and not Metrostroi.CurrentLanguageTable[Format("Entities.%s.Spawner.%s.%s", class, tbl[1], k)] then
if v:sub(1, 8) == "Spawner." then
v = Metrostroi.GetPhrase(v)
end
v = v:JavascriptSafe()
print(Format("Entities.%s.Spawner.%s.%s = %s", class, tbl[1], k, v))
str = str .. Format("Entities.%s.Spawner.%s.%s = %s\n", class, tbl[1], k, v)
end
end
end
end
end
end
SetClipboardText(str)
end)
Metrostroi.LanguageCache = Metrostroi.LanguageCache or {}
timer.Simple(0,function()
net.Start("metrostroi_language_sync")
net.SendToServer()
end)
net.Receive("metrostroi_language_sync",function()
print("------RECV------")
local id = net.ReadUInt(32)
local maxf = net.ReadUInt(8)
local currf = net.ReadUInt(8)
local count = net.ReadUInt(8)
local num = net.ReadUInt(8)
print("ID:"..id)
print(Format("Num:%02d/%02d",currf,maxf))
print(Format("count:%02d/%02d",num,count))
Metrostroi.LanguageCache[id] = Metrostroi.LanguageCache[id] or {}
Metrostroi.LanguageCache[id][currf] = Metrostroi.LanguageCache[id][currf] or {}
local size = net.ReadUInt(32)
Metrostroi.LanguageCache[id][currf][num] = net.ReadData(size)
print(Format("Metrostroi.LanguageCache[%d][%d] %s",id,currf,Metrostroi.LanguageCache[id][currf]))
print("Size:"..size)
local done = true
for cf=1,maxf do
if not Metrostroi.LanguageCache[id][cf] then done = false break end
local tdata = Metrostroi.LanguageCache[id][cf]
local pd = true
if tdata and type(tdata) == "table" and true then
for cd=0,#tdata do
if not tdata[cd] then pd = false break end
end
if pd then
print("Done receiving text data")
local data = ""
for i=0,#tdata do
data = data.. tdata[i]
end
Metrostroi.LanguageCache[id][cf] = data
end
end
if not pd then done = false break end
end
if done then
print("Done receiving all lang data")
local langdata = Metrostroi.LanguageCache[id]
Metrostroi.LanguageCache[id] = nil
Metrostroi.BuiltinLanguages = {}
for k,v in pairs(langdata) do Metrostroi.BuiltinLanguages[k] = util.Decompress(v) end
--data = util.Decompress(data)
reloadLang()
end
end)