Jump to content

LUA hooks


Good Ol 73

Recommended Posts

Hi! I’ve gotten as far as creating a lua file in the hooks directory, a check to see if it’s a server and multiplayer and a callback which responds to onplayerconnect etc.

How can I make it so that the player receives a message or a text output (trigger.action.outText didn’t work) upon connecting or changing slots etc?

Thanks.


Edited by Good Ol 73
Error in text. Probably still wrong.
Link to comment
Share on other sites

Try net.send_chat_to(message, player_id)
 

  • Like 1

I created and maintain Operation Candyland, a DCS Open Beta server. Since 2019, Operation Candyland has been one of the best persistent campaigns running on DCS. Featuring ALL modern US and Russian Air, Ground, and Sea forces dynamically controlled by a standalone AI controller. At any given time, there are over 500 units on the map without any lag or desync due to the standalone nature of the system. Experience one of the best multiday campaign experiences in DCS either solo or with a group of other pilots. Both new and veteran DCS pilots will find Operation Candyland a refreshing challenge where no two campaigns are ever the same. Challenge yourself by reaching the top of a custom scoreboard which grades you based on your sortie performance and experience a custom F10 fog of war system which reveals units based on your coalition's current level of command and control. Rescue downed friendly pilots or captured downed enemy pilots in order to extract valuable intel to progress the mission. Learn more at: https://discord.gg/operation-candyland

Link to comment
Share on other sites

Yes the above will work, it will print to the players local chat box. I think (not 100%) that if you require the gameMessages module there might be some screen print methods in there that print in the top left or the screen, similar to AWACs, but dont recall if they can be client specific.


Edited by PravusJSB

Creator & Developer of XSAF ::An AI model that wants to kill you, and needs no help from humans.

Discord: PravusJSB#9484   twitch.tv/pravusjsb  https://www.patreon.com/XSAF  https://discord.gg/pC9EBe8vWU https://bmc.link/johnsbeaslu

Work with me on Fiverr: https://www.fiverr.com/pravusjsb

Link to comment
Share on other sites

2 hours ago, Good Ol 73 said:

Hi! I’ve gotten as far as creating a lua file in the hooks directory, a check to see if it’s a server and multiplayer and a callback which responds to onplayerconnect etc.

How can I make it so that the player receives a message or a text output (trigger.action.outText didn’t work) upon connecting or changing slots etc?

Thanks.

 

Is there a tutorial or any documentation on what you can do by putting a script in there and what you can get access to? 

Link to comment
Share on other sites

Like this:

local topRightMessage = "trigger.action.outTextForGroup(" .. groupIdNumber .. ",'" .. message .. "'," .. howManySecondsToDisplayNumber .. "); "
net.dostring_in('server', topRightMessage)

  • Like 1

I created and maintain Operation Candyland, a DCS Open Beta server. Since 2019, Operation Candyland has been one of the best persistent campaigns running on DCS. Featuring ALL modern US and Russian Air, Ground, and Sea forces dynamically controlled by a standalone AI controller. At any given time, there are over 500 units on the map without any lag or desync due to the standalone nature of the system. Experience one of the best multiday campaign experiences in DCS either solo or with a group of other pilots. Both new and veteran DCS pilots will find Operation Candyland a refreshing challenge where no two campaigns are ever the same. Challenge yourself by reaching the top of a custom scoreboard which grades you based on your sortie performance and experience a custom F10 fog of war system which reveals units based on your coalition's current level of command and control. Rescue downed friendly pilots or captured downed enemy pilots in order to extract valuable intel to progress the mission. Learn more at: https://discord.gg/operation-candyland

Link to comment
Share on other sites

1 hour ago, xcandiottix said:

Like this:

local topRightMessage = "trigger.action.outTextForGroup(" .. groupIdNumber .. ",'" .. message .. "'," .. howManySecondsToDisplayNumber .. "); "
net.dostring_in('server', topRightMessage)

Isn't that something you can just do in a normal script you load in a .miz file? 

What's so special about the Hooks directory?

Link to comment
Share on other sites

5 hours ago, Elphaba said:

Isn't that something you can just do in a normal script you load in a .miz file? 

What's so special about the Hooks directory?

The hooks are loaded when the server is started and will be there for all missions. Doing the DCS.isServer() or DCS.isMultiplayer() checks doesn't work in the mission.

On the other hand trigger.action.outText() doesn't work in hooks, just in missions.

Link to comment
Share on other sites

9 hours ago, Good Ol 73 said:

Hi! I’ve gotten as far as creating a lua file in the hooks directory, a check to see if it’s a server and multiplayer and a callback which responds to onplayerconnect etc.

