-
Notifications
You must be signed in to change notification settings - Fork 1
/
init.lua
240 lines (226 loc) · 7.79 KB
/
init.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
--[[
Minetest Chat Translator
Version: 1
License: AGPLv3
LibreTranslate
Free and Open Source Machine Translation API
License: AGPLv3
]]--
local languages = {}
local http = minetest.request_http_api()
--returns an error if the mod is not trusted
minetest.register_on_prejoinplayer(function(pname)
if not http then
return "\n\nChat Translator needs to be added to your trusted mods list.\n" ..
"To do so, click on the 'Settings' tab in the main menu.\n" ..
"Click the 'All Settings' button and in the search bar, enter 'trusted'.\n" ..
"Click the 'Edit' button and add 'chat_translator' to the list."
end
http.fetch({ url = "http://localhost:5000/languages" }, get_languages)
end)
--intercepts chat messages and sends an http request to libretranslate
minetest.register_on_chat_message(function(name, message)
if http then
local sender_language = minetest.get_player_information(name).lang_code
if sender_language == "" then
sender_language = "en"
end
if not language_available(sender_language) then
return false
else
send_to_all(message, name, sender_language, false)
end
return true
end
end)
--overrides the builtin direct message function
minetest.override_chatcommand("msg", {
params = "",
description = "",
privs = { shout = true },
func = function(name, param)
local receiver_name, message = param:match("^(%S+)%s(.+)$")
if not receiver_name then
send_server_msg("Invalid usage. Try " .. "[/msg name message]", name)
return true
end
if not minetest.get_player_by_name(receiver_name) then
send_server_msg("The recipient is not online.", name)
return true
end
send_dm(message, name, receiver_name)
send_server_msg("Message sent.", name)
return true
end,
})
--overrides the builtin emote function
minetest.override_chatcommand("me", {
params = "",
description = "",
privs = { shout = true },
func = function(name, param)
if param ~= "" then
local sender_language = minetest.get_player_information(name).lang_code
if sender_language == "" then
sender_language = "en"
end
if not language_available(sender_language) then
minetest.chat_send_all("* " .. name .. " " .. message)
else
send_to_all(param, name, sender_language, true)
end
return true
else
send_server_msg("Invalid usage. Try [/me does something]", name)
return true
end
end,
})
--sends a translated message from the server to a player
function send_server_msg(message, receiver_name)
local receiver_language = minetest.get_player_information(receiver_name).lang_code
local params = {
message = message,
sender_name = "Minetest",
receiver_name = receiver_name,
sender_language = "en",
receiver_language = receiver_language,
prefix = "<",
suffix = "> "
}
if language_available(receiver_language) == false or receiver_language == "en" then
minetest.chat_send_player(
params.receiver_name,
params.prefix ..
params.sender_name ..
params.suffix ..
message
)
else
send_message(params)
end
end
--translates and sends a direct message
function send_dm(message, sender_name, receiver_name)
local sender_language = minetest.get_player_information(sender_name).lang_code
local receiver_language = minetest.get_player_information(receiver_name).lang_code
if sender_language == "" then sender_language = "en" end
if receiver_language == "" or language_available(receiver_language) == false then
receiver_language = "en"
end
local params = {
message = message,
sender_name = sender_name,
receiver_name = receiver_name,
sender_language = sender_language,
receiver_language = receiver_language,
prefix = "<",
suffix = "> ► <" .. receiver_name .. "> "
}
if language_available(sender_language) == false or sender_language == receiver_language then
minetest.chat_send_player(
params.receiver_name,
params.prefix ..
params.sender_name ..
params.suffix ..
message
)
else
send_message(params)
end
end
--translates and delivers the message to all players
function send_to_all(message, sender_name, sender_language, emote)
local prefix = emote and "* " or "<"
local suffix = emote and " " or "> "
for _,player in pairs(minetest.get_connected_players()) do
local receiver_name = player:get_player_name()
local receiver_language = minetest.get_player_information(receiver_name).lang_code
if sender_language == receiver_language then
minetest.chat_send_player(receiver_name, prefix .. sender_name .. suffix .. message)
else
if receiver_language == "" or language_available(receiver_language) == false then
receiver_language = "en"
end
local params = {
message = message,
sender_name = sender_name,
receiver_name = receiver_name,
sender_language = sender_language,
receiver_language = receiver_language,
prefix = prefix,
suffix = suffix
}
send_message(params)
end
end
end
--translates the message and sends it to the receiver
function send_message(params)
local url = 'http://localhost:5000/translate'
local post_data = {
q = params.message,
source = params.sender_language,
target = params.receiver_language
}
local headers = {
["Accept"] = "accept: application/json",
["Content-Type"] = "application/x-www-form-urlencoded"
}
local request = { url = url, post_data = post_data, extra_headers = headers }
http.fetch(request, function(response)
if not response.completed then
return
end
local msg = params.message
local data_json = minetest.parse_json(response.data)
if data_json then
msg = data_json.translatedText
else
handle_failure("Failed to translate a message.")
end
minetest.chat_send_player(
params.receiver_name,
params.prefix ..
params.sender_name ..
params.suffix ..
msg
)
end)
end
--gets all language codes from libretranslate
function get_languages(response)
if not response.completed then
return
end
local data_json = minetest.parse_json(response.data)
if data_json then
languages = {}
for _,language in pairs(data_json) do
table.insert(languages, language.code)
end
else
handle_failure("Failed to retrieve list of languages from libretranslate.")
end
end
--handles failed http requests
function handle_failure(message)
minetest.log("error", "Chat Translator: " .. message)
minetest.log("error", "Please ensure libretranslate is available at http://localhost:5000/translate")
end
--checks if libretranslate supports the language
function language_available(language)
if languages == {} then
http.fetch({ url = "http://localhost:5000/languages" }, get_languages)
end
if contains_value(languages,language) then
return true
end
return false
end
--returns true if the table contains the given value
function contains_value(table, value)
for k, v in pairs(table) do
if v == value then return true end
end
end