Jump to content

How to create statistics for your server


Recommended Posts

Hi there,

 

I added an HTTP request in the last piece of the code to send the event data, but I receive an error that global require call is a nil.

 

Don't the DCS World script engine have this package in the library?

 

How do I get the "socket.http" in the DCS World environment?

 

Here is the code I added in the script:

local stime = SecondsToClock(timer.getTime())
trigger.action.outText("stime="..stime.." WorldEvent="..WorldEvent.." InitID_="..InitID_.." InitCoa="..InitCoa.." InitGroupCat="..InitGroupCat.." InitType="..InitType.." InitPlayer="..InitPlayer.." eWeaponCat="..eWeaponCat.." eWeaponName="..eWeaponName.." TargID_="..TargID_.." TargCoa="..TargCoa.." TargGroupCat="..TargGroupCat.." TargType="..TargType.." TargPlayer="..TargPlayer, 20)
local http = require("socket.http")
local ltn12 = require("ltn12")
local request_body = "stime="..stime.."&WorldEvent="..WorldEvent.."&InitID_="..InitID_.."&InitCoa="..InitCoa.."&InitGroupCat="..InitGroupCat.."&InitType="..InitType.."&InitPlayer="..InitPlayer.."&eWeaponCat="..eWeaponCat.."&eWeaponName="..eWeaponName.."&TargID_="..TargID_.."&TargCoa="..TargCoa.."&TargGroupCat="..TargGroupCat.."&TargType="..TargType.."&TargPlayer="..TargPlayer
local response_body = {}
local res, code, response_headers = http.request{
 url = "http://httpbin.org/post",
 method = "POST", 
 headers = 
 {
["Content-Type"] = "application/x-www-form-urlencoded";
["Content-Length"] = #request_body;
 },
 source = ltn12.source.string(request_body),
 sink = ltn12.sink.table(response_body),
}
trigger.action.outText("res="..res.." code="..code, 10)
if type(response_headers) == "table" then
 for k, v in pairs(response_headers) do 
trigger.action.outText("k="..k.." v="..v, 10)
 end
end
trigger.action.outText("Response body: ", 10)
if type(response_body) == "table" then
 trigger.action.outText(table.concat(response_body), 10)
else
 trigger.action.outText("Not a table: "..type(response_body), 10)
end

 

--Handler table
local eStatHandler = {}

--Neccessary tables for string instead of intagers
local SETCoalition = 
{
[1] = "red",
[2] = "blue",
}

local SETGroupCat = 
{
[1] = "AIRPLANE",
[2] = "HELICOPTER",
[3] = "GROUND_UNIT",
[4] = "SHIP",
[5] = "STRUCTURE",
}

local SETWeaponCatName = 
{
  [0] = "SHELL",
  [1] = "MISSILE",
  [2] = "ROCKET",
  [3] = "BOMB",
}

local wEvent = {
[0] = "S_EVENT_INVALID",
[1] = "S_EVENT_SHOT",
[2] = "S_EVENT_HIT",
[3] = "S_EVENT_TAKEOFF",
[4] = "S_EVENT_LAND",
[5] = "S_EVENT_CRASH",
[6] = "S_EVENT_EJECTION",
[7] = "S_EVENT_REFUELING",
[8] = "S_EVENT_DEAD",
[9] = "S_EVENT_PILOT_DEAD",
[10] = "S_EVENT_BASE_CAPTURED",
[11] = "S_EVENT_MISSION_START",
[12] = "S_EVENT_MISSION_END",
[13] = "S_EVENT_TOOK_CONTROL",
[14] = "S_EVENT_REFUELING_STOP",
[15] = "S_EVENT_BIRTH",
[16] = "S_EVENT_HUMAN_FAILURE",
[17] = "S_EVENT_ENGINE_STARTUP",
[18] = "S_EVENT_ENGINE_SHUTDOWN",
[19] = "S_EVENT_PLAYER_ENTER_UNIT",
[20] = "S_EVENT_PLAYER_LEAVE_UNIT",
[21] = "S_EVENT_PLAYER_COMMENT",
[22] = "S_EVENT_SHOOTING_START",
[23] = "S_EVENT_SHOOTING_END",
[24] = "S_EVENT_MAX",
}

