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: Intel Core i5 4670k MOBO: Asus Z87-k MEM: Corsair Vegeance 16GB DDR3 1600MHz GPU: Gigabyte GTX 1070 G1 Gaming HT: TrackIR 5 HOTAS: TM HOTAS Warthog RUDDER: T.Flight Rudder Pedals WHEELS: Logitech G27 OS: Win 10 Pro SIMS: DCS World, Falcon BMS, IL-2 Sturmovik: BOS BOM BOK BOB, Arma 3, Assetto Corsa

Link to post
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: Scripting Wiki, Something...

Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread), SLMOD, IADScript, Mission Editing Wiki!, Mission Building Forum

Link to post
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: Intel Core i5 4670k MOBO: Asus Z87-k MEM: Corsair Vegeance 16GB DDR3 1600MHz GPU: Gigabyte GTX 1070 G1 Gaming HT: TrackIR 5 HOTAS: TM HOTAS Warthog RUDDER: T.Flight Rudder Pedals WHEELS: Logitech G27 OS: Win 10 Pro SIMS: DCS World, Falcon BMS, IL-2 Sturmovik: BOS BOM BOK BOB, Arma 3, Assetto Corsa

Link to post
Share on other sites
  • 5 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?

-System Specs are:

 

CPU: i9-9900K @ 4.9Ghz

M/B: Asus TUF z390 Gaming Plus

RAM: 32GB

Video Card: EVGA RTX 2080 Ti XC Hybrid Gaming (11G-P4-2384)

VR: Oculus Rift S

Controls: Warthog Stick & Throttle, TPR pedals, Streamdeck XL

Link to post
Share on other sites
  • 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 post
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: Scripting Wiki, Something...

Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread), SLMOD, IADScript, Mission Editing Wiki!, Mission Building Forum

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...