How can I make it so that the player receives a message or a text output (trigger.action.outText didn’t work) upon connecting or changing slots etc?

Thanks.

 

net.send_chat_to is the simplest way.

and capture the event onPlayerConnect and onPlayerChangeSlot  in net hooks.

Unless there is something else you need to achieve , the solution to your problem is nothing special. It is there and easy. 

 

  • Like 1
Link to comment
Share on other sites

Thanks all... I ended up with the code below. Not really useful but I am mostly trying to learn my way around LUA and DCS.

Now I got to figure out how to check the ucid against a list of known ucid's that I fly with.


local xifyCall = {}
	
	function xifyCall.onPlayerTryChangeSlot(playerId, side, slotId)
		local playerName = net.get_player_info(playerId, 'name')
		net.log(" ---------------- Player Changed Slot: " .. playerName)
		
		local ucid = net.get_player_info(playerId, 'ucid')
		
		if ucid == "af445aca07f1c28e40275b40c79c8f3d" then
			net.log(" ---------------- A familiar face is visiting.")
			
			local text = string.format("return trigger.action.outText(\"Welcome LT COL %s\", 60);", playerName)
			net.dostring_in('server', text)
			
			local message = string.format("Welcome LT COL %s", playerName)
			net.send_chat_to(message, playerId)
		end
	
	end

	function xifyCall.onPlayerConnect(playerId)
		local ucid = net.get_player_info(playerId, 'ucid')
		local playerName = net.get_player_info(playerId, 'name')
		net.log("---------------- Player " .. playerName .. " Connected: " .. ucid)
	end
		
DCS.setUserCallbacks(xifyCall)

 

19 hours ago, Elphaba said:

Is there a tutorial or any documentation on what you can do by putting a script in there and what you can get access to? 

https://wiki.hoggitworld.com/view/Category:DCS_Hooks

But it's not really beginner friendly IMO.

Link to comment
Share on other sites

In Lua, the fastest way to check if something exists is a nil check. Keep in mind people can change their user name so consider keying off the player's UCID. Be careful about what you do during the "onPlayerTryChangeSlot" event as you can accidentally prevent slot changing or break multi-slot aircraft compatibility. Recommend trying this:

 

local ucid = net.get_player_info(player_id, 'ucid')
local regulars = {}
regular['tbe94jfjvkskkckvfjjr995olpsnm9'] = "me" --This value isn't for anything other than keeping track of who is who
regular['nnght738h3u38ur2828ru29ru982uw'] = "John Doe" --This value isn't for anything other than keeping track of who is who
regular['777h73h7fh3f7q7fh7er7eh7hhhhee'] = "Jane Doe" --This value isn't for anything other than keeping track of who is who

If(regular[ucid] == nil) then
	--Some new user, log their UCID in case you want to add them to the regular list
elseif(regular[ucid] ~= nil) then
	--Some known user
else
	--some error
end

 


Edited by xcandiottix
  • Like 1

I created and maintain Operation Candyland, a DCS Open Beta server. Since 2019, Operation Candyland has been one of the best persistent campaigns running on DCS. Featuring ALL modern US and Russian Air, Ground, and Sea forces dynamically controlled by a standalone AI controller. At any given time, there are over 500 units on the map without any lag or desync due to the standalone nature of the system. Experience one of the best multiday campaign experiences in DCS either solo or with a group of other pilots. Both new and veteran DCS pilots will find Operation Candyland a refreshing challenge where no two campaigns are ever the same. Challenge yourself by reaching the top of a custom scoreboard which grades you based on your sortie performance and experience a custom F10 fog of war system which reveals units based on your coalition's current level of command and control. Rescue downed friendly pilots or captured downed enemy pilots in order to extract valuable intel to progress the mission. Learn more at: https://discord.gg/operation-candyland

Link to comment
Share on other sites

Lua is really nice in this regard; I agree with @xcandiottix code in general, and would only offer the following slight simplification:

If(regular[ucid]) then
	--Some known user	
else
	--Some new user, log their UCID in case you want to add them to the regular list
end

 


Edited by cfrag
  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...
On 12/20/2022 at 9:35 PM, Good Ol 73 said:

Hi! I’ve gotten as far as creating a lua file in the hooks directory, a check to see if it’s a server and multiplayer and a callback which responds to onplayerconnect etc.

How can I make it so that the player receives a message or a text output (trigger.action.outText didn’t work) upon connecting or changing slots etc?

Thanks.

 

How do you do the 'require' line for the file in the HOOKS directory? My script can't 'require' it because it's not in the path. 

 

Link to comment
Share on other sites

On 1/4/2023 at 1:50 AM, Elphaba said:

