Only sync inventory when necessary

This commit is contained in:
IQuant 2024-05-15 16:50:59 +03:00
parent b8a2802f4f
commit 6d5dd0a039
8 changed files with 66 additions and 10 deletions

View file

@ -2,7 +2,7 @@ local old_order_deck = order_deck
order_deck = function() order_deck = function()
local oldSetRandomSeed = SetRandomSeed local oldSetRandomSeed = SetRandomSeed
SetRandomSeed = function() SetRandomSeed = function()
local shooter = EntityGetRootEntity(GetUpdatedEntityID()) local shooter = EntityGetRootEntity(GetUpdatedEntityID())
@ -12,11 +12,13 @@ order_deck = function()
local seed = 0 local seed = 0
if(EntityHasTag(shooter, "ew_client"))then if(EntityHasTag(shooter, "ew_client"))then
--GamePrint("2: shooter_rng_"..EntityGetName(shooter)) -- GamePrint("2: ew_shooter_rng_"..EntityGetName(shooter))
-- GamePrint(GlobalsGetValue("ew_shooter_rng_"..EntityGetName(shooter), "0"))
seed = tonumber(GlobalsGetValue("ew_shooter_rng_"..EntityGetName(shooter), "0")) or 0 seed = tonumber(GlobalsGetValue("ew_shooter_rng_"..EntityGetName(shooter), "0")) or 0
elseif(EntityHasTag(shooter, "player_unit"))then elseif(EntityHasTag(shooter, "player_unit"))then
seed = Random(10, 10000000) seed = Random(10, 10000000)
GlobalsSetValue("ew_player_rng", tostring(seed)) GlobalsSetValue("ew_player_rng", tostring(seed))
-- GamePrint(tostring(seed))
end end
oldSetRandomSeed(seed, seed) oldSetRandomSeed(seed, seed)

View file

@ -11,6 +11,8 @@ ctx.init = function()
ctx.run_ended = false ctx.run_ended = false
ctx.player_data_by_local_entity = {} ctx.player_data_by_local_entity = {}
ctx.item_prevent_localize = {} ctx.item_prevent_localize = {}
ctx.events = {}
ctx.is_inventory_open = false
end end
return ctx return ctx

View file

@ -261,5 +261,18 @@ function inventory_helper.set_item_data(item_data, player_data)
end end
end end
function inventory_helper.has_inventory_changed(player_data)
local prev_inventory = player_data.prev_inventory_hash
local inventory_hash = 0
for _, item in ipairs(GameGetAllInventoryItems(player_data.entity)) do
local item_comp = EntityGetFirstComponentIncludingDisabled(item, "ItemComponent")
local slot_x, slot_y = ComponentGetValue2(item_comp, "inventory_slot")
inventory_hash = (inventory_hash + (item % 1024 + slot_x + slot_y)) % (math.pow(2, 20) - 1)
end
player_data.prev_inventory_hash = inventory_hash
return inventory_hash ~= prev_inventory
end
return inventory_helper return inventory_helper

View file

@ -114,6 +114,10 @@ function net.send_player_perks(perk_data)
net.send("perks", perk_data, true) net.send("perks", perk_data, true)
end end
function net.send_welcome()
net.send("welcome", nil, true)
end
function net.send_enemy_data(enemy_data) function net.send_enemy_data(enemy_data)
net.send("enemy", enemy_data) net.send("enemy", enemy_data)
end end

View file

@ -191,4 +191,8 @@ function net_handling.mod.item_upload(peer_id, item_data)
item_sync.upload(item_data) item_sync.upload(item_data)
end end
function net_handling.mod.welcome(peer_id, _)
ctx.events.new_player_just_connected = true
end
return net_handling return net_handling

View file

@ -393,6 +393,9 @@ function player_fns.peer_has_player(peer_id)
end end
function player_fns.peer_get_player_data(peer_id) function player_fns.peer_get_player_data(peer_id)
if not player_fns.peer_has_player(peer_id) then
player_fns.spawn_player_for(peer_id, ctx.initial_player_pos.x, ctx.initial_player_pos.y)
end
return ctx.players[peer_id] return ctx.players[peer_id]
end end
@ -413,6 +416,7 @@ function player_fns.spawn_player_for(peer_id, x, y)
end end
util.set_ent_firing_blocked(new, true) util.set_ent_firing_blocked(new, true)
ctx.player_data_by_local_entity[new] = new_playerdata ctx.player_data_by_local_entity[new] = new_playerdata
ctx.events.new_player_just_spawned = true
end end
function player_fns.is_inventory_open() function player_fns.is_inventory_open()

View file

@ -17,6 +17,7 @@ local perk_fns = dofile_once("mods/quant.ew/files/src/perk_fns.lua")
local enemy_sync = dofile_once("mods/quant.ew/files/src/enemy_sync.lua") local enemy_sync = dofile_once("mods/quant.ew/files/src/enemy_sync.lua")
local world_sync = dofile_once("mods/quant.ew/files/src/world_sync.lua") local world_sync = dofile_once("mods/quant.ew/files/src/world_sync.lua")
local item_sync = dofile_once("mods/quant.ew/files/src/item_sync.lua") local item_sync = dofile_once("mods/quant.ew/files/src/item_sync.lua")
local inventory_helper = dofile_once("mods/quant.ew/files/src/inventory_helper.lua")
ModLuaFileAppend("data/scripts/gun/gun.lua", "mods/quant.ew/files/append/gun.lua") ModLuaFileAppend("data/scripts/gun/gun.lua", "mods/quant.ew/files/append/gun.lua")
ModLuaFileAppend("data/scripts/gun/gun_actions.lua", "mods/quant.ew/files/append/action_fix.lua") ModLuaFileAppend("data/scripts/gun/gun_actions.lua", "mods/quant.ew/files/append/action_fix.lua")
@ -112,6 +113,14 @@ end
function OnPlayerSpawned( player_entity ) -- This runs when player entity has been created function OnPlayerSpawned( player_entity ) -- This runs when player entity has been created
GamePrint( "OnPlayerSpawned() - Player entity id: " .. tostring(player_entity) ) GamePrint( "OnPlayerSpawned() - Player entity id: " .. tostring(player_entity) )
for _, client in pairs(EntityGetWithTag("ew_client")) do
GamePrint("Removing previous client: "..client)
EntityKill(client)
end
local x, y = EntityGetTransform(player_entity)
ctx.initial_player_pos = {x=x, y=y}
my_player = player_fns.make_playerdata_for(player_entity, ctx.my_id) my_player = player_fns.make_playerdata_for(player_entity, ctx.my_id)
GamePrint("My peer_id: "..ctx.my_id) GamePrint("My peer_id: "..ctx.my_id)
ctx.players[ctx.my_id] = my_player ctx.players[ctx.my_id] = my_player
@ -150,6 +159,13 @@ local function on_world_pre_update_inner()
net.update() net.update()
local inventory_gui_comp = EntityGetFirstComponentIncludingDisabled(my_player.entity, "InventoryGuiComponent")
local inventory_open = ComponentGetValue2(inventory_gui_comp, "mActive")
if ctx.is_inventory_open and not inventory_open then
ctx.events.inventory_maybe_just_changed = true
end
ctx.is_inventory_open = inventory_open
if ctx.is_host and not EntityGetIsAlive(my_player.entity) then if ctx.is_host and not EntityGetIsAlive(my_player.entity) then
if not ctx.run_ended then if not ctx.run_ended then
GamePrint("Notifying of run end") GamePrint("Notifying of run end")
@ -169,6 +185,10 @@ local function on_world_pre_update_inner()
end end
end end
if GameGetFrameNum() == 0 then
net.send_welcome()
end
-- Item sync -- Item sync
if ctx.is_host then if ctx.is_host then
item_sync.host_upload_items(my_player) item_sync.host_upload_items(my_player)
@ -212,12 +232,18 @@ local function on_world_pre_update_inner()
net.send_host_player_info(player_info) net.send_host_player_info(player_info)
end end
if ctx.events.new_player_just_connected or ctx.events.inventory_maybe_just_changed or GameGetFrameNum() % 20 == 0 then
if ctx.events.new_player_just_connected or inventory_helper.has_inventory_changed(my_player) then
local inventory_state = player_fns.serialize_items(my_player)
if inventory_state ~= nil then
GamePrint("Sending updated inventory")
net.send_player_inventory(inventory_state)
end
end
end
-- Inventory and perk sync -- Inventory and perk sync
if GameGetFrameNum() % 120 == 0 then if GameGetFrameNum() % 120 == 0 then
local inventory_state = player_fns.serialize_items(my_player)
if inventory_state ~= nil then
net.send_player_inventory(inventory_state)
end
local perk_data = perk_fns.get_my_perks() local perk_data = perk_fns.get_my_perks()
if perk_data ~= nil then if perk_data ~= nil then
net.send_player_perks(perk_data) net.send_player_perks(perk_data)
@ -243,6 +269,7 @@ end
function OnWorldPostUpdate() -- This is called every time the game has finished updating the world function OnWorldPostUpdate() -- This is called every time the game has finished updating the world
util.tpcall(on_world_post_update_inner) util.tpcall(on_world_post_update_inner)
ctx.events = {}
end end

View file

@ -9,7 +9,7 @@
+ Sync shuffle + Sync shuffle
k Синхронизировать смерти противников k Синхронизировать смерти противников
- Общее золото - Общее золото
- Удаление лишних клиентов при загрузке игры + Удаление лишних клиентов при загрузке игры
- intern pathnames in enemy sync - intern pathnames in enemy sync
+ Fix bottles and other items duplicating when thrown (on host?) + Fix bottles and other items duplicating when thrown (on host?)
@ -24,8 +24,9 @@
+ Позволить менять сид мира + Позволить менять сид мира
- Никнеймы игроков - Никнеймы игроков
k Лимит на длину сообщения k Лимит на длину сообщения
- Улучшеная синхронизация инвентаря и перков + Улучшеная синхронизация инвентаря
+ ...и текущего предмета - ...и перков
+ ...и текущего предмета
+ reliability + reliability
+ Сжатие пакетов + Сжатие пакетов
+ Перекидывание предметов + Перекидывание предметов
@ -37,4 +38,3 @@
- proxy: stop receiving connections before another start_game on game over, noita: try to reconnect to proxy. - proxy: stop receiving connections before another start_game on game over, noita: try to reconnect to proxy.
- sync traps - sync traps
- holy mountains are screwed up when clients enter it before host does - holy mountains are screwed up when clients enter it before host does