statEventsTable = {}


function SecondsToClock(sSeconds)
local nSeconds = sSeconds
if nSeconds == 0 then
	--return nil;
	return "00:00:00";
else
	nHours = string.format("%02.f", math.floor(nSeconds/3600));
	nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours*60)));
	nSecs = string.format("%02.f", math.floor(nSeconds - nHours*3600 - nMins *60));
	return nHours..":"..nMins..":"..nSecs
end
end

function eStatHandler:onEvent(e)
   local InitID_ = ""
   local WorldEvent = wEvent[e.id]
   local InitCoa = ""
   local InitGroupCat = ""
   local InitType = ""
   local InitPlayer = ""
   local eWeaponCat = ""
   local eWeaponName = ""
   local TargID_ = ""
   local TargType = ""
   local TargPlayer = ""
   local TargCoa = ""
   local TargGroupCat = ""

--Initiator variables
if e.initiator and e.initiator~=nil and e.initiator~='' then
	if Object.getCategory(e.initiator) and Object.getCategory(e.initiator)==Object.Category.UNIT then
		if Unit.getCategory(e.initiator) and (Unit.getCategory(e.initiator)==Unit.Category.AIRPLANE or Unit.getCategory(e.initiator)==Unit.Category.HELICOPTER) then
			--get player name.
			if Unit.getPlayerName(e.initiator)~=nil then
				InitPlayer = Unit.getPlayerName(e.initiator)
			else
				InitPlayer = "AI"
			end
		end
	end
	
	--Check Category of object
	--If no category
	if not Object.getCategory(e.initiator) then
		InitID_ = e.initiator.id_
		InitCoa = SETCoalition[e.initiator:getCoalition()]
		InitGroupCat = SETGroupCat[e.initiator:getCategory()]
		InitType = e.initiator:getTypeName()
	--if Category is UNIT	
	elseif Object.getCategory(e.initiator) == Object.Category.UNIT then
		local InitGroup = e.initiator:getGroup()
		InitID_ = e.initiator.id_
		InitCoa = SETCoalition[initGroup:getCoalition()]
		InitGroupCat = SETGroupCat[initGroup:getCategory() + 1]
		InitType = e.initiator:getTypeName()
	--if Category is STATIC
	elseif  Object.getCategory(e.initiator) == Object.Category.STATIC then
		InitID_ = e.initiator.id_
		InitCoa = SETCoalition[e.initiator:getCoalition()]
		InitGroupCat = SETGroupCat[e.initiator:getCategory()]
		InitType = e.initiator:getTypeName()
	end
else
	InitID_ = "No Initiator"
	InitCoa = "No Initiator"
	InitGroupCat = "No Initiator"
	InitType = "No Initiator"
	InitPlayer = "No Initiator"
end

--Weapon variables	
if e.weapon == nil then
	eWeaponCat = "No Weapon"
	eWeaponName = "No Weapon"
else
	local eWeaponDesc = e.weapon:getDesc()
	eWeaponCat = SETWeaponCatName[eWeaponDesc.category]
	eWeaponName = eWeaponDesc.displayName
end

--Target variables
if e.target and e.target~=nil and e.target~='' and e.target:isExist() then
	if Object.getCategory(e.target) and Object.getCategory(e.target)==Object.Category.UNIT then
		if Unit.getCategory(e.target) and (Unit.getCategory(e.target)==Unit.Category.AIRPLANE or Unit.getCategory(e.target)==Unit.Category.HELICOPTER) then
			--get player name.
			if Unit.getPlayerName(e.target)~=nil then
				TargPlayer = Unit.getPlayerName(e.target)
			else
				TargPlayer = "AI"
			end
		end
	end
	
	--Check Category of object
	--If no category
	if not Object.getCategory(e.target) then
		TargID_ = e.target.id_
		TargCoa = SETCoalition[e.target:getCoalition()]
		TargGroupCat = SETGroupCat[e.target:getCategory()]
		TargType = e.target:getTypeName()
	--if Category is UNIT	
	elseif Object.getCategory(e.target) == Object.Category.UNIT then
		local TargGroup = e.target:getGroup()
		TargID_ = e.target.id_
		TargCoa = SETCoalition[TargGroup:getCoalition()]
		TargGroupCat = SETGroupCat[TargGroup:getCategory() + 1]
		TargType = e.target:getTypeName()
	--if Category is STATIC
	elseif  Object.getCategory(e.target) == Object.Category.STATIC then
		TargID_ = e.target.id_
		TargCoa = SETCoalition[e.target:getCoalition()]
		TargGroupCat = SETGroupCat[e.target:getCategory()]
		TargType = e.target:getTypeName()
	end
else
	TargID_ = "No target"
	TargCoa = "No target"
	TargGroupCat = "No target"
	TargType = "No target"
	TargPlayer = "No target"
end


--write events to table
if e.id == world.event.S_EVENT_HIT 
or e.id == world.event.S_EVENT_SHOT
or e.id == world.event.S_EVENT_EJECTION
or e.id == world.event.S_EVENT_BIRTH
or e.id == world.event.S_EVENT_CRASH
or e.id == world.event.S_EVENT_DEAD
or e.id == world.event.S_EVENT_PILOT_DEAD
or e.id == world.event.S_EVENT_LAND
or e.id == world.event.S_EVENT_TAKEOFF
or e.id == world.event.S_EVENT_PLAYER_LEAVE_UNIT then
	local stime = SecondsToClock(timer.getTime())
	trigger.action.outText("stime="..stime.." WorldEvent="..WorldEvent.." InitID_="..InitID_.." InitCoa="..InitCoa.." InitGroupCat="..InitGroupCat.." InitType="..InitType.." InitPlayer="..InitPlayer.." eWeaponCat="..eWeaponCat.." eWeaponName="..eWeaponName.." TargID_="..TargID_.." TargCoa="..TargCoa.." TargGroupCat="..TargGroupCat.." TargType="..TargType.." TargPlayer="..TargPlayer, 20)
	local http = require("socket.http")
	local ltn12 = require("ltn12")
	local request_body = "stime="..stime.."&WorldEvent="..WorldEvent.."&InitID_="..InitID_.."&InitCoa="..InitCoa.."&InitGroupCat="..InitGroupCat.."&InitType="..InitType.."&InitPlayer="..InitPlayer.."&eWeaponCat="..eWeaponCat.."&eWeaponName="..eWeaponName.."&TargID_="..TargID_.."&TargCoa="..TargCoa.."&TargGroupCat="..TargGroupCat.."&TargType="..TargType.."&TargPlayer="..TargPlayer
	local response_body = {}
	local res, code, response_headers = http.request{
	  url = "http://httpbin.org/post",
	  method = "POST", 
	  headers = 
	  {
		["Content-Type"] = "application/x-www-form-urlencoded";
		["Content-Length"] = #request_body;
	  },
	  source = ltn12.source.string(request_body),
	  sink = ltn12.sink.table(response_body),
	}
	trigger.action.outText("res="..res.." code="..code, 10)
	if type(response_headers) == "table" then
	  for k, v in pairs(response_headers) do 
		trigger.action.outText("k="..k.." v="..v, 10)
	  end
	end
	trigger.action.outText("Response body: ", 10)
	if type(response_body) == "table" then
	  trigger.action.outText(table.concat(response_body), 10)
	else
	  trigger.action.outText("Not a table: "..type(response_body), 10)
	end	
	statEventsTable[#statEventsTable + 1] = 
	{
		[1] = stime,
		[2] = WorldEvent,
		[3] = InitID_,
		[4] = InitCoa,
		[5] = InitGroupCat,
		[6] = InitType,
		[7] = InitPlayer,
		[8] = eWeaponCat,
		[9] = eWeaponName,
		[10] = TargID_,
		[11] = TargCoa,
		[12] = TargGroupCat,
		[13] = TargType,
		[14] = TargPlayer,
	}
end
end

world.addEventHandler(eStatHandler)

Screenshot_1.png.0b37485190f840c3fba0cfe9ec6a6905.png


Edited by SilentSierra

CPU: AMD Ryzen 7 7800X3D MOBO: Asus ROG STRIX B650E-E MEM: Kingston FURY Renegade 64GB DDR5 5200MHz SSD: Kingstone Fury Renegade NVME PCIe 4.0 M.2 SSD 4TB GPU: ASUS ROG STRIX RTX 4090 OC CASE: Cooler Master TD500 Mesh WATER COOLER: Cooler Master Master Liquid ML360 Illusion HT: TrackIR 5 VR: HP Reverb G2 V2 HOTAS: TM HOTAS Warthog RUDDER: TPR Rudder Pedals GRIP: TM F/A-18C GRIP WHEELS: Logitech G27 OS: Win 11 Pro SIMS: DCS World, Falcon BMS, IL-2 Sturmovik, MSFS2020, Arma 3, Assetto Corsa.

Link to comment
Share on other sites

You have to modify install/Scripts/MissionScripting.lua so that it doesn't sanitize certain lua functionality. In this instance add -- in front of require = nil. Also if you need any io, lfs, or os functions.

The right man in the wrong place makes all the difference in the world.

Current Projects:  Grayflag ServerScripting Wiki

Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread)

 SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum

Link to comment
Share on other sites

You have to modify install/Scripts/MissionScripting.lua so that it doesn't sanitize certain lua functionality. In this instance add -- in front of require = nil. Also if you need any io, lfs, or os functions.

 

I thought I could work with the Lua libraries. I would not want to change the default scripts.

CPU: AMD Ryzen 7 7800X3D MOBO: Asus ROG STRIX B650E-E MEM: Kingston FURY Renegade 64GB DDR5 5200MHz SSD: Kingstone Fury Renegade NVME PCIe 4.0 M.2 SSD 4TB GPU: ASUS ROG STRIX RTX 4090 OC CASE: Cooler Master TD500 Mesh WATER COOLER: Cooler Master Master Liquid ML360 Illusion HT: TrackIR 5 VR: HP Reverb G2 V2 HOTAS: TM HOTAS Warthog RUDDER: TPR Rudder Pedals GRIP: TM F/A-18C GRIP WHEELS: Logitech G27 OS: Win 11 Pro SIMS: DCS World, Falcon BMS, IL-2 Sturmovik, MSFS2020, Arma 3, Assetto Corsa.

Link to comment
Share on other sites

  • 5 months later...
  • 6 months later...
I know xcom doesnt do any work on this anymore, but is there a walk through on how to get this working anywhere?

 

 

Maybe Grimes can help us out a bit. Just need to know the basics of capturing and exporting data such as flight hours per airframe flown. Other thing is how to impliment in WordPress. The search for knowledge continues.

Midnite Signature.jpg

552334314_MidniteSignature.jpg.7c1678ea5639bd6d044b092eb97c300e.jpg

Link to comment
Share on other sites

Well you can either use the scripting engine to get events like above or use onGameEvent callback in the gameGUI API. As for actually tracking flight hours you have the choice of checking at a set rate and just adding time to a player's stat or comparing the time between take-off and flight ending events like dead, crash, eject, or landing. Slmod uses the former as using events is an imperfect system due to server crashing and not having an end event, air spawns, and lack of event for players joining multicrew aircraft.

 

No thoughts on how to display the stats on a website. Its been a long time since I've done anything for websites.

The right man in the wrong place makes all the difference in the world.

Current Projects:  Grayflag ServerScripting Wiki

Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread)

 SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum

Link to comment
Share on other sites

  • 7 months later...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...