DML/modules/clients.lua
Christian Franz 8f7371825d Version 2.2.1
csarManager enhancements etc.
2024-04-04 13:25:33 +02:00

199 lines
5.7 KiB
Lua

clients = {}
clients.version = "0.0.0"
clients.ups = 1
clients.verbose = false
clients.netlog = true
clients.players = {}
-- player entry: indexed by name
-- playerName - name of player, same as index
-- uName = unit name
-- coa = coalition
-- connected = true/false is currently ingame
function clients.out(msg)
-- do some preprocessing?
if clients.verbose then
trigger.action.outText(msg, 30)
end
-- add to own log?
if clients.netlog then
env.info(msg)
end
end
--[[--
Event ID:
1 = player enters mission for first time
2 = player enters unit
3 = player leaves unit
4 = player changes unit
5 = player changes coalition
Sequence of events
Player enters mission first time
- player enters mission (new player) ID = 1
- player enters unit ID = 2
Player is no longer active (their unit is gone)
- player leaves unit ID = 3
Player enters unit after having already been in the mission
- (player changes coalition) if unit belongs to different coa
- (player changes unit if unit different than before)
- player enters unit
--]]--
--
-- client events
--
clients.cb = {} -- profile = (id, this, last)
function clients.invokeCallbacks(ID, this, last)
for idx, cb in pairs(clients.cb) do
cb(ID, this, last)
end
end
function clients.addCallback(theCB)
table.insert(clients.cb, theCB)
end
function clients.playerEnteredMission(thisTime)
clients.out("clients: Player <" .. thisTime.playerName .. "> enters mission for the first time")
clients.invokeCallbacks(1, thisTime)
end
function clients.playerEnteredUnit(thisTime)
-- called when player enters a unit
clients.out("clients: Player <" .. thisTime.playerName .. "> enters Unit <" .. thisTime.uName .. ">.")
clients.invokeCallbacks(2, thisTime)
end
function clients.playerLeavesUnit(lastTime)
-- called when player leaves a unit
clients.out("clients: Player <" .. lastTime.playerName .. "> leaves Unit <" .. lastTime.uName .. ">.")
clients.invokeCallbacks(3, lastTime)
end
function clients.playerChangedUnits(thisTime, lastTime)
-- called when player enters a different unit
clients.out("clients: Player <" .. thisTime.playerName .. "> changes from Unit <" .. lastTime.uName .. "> to NEW unit <" .. thisTime.uName .. ">.")
clients.invokeCallbacks(4, thisTime, lastTime)
end
function clients.playerChangedCoalition(thisTime, lastTime)
-- called when player enters a different unit
clients.out("clients: Player <" .. thisTime.playerName .. "> changes from coalition <" .. lastTime.coa .. "> to NEW coalition <" .. thisTime.coa .. ">.")
clients.invokeCallbacks(4, thisTime, lastTime)
end
-- check all connected player units
function clients.compareStatus(thisTime, lastTime)
if lastTime then
-- they were known last time I checked. see if they were in-game
if thisTime.connected == lastTime.connected then
-- status is the same as before
else
-- player entered or left mission, and was known last time
if thisTime.connected then
-- player connected but was known, do nothing
else
-- player left mission. do we want to record this?
end
end
-- check if they have the same unit name
-- if not, check if they have changed coas
if lastTime.uName == thisTime.uName then
-- same unit, all is fine
else
-- new unit. check if same side
if lastTime.coa == thisTime.coa then
-- player stayed in same coa
else
-- player changed coalition
clients.playerChangedCoalition(thisTime, lastTime)
end
clients.playerEnteredUnit(thisTime)
clients.playerChangedUnits(thisTime, lastTime)
end
else
-- player is new to mission
clients.playerEnteredMission(thisTime)
clients.playerEnteredUnit(thisTime)
end
end
function clients.checkPlayers()
local connectedNow = {} -- players that are connected now
local allCoas = {0, 1, 2}
-- collect all currently connected players
for idx, coa in pairs(allCoas) do
local cPlayers = coalition.getPlayers(coa) -- gets UNITS!
for idy, aPlayerUnit in pairs(cPlayers) do
if aPlayerUnit and Unit.isExist(aPlayerUnit) then
local entry = {}
local playerName = aPlayerUnit:getPlayerName()
entry.playerName = playerName
entry.uName = aPlayerUnit:getName()
entry.coa = coa
entry.connected = true
connectedNow[playerName] = entry
-- see if they were connected last time we checked
local lastTime = clients.players[playerName]
clients.compareStatus(entry, lastTime)
end
end
end
-- now find players who are no longer represented and
-- event them
for aPlayerName, lastTime in pairs(clients.players) do
local thisTime = connectedNow[aPlayerName]
if thisTime then
-- is also present now. skip
else
-- no longer active, see if they were active last time
if lastTime.connected then
-- they were active, generate disco event
clients.playerLeavesUnit(lastTime)
end
lastTime.connected = false
-- keep on roster
connectedNow[aPlayerName] = lastTime
end
end
clients.players = connectedNow
end
function clients.update()
timer.scheduleFunction(clients.update, {}, timer.getTime() + 1)
clients.checkPlayers()
end
--
-- Event handling
--
function clients:onEvent(theEvent)
if not theEvent then return end
local theUnit = theEvent.initiator
if not theUnit then return end
if not theUnit.getPlayerName or not theUnit:getPlayerName() then return end
-- we have a player birth. Simply invoke checkplayers
clients.out("clients: detected player birth event.")
clients.checkPlayers()
end
--
-- Start
--
function clients.start()
world.addEventHandler(clients)
timer.scheduleFunction(clients.update, {}, timer.getTime() + 1)
trigger.action.outText("clients v" .. clients.version .. " running.", 30)
end
clients.start()