How do you do the 'require' line for the file in the HOOKS directory? My script can't 'require' it because it's not in the path. 

 

You don't. Files in the hooks directory are automatically run when you restart the server. I.e. if you have bugs you need to restart the whole server 😕

Link to comment
Share on other sites

1 hour ago, Good Ol 73 said:

You don't. Files in the hooks directory are automatically run when you restart the server. I.e. if you have bugs you need to restart the whole server 😕

So they're in the same 'protected sandbox' that my regular script is running in? So I can address a function in the HOOK.lua file directly?

e.g. 

HOOK_FILE = {}

function HOOK_FILE:PrintX()

end





MYSCRIPT = {}

function MYSCRIPT:PrintXViaHookFile()

  HOOK_FILE:PrintX()

end

Like that? No Require? No LUA_PATH or anything?

Link to comment
Share on other sites

On 1/4/2023 at 2:50 AM, Elphaba said:

How do you do the 'require' line for the file in the HOOKS directory? My script can't 'require' it because it's not in the path. 

 

Before you can do require you need to de-sanitize the MissionScripting.lua file from DCS game\Scripts folder. Like this:

dofile('Scripts/ScriptingSystem.lua')
 
--Sanitize Mission Scripting environment
--This makes unavailable some unsecure functions.
--Mission downloaded from server to client may contain potentialy harmful lua code that may use these functions.
--You can remove the code below and make availble these functions at your own risk.
 
local function sanitizeModule(name)
    --_G[name] = nil
    --package.loaded[name] = nil
end
 
do
    --sanitizeModule('os')
    --sanitizeModule('io')
    --sanitizeModule('lfs')
    --_G['require'] = nil
    --_G['loadlib'] = nil
    --_G['package'] = nil
end

 

Then you can require anything in hooks or mission files, like this:

local dcsSr=require('lfs')
InccludeDir =dcsSr.writedir() .. "Scripts/Hooks/AnotherLuaFilesFolder/"
 
dofile(InccludeDir .. 'a_file_from_that_folder.lua')

Edited by mirq
Link to comment
Share on other sites

1 hour ago, Good Ol 73 said:

@Elphaba

The regular scripts don’t have access to net functionality, hence I had to use a hook

net.get_player_info(playerId, 'ucid')

If you meaan by regular lua files from miision env, then cand do this net. call. In mission you can only find the playername, not the playerId. Id exists only in GUI. orget about ucid in mission. But you dont need them. You can play exclusively in GUI. You dont need anything fro mission

7 minutes ago, Elphaba said:

There's no way around having to de-sanitise your server?

 

yes there is

I tried with this code. It seems it works. Looks like relative path is good enough. If you dont need acces to io or os libs then you can survive with this. The last resort is to make one single file. But if you need mist, your screwed

MissIncludesDir ="/MissionIncludes/"
dofile(MissIncludesDir .. 'mist_4_4_90.lua')

Edited by mirq
Link to comment
Share on other sites

21 minutes ago, Elphaba said:

There's no way around having to de-sanitise your server?

 

But wait a minute. You are running a server or a client ? I you are making a server than there no risk for you. The risk is on the clients who de-sanitize access to folders and missions from servers run mallicious code on clients. On server you are supposed to be clean. Though I just discovered that clients can run code also, it cant reach the server. Yet

Link to comment
Share on other sites

8 minutes ago, Elphaba said:

Why am I doing 'dofile' on a lua file that's supposed to be in the hooks dir? DCS has already loaded it and it's running. 

My script - loaded in the mission at MISSION START, needs to talk to my script in the hooks directory. 

That's what I'm trying to do. 

Not run it again. 

That will never happen. I did it, as you already know, but in an un-orthodox way. For laymen , that's impossible.

And here is why: iff you mean a lua file from hooks, than I suppose this contains code from net. and DCS. space. These spaces are not accessible in mission env, so if you import those hook ffiles in a mission file, a lot of errors will occur, as net. and DCS. are nil things there. 


Edited by mirq
Link to comment
Share on other sites

But why do you need to run code from mission still ? What is exactly your aim ? I bet it can be solved in GUI only, and you will forget about mission. For example you can spawn AI from GUI hooks, you can destroy AI, everyhing you can do in mission youcan do from GUI hooks. You can send triiger text from GUI, and many more.

So there are two kind of approacehs: 

1. Run code from HOOKS to mission -> that's possible oficially via a_do_script

2. Run code from mission to HOOKS -> that's  imposible oficially, but there are workarounds. Several  

Which one are you up to, and for what purpose ?


Edited by mirq
Link to comment
Share on other sites

  • Recently Browsing   0 members

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