Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FxServer tries to start sessionmanager even when OneSync is enabled #2876

Open
brunosollar opened this issue Oct 22, 2024 · 5 comments · May be fixed by #2877
Open

FxServer tries to start sessionmanager even when OneSync is enabled #2876

brunosollar opened this issue Oct 22, 2024 · 5 comments · May be fixed by #2877
Labels
bug triage Needs a preliminary assessment to determine the urgency and required action

Comments

@brunosollar
Copy link

What happened?

Self-explanatory.

Expected result

FXServer not forcing the start of sessionmanager.

Reproduction steps

  1. Setup a server and enable OneSync.
  2. The server should try to start sessionmanager.

Importancy

Slight inconvenience

Area(s)

FXServer

Specific version(s)

Any FXServer version

Additional information

No response

@brunosollar brunosollar added bug triage Needs a preliminary assessment to determine the urgency and required action labels Oct 22, 2024
@outsider31000
Copy link

that is done in your server.cfg , is onesync supposed to force start it even when you dont have ensure ensure sessionmanager ?

@Ehbw
Copy link
Contributor

Ehbw commented Oct 22, 2024

that is done in your server.cfg , is onesync supposed to force start it even when you dont have ensure ensure sessionmanager ?

Not in this case. citizen-server-impl will try to start sessionmanager even if the server is using onesync infinity

if (instance->GetComponent<fx::GameServer>()->GetGameName() == fx::GameName::RDR3)
{
consoleCtx->ExecuteSingleCommandDirect(ProgramArguments{ "start", "sessionmanager-rdr3" });
}
else
{
consoleCtx->ExecuteSingleCommandDirect(ProgramArguments{ "start", "sessionmanager" });
}

@DerDevHD
Copy link

