Merge branch 'bi'

This commit is contained in:
Unknown 2018-03-04 21:50:58 +03:00
commit 13ac23b971
4 changed files with 183 additions and 78 deletions

View file

@ -41,6 +41,16 @@ return {
ru = "Открывает новое окно, в которое в реальном времени выводится игровой лог.\n\n" .. ru = "Открывает новое окно, в которое в реальном времени выводится игровой лог.\n\n" ..
"Чтобы его закрыть, сначала выключите консоль из меню настроек, и потом закройте вручную.", "Чтобы его закрыть, сначала выключите консоль из меню настроек, и потом закройте вручную.",
}, },
show_network_debug_info = {
en = "Log Network Calls",
ru = "Логгирование сетевых вызовов",
},
show_network_debug_info_tooltip = {
en = "Log all the VMF network calls and all the data transfered with them.\n\n" ..
"The method 'info' is used for the logging.",
ru = "Логирование всех сетевых вызовов VMF и передаваемых с ними данных.\n\n" ..
"Для логирования используется метод 'info'.",
},
logging_mode = { logging_mode = {
en = "Logging Settings.", en = "Logging Settings.",
ru = "Настройки логирования", ru = "Настройки логирования",

View file

@ -94,4 +94,24 @@ vmf.mod_disabled_event = function(mod, initial_call)
else else
mod:warning("Attemt to call undefined event 'mod.%s'.", event_name) mod:warning("Attemt to call undefined event 'mod.%s'.", event_name)
end end
end
vmf.mod_user_joined_the_game = function(mod, player)
local event_name = "on_user_joined"
local event = mod[event_name]
if event then
run_event(mod, event_name, event, player)
end
end
vmf.mod_user_left_the_game = function(mod, player)
local event_name = "on_user_left"
local event = mod[event_name]
if event then
run_event(mod, event_name, event, player)
end
end end

View file

@ -1,5 +1,3 @@
-- @TODO: when recieving maps of other users, check for consistency
-- @TODO: don't call during suspension
local vmf = get_mod("VMF") local vmf = get_mod("VMF")
local _VMF_USERS = {} local _VMF_USERS = {}
@ -13,17 +11,31 @@ local _SHARED_RPCS_MAP = ""
local _NETWORK_MODULE_IS_INITIALIZED = false local _NETWORK_MODULE_IS_INITIALIZED = false
-- converting -- ####################################################################################################################
-- ##### Local functions ##############################################################################################
-- ####################################################################################################################
local function convert_names_to_numbers(user_rpcs_dictionary, mod_name, rpc_name) local function is_rpc_registered(mod_name, rpc_name)
local mod_number = user_rpcs_dictionary[1][mod_name] local success = pcall(function() return _RPC_CALLBACKS[mod_name][rpc_name] end)
if mod_number then return success
end
local rpc_number = user_rpcs_dictionary[2][mod_number][rpc_name] -- CONVERTING
if rpc_number then
return mod_number, rpc_number local function convert_names_to_numbers(peer_id, mod_name, rpc_name)
local user_rpcs_dictionary = _VMF_USERS[peer_id]
if user_rpcs_dictionary then
local mod_number = user_rpcs_dictionary[1][mod_name]
if mod_number then
local rpc_number = user_rpcs_dictionary[2][mod_number][rpc_name]
if rpc_number then
return mod_number, rpc_number
end
end end
end end
return nil return nil
@ -44,7 +56,7 @@ local function convert_numbers_to_names(mod_number, rpc_number)
return nil return nil
end end
-- serialization -- SERIALIZATION
local function serialize_data(...) local function serialize_data(...)
@ -66,52 +78,86 @@ local function deserialize_data(data)
return unpack(data, 1, args_number) return unpack(data, 1, args_number)
end end
-- rpcs -- DEBUG
local function network_debug(rpc_type, action_type, peer_id, mod_name, rpc_name, data)
if vmf.network_debug then
local debug_message = nil
if action_type == "local" then
debug_message = "[NETWORK][LOCAL]"
else
debug_message = "[NETWORK][" .. peer_id .. " (" .. tostring(Managers.player:player_from_peer_id(peer_id)) .. ")]" .. (action_type == "sent" and "<-" or "->")
end
if rpc_type == "ping" then
debug_message = debug_message .. "[PING]"
elseif rpc_type == "pong" then
debug_message = debug_message .. "[PONG]"
elseif rpc_type == "data" then
debug_message = debug_message .. "[DATA][" .. mod_name .. "][" .. rpc_name .. "]: "
if type(data) == "string" then
debug_message = debug_message .. data
else
local success, serialized_data = pcall(serialize_data, unpack(data))
if success then
debug_message = debug_message .. serialized_data
end
end
end
vmf:info(debug_message)
end
end
-- NETWORK
local function send_rpc_vmf_ping(peer_id) local function send_rpc_vmf_ping(peer_id)
network_debug("ping", "sent", peer_id)
RPC.rpc_chat_message(peer_id, 3, Network.peer_id(), "", "", false, true, false) RPC.rpc_chat_message(peer_id, 3, Network.peer_id(), "", "", false, true, false)
vmf:info("[NETWORK][SENT PING] %s", peer_id) -- @DEBUG:
end end
local function send_rpc_vmf_pong(peer_id) local function send_rpc_vmf_pong(peer_id)
network_debug("pong", "sent", peer_id)
RPC.rpc_chat_message(peer_id, 4, Network.peer_id(), _SHARED_MODS_MAP, _SHARED_RPCS_MAP, false, true, false) RPC.rpc_chat_message(peer_id, 4, Network.peer_id(), _SHARED_MODS_MAP, _SHARED_RPCS_MAP, false, true, false)
vmf:info("[NETWORK][SENT PONG] %s", peer_id) -- @DEBUG:
end end
local function send_rpc_vmf_data(peer_id, mod_number, rpc_number, ...) local function send_rpc_vmf_data(peer_id, mod_name, rpc_name, ...)
local rpc_info = cjson.encode({mod_number, rpc_number}) local mod_number, rpc_number = convert_names_to_numbers(peer_id, mod_name, rpc_name)
local success, data = pcall(serialize_data, ...) if mod_number then
if success then
RPC.rpc_chat_message(peer_id, 5, Network.peer_id(), rpc_info, data, false, true, false) local rpc_info = cjson.encode({mod_number, rpc_number})
vmf:info("[NETWORK][SENT RPC] '%s' [%s]: %s", _VMF_USERS[peer_id][mod_number][rpc_number], peer_id, data) -- @DEBUG: local success, data = pcall(serialize_data, ...)
if success then
network_debug("data", "sent", peer_id, mod_name, rpc_name, data)
RPC.rpc_chat_message(peer_id, 5, Network.peer_id(), rpc_info, data, false, true, false)
end
end end
end end
local function send_rpc_vmf_data_local(mod_name, rpc_name, ...) local function send_rpc_vmf_data_local(mod_name, rpc_name, ...)
local success, error_message = pcall(_RPC_CALLBACKS[mod_name][rpc_name], Network.peer_id(), ...) if get_mod(mod_name):is_enabled() then
network_debug("data", "local", nil, mod_name, rpc_name, {...})
if not success then local success, error_message = pcall(_RPC_CALLBACKS[mod_name][rpc_name], Network.peer_id(), ...)
get_mod(mod_name):error("(local rpc) in rpc '%s': %s", rpc_name, error_message) if not success then
else get_mod(mod_name):error("(local rpc) in rpc '%s': %s", tostring(rpc_name), tostring(error_message))
local success, data = pcall(serialize_data, ...) -- @DEBUG: end
if success then -- @DEBUG:
vmf:info("[NETWORK][LOCAL RPC] '%s': %s", rpc_name, data) -- @DEBUG:
end -- @DEBUG:
end end
end end
local function is_rpc_registered(mod_name, rpc_name)
local success = pcall(function() return _RPC_CALLBACKS[mod_name][rpc_name] end)
return success
end
-- #################################################################################################################### -- ####################################################################################################################
-- ##### VMFMod ####################################################################################################### -- ##### VMFMod #######################################################################################################
-- #################################################################################################################### -- ####################################################################################################################
@ -149,26 +195,16 @@ VMFMod.network_send = function (self, rpc_name, recipient, ...)
if recipient == "all" then if recipient == "all" then
for peer_id, user_rpcs_dictionary in pairs(_VMF_USERS) do for peer_id, _ in pairs(_VMF_USERS) do
send_rpc_vmf_data(peer_id, self:get_name(), rpc_name, ...)
local mod_number, rpc_number = convert_names_to_numbers(user_rpcs_dictionary, self:get_name(), rpc_name)
if mod_number then
send_rpc_vmf_data(peer_id, mod_number, rpc_number, ...)
end
end end
send_rpc_vmf_data_local(self:get_name(), rpc_name, ...) send_rpc_vmf_data_local(self:get_name(), rpc_name, ...)
elseif recipient == "others" then elseif recipient == "others" then
for peer_id, user_rpcs_dictionary in pairs(_VMF_USERS) do for peer_id, _ in pairs(_VMF_USERS) do
send_rpc_vmf_data(peer_id, self:get_name(), rpc_name, ...)
local mod_number, rpc_number = convert_names_to_numbers(user_rpcs_dictionary, self:get_name(), rpc_name)
if mod_number then
send_rpc_vmf_data(peer_id, mod_number, rpc_number, ...)
end
end end
elseif recipient == "local" or recipient == Network.peer_id() then elseif recipient == "local" or recipient == Network.peer_id() then
@ -177,15 +213,7 @@ VMFMod.network_send = function (self, rpc_name, recipient, ...)
else -- recipient == peer_id else -- recipient == peer_id
local user_rpcs_dictionary = _VMF_USERS[recipient] send_rpc_vmf_data(recipient, self:get_name(), rpc_name, ...)
if user_rpcs_dictionary then
local mod_number, rpc_number = convert_names_to_numbers(user_rpcs_dictionary, self:get_name(), rpc_name)
if mod_number then
send_rpc_vmf_data(recipient, mod_number, rpc_number, ...)
end
end
end end
end end
@ -195,41 +223,61 @@ end
vmf:hook("ChatManager.rpc_chat_message", function(func, self, sender, channel_id, message_sender, message, localization_param, ...) vmf:hook("ChatManager.rpc_chat_message", function(func, self, sender, channel_id, message_sender, message, localization_param, ...)
if not _NETWORK_MODULE_IS_INITIALIZED then
return
end
if channel_id == 1 then if channel_id == 1 then
func(self, sender, channel_id, message_sender, message, localization_param, ...) func(self, sender, channel_id, message_sender, message, localization_param, ...)
else else
if not _NETWORK_MODULE_IS_INITIALIZED then
return
end
if channel_id == 3 then -- rpc_vmf_request if channel_id == 3 then -- rpc_vmf_request
network_debug("ping", "received", sender)
send_rpc_vmf_pong(sender) send_rpc_vmf_pong(sender)
vmf:info("[NETWORK][RECIEVED PING] %s", sender) -- @DEBUG: elseif channel_id == 4 then -- rpc_vmf_responce (@TODO: maybe I should protect it from sending by the player who's not in the game?)
elseif channel_id == 4 then -- rpc_vmf_responce network_debug("pong", "received", sender)
if vmf.network_debug then
vmf:info("[RECEIVED MODS TABLE]: " .. message)
vmf:info("[RECEIVED RPCS TABLE]: " .. localization_param)
end
_VMF_USERS[sender] = {} pcall(function()
_VMF_USERS[sender][1] = cjson.decode(message) -- mods local user_rpcs_dictionary = {}
_VMF_USERS[sender][2] = cjson.decode(localization_param) -- rpcs
vmf:info("[NETWORK][RECIEVED PONG] %s", sender) -- @DEBUG: user_rpcs_dictionary[1] = cjson.decode(message) -- mods
vmf:info("[RECEIVED MODS TABLE]: " .. message) -- @DEBUG: user_rpcs_dictionary[2] = cjson.decode(localization_param) -- rpcs
vmf:info("[RECEIVED RPCS TABLE]: " .. localization_param) -- @DEBUG:
vmf:info("Added %s to the VMF users list.", sender) _VMF_USERS[sender] = user_rpcs_dictionary
vmf:info("Added %s to the VMF users list.", sender)
-- event
local player = Managers.player:player_from_peer_id(sender)
if player then
for mod_name, _ in pairs(user_rpcs_dictionary[1]) do
local mod = get_mod(mod_name)
if mod then
vmf.mod_user_joined_the_game(mod, player)
end
end
end
end)
elseif channel_id == 5 then elseif channel_id == 5 then
local mod_number, rpc_number = unpack(cjson.decode(message)) local mod_number, rpc_number = unpack(cjson.decode(message))
local mod_name, rpc_name = convert_numbers_to_names(mod_number, rpc_number) local mod_name, rpc_name = convert_numbers_to_names(mod_number, rpc_number)
if mod_name then if mod_name and get_mod(mod_name):is_enabled() then
vmf:info("[NETWORK][RECEIVED RPC] '%s.%s' [%s]: %s", mod_name, rpc_name, sender, message) -- @DEBUG: network_debug("data", "received", sender, mod_name, rpc_name, localization_param)
-- can be error in both callback_function() and deserialize_data() -- can be error in both callback_function() and deserialize_data()
local success, error_message = pcall(function() _RPC_CALLBACKS[mod_name][rpc_name](sender, deserialize_data(localization_param)) end) local success, error_message = pcall(function() _RPC_CALLBACKS[mod_name][rpc_name](sender, deserialize_data(localization_param)) end)
@ -258,8 +306,17 @@ vmf:hook("PlayerManager.remove_player", function (func, self, peer_id, local_pla
for _, player in pairs(Managers.player:human_players()) do for _, player in pairs(Managers.player:human_players()) do
if player.peer_id == peer_id then if player.peer_id == peer_id then
_VMF_USERS[peer_id] = nil
vmf:info("Removed %s from the VMF users list.", peer_id) vmf:info("Removed %s from the VMF users list.", peer_id)
-- event
for mod_name, _ in pairs(_VMF_USERS[peer_id][1]) do
local mod = get_mod(mod_name)
if mod then
vmf.mod_user_left_the_game(mod, player)
end
end
_VMF_USERS[peer_id] = nil
break break
end end
end end
@ -272,6 +329,8 @@ end)
-- ##### VMF internal functions and variables ######################################################################### -- ##### VMF internal functions and variables #########################################################################
-- #################################################################################################################### -- ####################################################################################################################
vmf.network_debug = vmf:get("developer_mode") and vmf:get("show_network_debug_info")
vmf.create_network_dictionary = function() vmf.create_network_dictionary = function()
_SHARED_MODS_MAP = {} _SHARED_MODS_MAP = {}
@ -306,11 +365,13 @@ end
vmf.ping_vmf_users = function() vmf.ping_vmf_users = function()
for _, player in pairs(Managers.player:human_players()) do if Managers.player then
if player.peer_id ~= Network.peer_id() then for _, player in pairs(Managers.player:human_players()) do
if player.peer_id ~= Network.peer_id() then
send_rpc_vmf_ping(player.peer_id) send_rpc_vmf_ping(player.peer_id)
send_rpc_vmf_pong(player.peer_id) send_rpc_vmf_pong(player.peer_id)
end
end end
end end
end end

View file

@ -42,6 +42,14 @@ local options_widgets = {
vmf:localize("show_developer_console_tooltip"), vmf:localize("show_developer_console_tooltip"),
["default_value"] = false ["default_value"] = false
}, },
{
["setting_name"] = "show_network_debug_info",
["widget_type"] = "checkbox",
["text"] = vmf:localize("show_network_debug_info"),
["tooltip"] = vmf:localize("show_network_debug_info") .. "\n" ..
vmf:localize("show_network_debug_info_tooltip"),
["default_value"] = false
},
-- { -- {
-- ["setting_name"] = "toggle_developer_console", -- ["setting_name"] = "toggle_developer_console",
-- ["widget_type"] = "keybind", -- ["widget_type"] = "keybind",
@ -153,6 +161,8 @@ vmf.on_setting_changed = function (setting_name)
Managers.mod._settings.developer_mode = vmf:get(setting_name) Managers.mod._settings.developer_mode = vmf:get(setting_name)
Application.set_user_setting("mod_settings", Managers.mod._settings) Application.set_user_setting("mod_settings", Managers.mod._settings)
vmf.network_debug = vmf:get(setting_name) and vmf:get("show_network_debug_info")
local show_developer_console = vmf:get(setting_name) and vmf:get("show_developer_console") local show_developer_console = vmf:get(setting_name) and vmf:get("show_developer_console")
vmf.toggle_developer_console(show_developer_console) vmf.toggle_developer_console(show_developer_console)
@ -160,6 +170,10 @@ vmf.on_setting_changed = function (setting_name)
vmf.toggle_developer_console(vmf:get(setting_name)) vmf.toggle_developer_console(vmf:get(setting_name))
elseif setting_name == "show_network_debug_info" then
vmf.network_debug = vmf:get(setting_name)
elseif setting_name == "logging_mode" then elseif setting_name == "logging_mode" then
vmf.load_logging_settings() vmf.load_logging_settings()