Skip to content

Commit

Permalink
#67 Fixed noitapatcher. Changed de-/serialisation of entities.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ismoh committed Jul 12, 2023
1 parent 5f3e4e0 commit 6f8d617
Show file tree
Hide file tree
Showing 14 changed files with 68 additions and 771 deletions.
Binary file modified miscs/2022-06-21_teaser.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 12 additions & 12 deletions mods/noita-mp/files/scripts/init/init_.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ if require then
dofile("mods/noita-mp/files/scripts/init/init_package_loading.lua")
end

if not _G.NoitaPatcherUtils then
-- If require is not available, we are in Noita Components lua context and should use dofile_once instead.
-- But make sure to load files only when needed, to avoid loading them into memory.
if not require then
-- NoitaPatcher won't be available in Noita Components context!
else
print("Initialise NoitaPatcherUtils..")
---Globally accessible noitapatcher in _G.noitapatcher.
---@alias _G.NoitaPatcherUtils NoitaPatcherUtils
_G.NoitaPatcherUtils = require("NoitaPatcherUtils")
end
end

if not _G.Logger then
if not require then
Expand Down Expand Up @@ -243,18 +255,6 @@ if not _G.Client then
end
end

if not _G.NoitaPatcherUtils then
-- If require is not available, we are in Noita Components lua context and should use dofile_once instead.
-- But make sure to load files only when needed, to avoid loading them into memory.
if not require then
-- NoitaPatcher won't be available in Noita Components context!
else
---Globally accessible noitapatcher in _G.noitapatcher.
---@alias _G.NoitaPatcherUtils NoitaPatcherUtils
_G.NoitaPatcherUtils = require("NoitaPatcherUtils")
end
end

if not _G.guiI then
if not require then
-- imGui won't be available in Noita Components context!
Expand Down
20 changes: 17 additions & 3 deletions mods/noita-mp/files/scripts/net/Client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -511,14 +511,22 @@ function ClientInit.new(sockClient)
error(("onNewNuidSerialized data.entityId is empty: %s"):format(data.entityId), 2)
end

if Utils.IsEmpty(data.serializedEntity) then
error(("onNewNuidSerialized data.serializedEntity is empty: %s"):format(data.serializedEntity), 2)
if Utils.IsEmpty(data.serializedEntityString) then
error(("onNewNuidSerialized data.serializedEntityString is empty: %s"):format(data.serializedEntityString), 2)
end

if Utils.IsEmpty(data.nuid) then
error(("onNewNuidSerialized data.nuid is empty: %s"):format(data.nuid), 2)
end

if Utils.IsEmpty(data.x) then
error(("onNewNuidSerialized data.x is empty: %s"):format(data.x), 2)
end

if Utils.IsEmpty(data.y) then
error(("onNewNuidSerialized data.y is empty: %s"):format(data.y), 2)
end

-- FOR TESTING ONLY, DO NOT MERGE
--print(Utils.pformat(data))
--os.exit()
Expand All @@ -529,7 +537,13 @@ function ClientInit.new(sockClient)
-- end
--end

EntitySerialisationUtils.deserializeEntireRootEntity(data.serializedEntity, data.nuid)
local nuid, entityId = GlobalsUtils.getNuidEntityPair(data.nuid)

if Utils.IsEmpty(entityId) then
entityId = EntityCreateNew(data.nuid)
end

entityId = NoitaPatcherUtils.deserializeEntity(entityId, data.serializedEntityString, data.x, data.y) --EntitySerialisationUtils.deserializeEntireRootEntity(data.serializedEntity, data.nuid)

sendAck(data.networkMessageId, NetworkUtils.events.newNuidSerialized.name)
CustomProfiler.stop("ClientInit.onNewNuidSerialized", cpc32)
Expand Down
27 changes: 17 additions & 10 deletions mods/noita-mp/files/scripts/net/Server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -974,15 +974,16 @@ function ServerInit.new(sockServer)
end

function self.sendNewNuid(owner, localEntityId, newNuid, x, y, rotation, velocity, filename, health, isPolymorphed)
local cpc017 = CustomProfiler.start("Server.sendNewNuid")
local event = NetworkUtils.events.newNuid.name
local data = { NetworkUtils.getNextNetworkMessageId(), owner, localEntityId, newNuid, x, y, rotation, velocity, filename, health, isPolymorphed }
local sent = self:sendToAll(event, data)
CustomProfiler.stop("Server.sendNewNuid", cpc017)
return sent
local cpc017 = CustomProfiler.start("Server.sendNewNuid")
local event = NetworkUtils.events.newNuid.name
local data = { NetworkUtils.getNextNetworkMessageId(), owner, localEntityId, newNuid, x, y, rotation, velocity, filename, health,
isPolymorphed }
local sent = self:sendToAll(event, data)
CustomProfiler.stop("Server.sendNewNuid", cpc017)
return sent
end

function self.sendNewNuidSerialized(ownerName, ownerGuid, entityId, serializedEntity, nuid)
function self.sendNewNuidSerialized(ownerName, ownerGuid, entityId, serializedEntityString, nuid, x, y)
local cpc026 = CustomProfiler.start("Server.sendNewNuidSerialized")

if Utils.IsEmpty(ownerName) then
Expand All @@ -994,15 +995,21 @@ function ServerInit.new(sockServer)
if Utils.IsEmpty(entityId) then
error(("entityId must not be nil or empty %s"):format(entityId), 2)
end
if Utils.IsEmpty(serializedEntity) then
error(("serializedEntity must not be nil or empty %s"):format(serializedEntity), 2)
if Utils.IsEmpty(serializedEntityString) or type(serializedEntityString) ~= "string" then
error(("serializedEntityString must not be nil or empty %s or is not of type 'string'."):format(serializedEntityString), 2)
end
if Utils.IsEmpty(nuid) then
error(("nuid must not be nil or empty %s"):format(nuid), 2)
end
if Utils.IsEmpty(x) then
error(("x must not be nil or empty %s"):format(x), 2)
end
if Utils.IsEmpty(y) then
error(("y must not be nil or empty %s"):format(y), 2)
end

local event = NetworkUtils.events.newNuidSerialized.name
local data = { NetworkUtils.getNextNetworkMessageId(), ownerName, ownerGuid, entityId, serializedEntity, nuid }
local data = { NetworkUtils.getNextNetworkMessageId(), ownerName, ownerGuid, entityId, serializedEntityString, nuid, x, y }
local sent = self:sendToAll(event, data)
CustomProfiler.stop("Server.sendNewNuidSerialized", cpc026)

Expand Down
56 changes: 11 additions & 45 deletions mods/noita-mp/files/scripts/util/EntityUtils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -206,40 +206,6 @@ local function findByFilename(filename, filenames)
return false
end

local function getParentsUntilRootEntity(who, entityId)
local cpc = CustomProfiler.start("EntityUtils.getParentsUntilRootEntity")
local parentNuids = {}
local parentEntityId = EntityGetParent(entityId) -- returns 0, if entity has no parent

while parentEntityId and parentEntityId > 0 do
local hasParentNuid, parentNuid = NetworkVscUtils.hasNuidSet(parentEntityId)
if not parentNuid then
local localPlayer = MinaUtils.getLocalMinaInformation()
local ownerName = localPlayer.name
local ownerGuid = localPlayer.guid
if who == Server.iAm and not parentNuid then
parentNuid = NuidUtils.getNextNuid()
NetworkVscUtils.addOrUpdateAllVscs(parentEntityId, ownerName, ownerGuid, parentNuid)
local _, _, _, filename, health, rotation, velocity, x, y = NoitaComponentUtils.getEntityData(parentEntityId)
Server.sendNewNuid({ ownerName, ownerGuid }, parentEntityId, parentNuid, x, y, rotation, velocity,
filename, health, EntityUtils.isEntityPolymorphed(entityId))
elseif who == Client.iAm and not parentNuid then
Client.sendNeedNuid(ownerName, ownerGuid, entityId)
-- TODO: return and wait for nuid? Otherwise child will never know who is the parent.
else
error("Unable to get whoAmI() unused!", 2)
end
end
if type(parentNuid) == "number" then
table.insert(parentNuids, 1, parentNuid)
end
parentEntityId = EntityGetParent(parentEntityId)
end
CustomProfiler.stop("EntityUtils.getParentsUntilRootEntity", cpc)
return parentNuids
end


--- public global methods:


Expand Down Expand Up @@ -517,8 +483,8 @@ function EntityUtils.processAndSyncEntityNetworking(startFrameTime)
NetworkVscUtils.addOrUpdateAllVscs(entityId, compOwnerName, compOwnerGuid, nuid)
end
end
Server.sendNewNuid({ compOwnerName, compOwnerGuid }, entityId, nuid, x, y, rotation, velocity,
filename, health, EntityUtils.isEntityPolymorphed(entityId))
--Server.sendNewNuid({ compOwnerName, compOwnerGuid }, entityId, nuid, x, y, rotation, velocity,
-- filename, health, EntityUtils.isEntityPolymorphed(entityId))
--local finished, serializedEntity = EntitySerialisationUtils.serializeEntireRootEntity(entityId, nuid, startFrameTime)
--local ONLYFORTESTING = EntitySerialisationUtils.deserializeEntireRootEntity(serializedEntity)
local serializedEntityString = NoitaPatcherUtils.serializeEntity(entityId)
Expand All @@ -527,16 +493,16 @@ function EntityUtils.processAndSyncEntityNetworking(startFrameTime)
finished = true
end
if finished == true then
Server.sendNewNuidSerialized(compOwnerName, compOwnerGuid, entityId, serializedEntityString, nuid)
Server.sendNewNuidSerialized(compOwnerName, compOwnerGuid, entityId, serializedEntityString, nuid, x, y)
else
Logger.warn(Logger.channels.entity,
"EntitySerialisationUtils.serializeEntireRootEntity took too long. Breaking loop by returning entityId.")
-- when executionTime is too long, return the next entityCacheIndex to continue with it
--prevEntityIndex = entityIndex + 1
EntityCacheUtils.set(entityId, nuid, compOwnerGuid, compOwnerName, filename, x, y, rotation,
velocity.x, velocity.y, health.current, health.max, finished, serializedEntity)
CustomProfiler.stop("EntityUtils.processAndSyncEntityNetworking", cpc)
return -- completely end function, because it took too long
-- Logger.warn(Logger.channels.entity,
-- "EntitySerialisationUtils.serializeEntireRootEntity took too long. Breaking loop by returning entityId.")
-- -- when executionTime is too long, return the next entityCacheIndex to continue with it
-- --prevEntityIndex = entityIndex + 1
-- EntityCacheUtils.set(entityId, nuid, compOwnerGuid, compOwnerName, filename, x, y, rotation,
-- velocity.x, velocity.y, health.current, health.max, finished, serializedEntityString)
-- CustomProfiler.stop("EntityUtils.processAndSyncEntityNetworking", cpc)
-- return -- completely end function, because it took too long
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions mods/noita-mp/files/scripts/util/NetworkUtils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ NetworkUtils.events = {
},
newNuidSerialized = {
name = "newNuidSerialized",
schema = { "networkMessageId", "ownerName", "ownerGuid", "entityId", "serializedEntity", "nuid" },
resendIdentifiers = { "ownerName", "ownerGuid", "entityId" },
schema = { "networkMessageId", "ownerName", "ownerGuid", "entityId", "serializedEntityString", "nuid", "x", "y" },
resendIdentifiers = { "ownerName", "ownerGuid", "entityId", "nuid" },
isCacheable = true
},
--- needNuid is used to ask for a nuid from client to servers
Expand Down
10 changes: 9 additions & 1 deletion mods/noita-mp/files/scripts/util/NoitaPatcherUtils.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local NoitaPatcherUtils = {}

local np = require("noitapatcher")
local base64 = require("base64")

-- see https://dexter.xn--dpping-wxa.eu/NoitaPatcher/Example.html#example

Expand All @@ -11,7 +12,14 @@ function OnProjectileFired() end
function OnProjectileFiredPost() end

function NoitaPatcherUtils.serializeEntity(entityId)
return np.SerializeEntity(entityId)
local binaryString = np.SerializeEntity(entityId)
local encoded = base64.encode(binaryString)
return encoded
end

function NoitaPatcherUtils.deserializeEntity(entityId, serializedEntityString, x, y)
local decoded = base64.decode(serializedEntityString)
return np.DeserializeEntity(entityId, decoded, x, y)
end

return NoitaPatcherUtils
1 change: 0 additions & 1 deletion mods/noita-mp/lua_modules/lib/lua/5.1/nsew.version

This file was deleted.

Binary file not shown.
43 changes: 0 additions & 43 deletions mods/noita-mp/lua_modules/share/lua/5.1/nsew/load.lua

This file was deleted.

11 changes: 0 additions & 11 deletions mods/noita-mp/lua_modules/share/lua/5.1/nsew/native_dll.lua

This file was deleted.

Loading

0 comments on commit 6f8d617

Please sign in to comment.