Session-manager is force-started (even when it was deleted, so you'll receive warnings in the console) since the current RPC implementation relies on it.

-- RPC REQUEST HANDLER
local InvokeRpcEvent
if GetCurrentResourceName() == 'sessionmanager' then
local rpcEvName = ('__cfx_rpcReq')
RegisterNetEvent(rpcEvName)
AddEventHandler(rpcEvName, function(retEvent, retId, refId, args)
local source = source
local eventTriggerFn = TriggerServerEvent
if isDuplicityVersion then
eventTriggerFn = function(name, ...)
TriggerClientEvent(name, source, ...)
end
end
local returnEvent = function(args, err)
eventTriggerFn(retEvent, retId, args, err)
end
local function makeArgRefs(o)
if type(o) == 'table' then
for k, v in pairs(o) do
if type(v) == 'table' and rawget(v, '__cfx_functionReference') then
o[k] = function(...)
return InvokeRpcEvent(source, rawget(v, '__cfx_functionReference'), {...})
end
end
makeArgRefs(v)
end
end
end
makeArgRefs(args)
runWithBoundaryEnd(function()
local payload = Citizen_InvokeFunctionReference(refId, msgpack_pack(args))
if #payload == 0 then
returnEvent(false, 'err')
return
end
local rvs = msgpack_unpack(payload)
if type(rvs[1]) == 'table' and rvs[1].__cfx_async_retval then
rvs[1].__cfx_async_retval(returnEvent)
else
returnEvent(rvs)
end
end)
end)
end
local rpcId = 0
local rpcPromises = {}
local playerPromises = {}
-- RPC REPLY HANDLER
local repName = ('__cfx_rpcRep:%s'):format(GetCurrentResourceName())
RegisterNetEvent(repName)
AddEventHandler(repName, function(retId, args, err)
local promise = rpcPromises[retId]
rpcPromises[retId] = nil
-- remove any player promise for us
for k, v in pairs(playerPromises) do
v[retId] = nil
end
if promise then
if args then
promise:resolve(args[1])
elseif err then
promise:reject(err)
end
end
end)
if isDuplicityVersion then
AddEventHandler('playerDropped', function(reason)
local source = source
if playerPromises[source] then
for k, v in pairs(playerPromises[source]) do
local p = rpcPromises[k]
if p then
p:reject('Player dropped: ' .. reason)
end
end
end
playerPromises[source] = nil
end)
end
local EXT_FUNCREF = 10
local EXT_LOCALFUNCREF = 11
msgpack.extend_clear(EXT_FUNCREF, EXT_LOCALFUNCREF)
-- RPC INVOCATION
InvokeRpcEvent = function(source, ref, args)
if not coroutine_running() then
error('RPC delegates can only be invoked from a thread.', 2)
end
local src = source
local eventTriggerFn = TriggerServerEvent
if isDuplicityVersion then
eventTriggerFn = function(name, ...)
TriggerClientEvent(name, src, ...)
end
end
local p = promise.new()
local asyncId = rpcId
rpcId = rpcId + 1
local refId = ('%d:%d'):format(GetInstanceId(), asyncId)
eventTriggerFn('__cfx_rpcReq', repName, refId, ref, args)
-- add rpc promise
rpcPromises[refId] = p
-- add a player promise
if not playerPromises[src] then
playerPromises[src] = {}
end
playerPromises[src][refId] = true
return Citizen.Await(p)
end
local funcref_mt = nil
funcref_mt = msgpack.extend({
__gc = function(t)
DeleteFunctionReference(rawget(t, '__cfx_functionReference'))
end,
__index = function(t, k)
error('Cannot index a funcref', 2)
end,
__newindex = function(t, k, v)
error('Cannot set indexes on a funcref', 2)
end,
__call = function(t, ...)
local netSource = rawget(t, '__cfx_functionSource')
local ref = rawget(t, '__cfx_functionReference')
if not netSource then
local args = msgpack_pack_args(...)
-- as Lua doesn't allow directly getting lengths from a data buffer, and _s will zero-terminate, we have a wrapper in the game itself
local rv = runWithBoundaryEnd(function()
return Citizen_InvokeFunctionReference(ref, args)
end)
local rvs = msgpack_unpack(rv)
-- handle async retvals from refs
if rvs and type(rvs[1]) == 'table' and rawget(rvs[1], '__cfx_async_retval') and coroutine_running() then
local p = promise.new()
rvs[1].__cfx_async_retval(function(r, e)
if r then
p:resolve(r)
elseif e then
p:reject(e)
end
end)
return table_unpack(Citizen.Await(p))
end
if not rvs then
error()
end
return table_unpack(rvs)
else
return InvokeRpcEvent(tonumber(netSource.source:sub(5)), ref, {...})
end
end,
__ext = EXT_FUNCREF,
__pack = function(self, tag)
local refstr = Citizen.GetFunctionReference(self)
if refstr then
return refstr
else
error(("Unknown funcref type: %d %s"):format(tag, type(self)), 2)
end
end,
__unpack = function(data, tag)
local ref = data
-- add a reference
DuplicateFunctionReference(ref)
local tbl = {
__cfx_functionReference = ref,
__cfx_functionSource = deserializingNetEvent
}
if tag == EXT_LOCALFUNCREF then
tbl.__cfx_functionSource = nil
end
tbl = setmetatable(tbl, funcref_mt)
return tbl
end,
})

@AvarianKnight
Copy link
Contributor

I don't think that code is actually used by anything, RPC natives are all done in C++

@tens0rfl0w
Copy link
Contributor

tens0rfl0w commented Oct 23, 2024

This is 'leftover' code from when remote function references were a thing.

Back then, you could trigger callbacks from net events natively. However, this implementation broke some time ago and was left behind IIRC.

TriggerServerEvent('rpcEvent', function(value)
    print(value)
end)

RegisterNetEvent('rpcEvent', function(cb)
    cb('test')
end)

So if there are no plans to make RPC calls generally available again, then this could be removed.

@tens0rfl0w tens0rfl0w linked a pull request Oct 23, 2024 that will close this issue
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug triage Needs a preliminary assessment to determine the urgency and required action
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants