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

vscript additions and fixes 2 #80

Merged
merged 1 commit into from
Dec 27, 2020

Conversation

samisalreadytaken
Copy link

@samisalreadytaken samisalreadytaken commented Dec 25, 2020

This PR mainly fully implements CNetMsgScriptHelper for custom network message communication, but also adds clientside debugoverlay (that I had planned to include previously but forgot about), CBaseEntity::SetContextThink for more complex thinking from script, fixes user script execution order and clientside player script instance registration, moves all documentation under the __Documentation namespace from global scope, and some misc improvements.


A (not necessarily good) example of server to client, then client to server messaging below. The server queries the screen position of a world vector, client responds with the screen position to server to draw on client's screen with debugoverlay. This example simulates the debugoverlay.EntityTextAtPosition functionality using ScreenText.

if ( IsServer() )
{
	function start()
	{
		player.SetThink( function()
		{
			local pos = Entities.FindByClassname( null, "npc_rollermine" ).GetOrigin()

			QueryScreenPos( pos )

			return interval_per_tick
		}, 0 )
	}

	function QueryScreenPos( pos )
	{
		NetMsg.Start( "EntityPos" )
			NetMsg.WriteVec3Coord( pos )
		NetMsg.Send( player, true )
	}

	NetMsg.Recieve( "ScreenPos", function(ply)
	{
		local bFacing = NetMsg.ReadBool()

		if ( bFacing )
		{
			local x = NetMsg.ReadNormal()
			local y = NetMsg.ReadNormal()

			debugoverlay.ScreenText( x, y, "O", 0,255,0,255, interval_per_tick + 0.25 )
		}
		else
		{
			debugoverlay.ScreenText( 0.5, 0.5, "NOT FACING", 255,0,0,255, interval_per_tick * 2 )
		}
	} )
}

if ( IsClient() )
{
	local m_ScreenXY = [0,0]

	NetMsg.Recieve( "EntityPos", function()
	{
		local pos = NetMsg.ReadVec3Coord()
		local bFacing = ScreenTransform( pos, m_ScreenXY )

		local x = m_ScreenXY[0]
		local y = m_ScreenXY[1]

		NetMsg.Start( "ScreenPos" )

			NetMsg.WriteBool( bFacing )

			if ( bFacing )
			{
				NetMsg.WriteNormal( x )
				NetMsg.WriteNormal( y )
			}

		NetMsg.Send()
	} )
}

Or simply call a clientside function

if ( IsServer() )
{
	function CallClientsideFunction( ply )
	{
		NetMsg.Start( "CallFunction1" )
		NetMsg.Send( ply, true )
	}
}

if ( IsClient() )
{
	NetMsg.Recieve( "CallFunction1", MyFunction1 )
}

The security of this communication in multiplayer depends all on the user. Clients cannot execute arbitrary code on server, and the sender is passed to the reciver function so the user can check if the client has permissions to run whatever to run.


The logic of script context thinking differs from Source 2. In Source 2, the execution order of added think functions are not serial, and change depending on the context name; in my implementation it follows the added order.

For example executing the snippet below in Source 2 will print "231", while here it is "123"

player.SetContextThink( "1aaa", function(self) { print(1) }, 0 )
player.SetContextThink( "2",    function(self) { print(2) }, 0 )
player.SetContextThink( "3",    function(self) { print(3) }, 0 )

Passing null instead of a closure stops thinking.

CBaseEntity::SetThink now internally executes SetContextThink with an empty context.


IScriptVM::Get/Set/ClearValue additions are something Valve should have already implemented. They allow accession of any type as table keys instead of just strings, and also allow script array modification.


With the addition of hash maps for the save/restore tables and event listeners, I removed the context length limit as the strings are no longer allocated. Event lookup on WriteEventData should also now be much faster.

PR Checklist

  • My PR follows all guidelines in the CONTRIBUTING.md file
  • My PR targets a develop branch OR targets another branch with a specific goal in mind

@Blixibon
Copy link
Member

Blixibon commented Dec 26, 2020

This PR is very timely considering the recent work towards client-side VScript applications (including the in-progress #78). I was already wondering how data and events could be conventionally transmitted between the server/client for VScript purposes, but CNetMsgScriptHelper's new custom user message functionality seems to solve that problem completely. I could already see it being one of the most vital tools for client-side VScript in the future.


I had already noticed the player instance was missing from client-side VScript during my experiments and I was also planning on investigating any potential overhead from the ever-increasing documentation, so thank you for working towards the other misc. improvements and optimizations.


I also greatly appreciate the fact this corrects a few of my own mistakes and typos from prior updates. I especially apologize if I mis-attributed the origins of some of your work when I transferred some of it to vscript_singletons.cpp.

Thank you very much for your continued contributions to Mapbase's implementation of VScript. I'll test this on my end later and merge it if I think it's ready.

vscript_client.cpp
   - Fixed local player script instance registration
   - Added CEntities::GetLocalPlayer
   - Added Con_IsVisible
   - Added IsWindowedMode
   - Added ScreenWidth
   - Added ScreenHeight
   - Added ScreenTransform
   - Added missing DoUniqueString

gameinterface.cpp
usercmd.h
usercmd.cpp
vscript_singletons.cpp
   - CNetMsgScriptHelper

vscript_singletons.cpp
   - Added hash map for CScriptSaveRestoreUtil
   - Added hash map for CScriptGameEventListener::s_GameEvents
   - Changed CScriptGameEventListener string contexts to hashes
   - Added invalid input condition on CScriptGameEventListener::ListenToGameEvent
   - Moved CDebugOverlayScriptHelper to shared code

ivscript.h
vscript_squirrel.cpp
   - Added IScriptVM::Get/Set/ClearValue (ScriptVariant_t key)

baseentity.h
baseentity.cpp
   - Added CBaseEntity::SetContextThink (ScriptSetContextThink)

vscript_server.cpp
vscript_client.cpp
vscript_funcs_shared.cpp
   - Changed the order user vscript_*.nut files are executed - after internal scripts, before mapspawn

vscript_squirrel.cpp
vscript_squirrel.nut
vscript_server.nut
vscript_shared.cpp
   - Localised all documentation under __Documentation

hl2_usermessages.cpp
   - Added usermessage ScriptMsg

c_baseplayer.cpp
   - Removed redundant check in ~C_BasePlayer
reductor added a commit to reductor/source-sdk-2013 that referenced this pull request Dec 27, 2020
@Blixibon Blixibon merged commit e55bfa0 into mapbase-source:develop Dec 27, 2020
VDeltaGabriel pushed a commit to Project-P2009/p2009_sdk that referenced this pull request Apr 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants