vscript additions and fixes 2 - #80

Merged
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23
Dec 27, 2020
Merged

vscript additions and fixes 2#80
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23

Conversation

@samisalreadytaken

@samisalreadytakensamisalreadytaken commented Dec 25, 2020

Copy link
Copy Markdown

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()){functionstart(){player.SetThink(function(){localpos= Entities.FindByClassname(null,"npc_rollermine").GetOrigin()
QueryScreenPos(pos)returninterval_per_tick},0)}function QueryScreenPos(pos){NetMsg.Start("EntityPos")
NetMsg.WriteVec3Coord(pos)
NetMsg.Send(player,true)}NetMsg.Recieve("ScreenPos",function(ply){localbFacing= NetMsg.ReadBool()
if ( bFacing ){localx=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(){localpos= NetMsg.ReadVec3Coord()localbFacing=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()){functionCallClientsideFunction(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

Blixibon commented Dec 26, 2020

Copy link
Copy Markdown
Member

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:developDec 27, 2020
@samisalreadytaken
samisalreadytaken deleted the _23 branch March 7, 2021 15:45
VDeltaGabriel pushed a commit to Project-P2009/p2009_sdk that referenced this pull request Apr 27, 2023
Sign up for freeto 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

@samisalreadytaken@Blixibon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

vscript additions and fixes 2 - #80

Merged
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23
Dec 27, 2020
Merged

vscript additions and fixes 2#80
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23

Conversation

@samisalreadytaken

@samisalreadytakensamisalreadytaken commented Dec 25, 2020

Copy link
Copy Markdown

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()){functionstart(){player.SetThink(function(){localpos= Entities.FindByClassname(null,"npc_rollermine").GetOrigin()
QueryScreenPos(pos)returninterval_per_tick},0)}function QueryScreenPos(pos){NetMsg.Start("EntityPos")
NetMsg.WriteVec3Coord(pos)
NetMsg.Send(player,true)}NetMsg.Recieve("ScreenPos",function(ply){localbFacing= NetMsg.ReadBool()
if ( bFacing ){localx=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(){localpos= NetMsg.ReadVec3Coord()localbFacing=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()){functionCallClientsideFunction(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

Blixibon commented Dec 26, 2020

Copy link
Copy Markdown
Member

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:developDec 27, 2020
@samisalreadytaken
samisalreadytaken deleted the _23 branch March 7, 2021 15:45
VDeltaGabriel pushed a commit to Project-P2009/p2009_sdk that referenced this pull request Apr 27, 2023
Sign up for freeto 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

@samisalreadytaken@Blixibon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

vscript additions and fixes 2 - #80

Merged
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23
Dec 27, 2020
Merged

vscript additions and fixes 2#80
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23

Conversation

@samisalreadytaken

@samisalreadytakensamisalreadytaken commented Dec 25, 2020

Copy link
Copy Markdown

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()){functionstart(){player.SetThink(function(){localpos= Entities.FindByClassname(null,"npc_rollermine").GetOrigin()
QueryScreenPos(pos)returninterval_per_tick},0)}function QueryScreenPos(pos){NetMsg.Start("EntityPos")
NetMsg.WriteVec3Coord(pos)
NetMsg.Send(player,true)}NetMsg.Recieve("ScreenPos",function(ply){localbFacing= NetMsg.ReadBool()
if ( bFacing ){localx=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(){localpos= NetMsg.ReadVec3Coord()localbFacing=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()){functionCallClientsideFunction(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

Blixibon commented Dec 26, 2020

Copy link
Copy Markdown
Member

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:developDec 27, 2020
@samisalreadytaken
samisalreadytaken deleted the _23 branch March 7, 2021 15:45
VDeltaGabriel pushed a commit to Project-P2009/p2009_sdk that referenced this pull request Apr 27, 2023
Sign up for freeto 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

@samisalreadytaken@Blixibon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

vscript additions and fixes 2 - #80

Merged
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23
Dec 27, 2020
Merged

vscript additions and fixes 2#80
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23

Conversation

@samisalreadytaken

@samisalreadytakensamisalreadytaken commented Dec 25, 2020

Copy link
Copy Markdown

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()){functionstart(){player.SetThink(function(){localpos= Entities.FindByClassname(null,"npc_rollermine").GetOrigin()
QueryScreenPos(pos)returninterval_per_tick},0)}function QueryScreenPos(pos){NetMsg.Start("EntityPos")
NetMsg.WriteVec3Coord(pos)
NetMsg.Send(player,true)}NetMsg.Recieve("ScreenPos",function(ply){localbFacing= NetMsg.ReadBool()
if ( bFacing ){localx=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(){localpos= NetMsg.ReadVec3Coord()localbFacing=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()){functionCallClientsideFunction(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

Blixibon commented Dec 26, 2020

Copy link
Copy Markdown
Member

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:developDec 27, 2020
@samisalreadytaken
samisalreadytaken deleted the _23 branch March 7, 2021 15:45
VDeltaGabriel pushed a commit to Project-P2009/p2009_sdk that referenced this pull request Apr 27, 2023
Sign up for freeto 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

@samisalreadytaken@Blixibon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

vscript additions and fixes 2 - #80

Merged
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23
Dec 27, 2020
Merged

vscript additions and fixes 2#80
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23

Conversation

@samisalreadytaken

@samisalreadytakensamisalreadytaken commented Dec 25, 2020

Copy link
Copy Markdown

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()){functionstart(){player.SetThink(function(){localpos= Entities.FindByClassname(null,"npc_rollermine").GetOrigin()
QueryScreenPos(pos)returninterval_per_tick},0)}function QueryScreenPos(pos){NetMsg.Start("EntityPos")
NetMsg.WriteVec3Coord(pos)
NetMsg.Send(player,true)}NetMsg.Recieve("ScreenPos",function(ply){localbFacing= NetMsg.ReadBool()
if ( bFacing ){localx=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(){localpos= NetMsg.ReadVec3Coord()localbFacing=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()){functionCallClientsideFunction(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

Blixibon commented Dec 26, 2020

Copy link
Copy Markdown
Member

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:developDec 27, 2020
@samisalreadytaken
samisalreadytaken deleted the _23 branch March 7, 2021 15:45
VDeltaGabriel pushed a commit to Project-P2009/p2009_sdk that referenced this pull request Apr 27, 2023
Sign up for freeto 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

@samisalreadytaken@Blixibon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

vscript additions and fixes 2 - #80

Merged
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23
Dec 27, 2020
Merged

vscript additions and fixes 2#80
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23

Conversation

@samisalreadytaken

@samisalreadytakensamisalreadytaken commented Dec 25, 2020

Copy link
Copy Markdown

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()){functionstart(){player.SetThink(function(){localpos= Entities.FindByClassname(null,"npc_rollermine").GetOrigin()
QueryScreenPos(pos)returninterval_per_tick},0)}function QueryScreenPos(pos){NetMsg.Start("EntityPos")
NetMsg.WriteVec3Coord(pos)
NetMsg.Send(player,true)}NetMsg.Recieve("ScreenPos",function(ply){localbFacing= NetMsg.ReadBool()
if ( bFacing ){localx=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(){localpos= NetMsg.ReadVec3Coord()localbFacing=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()){functionCallClientsideFunction(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

Blixibon commented Dec 26, 2020

Copy link
Copy Markdown
Member

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:developDec 27, 2020
@samisalreadytaken
samisalreadytaken deleted the _23 branch March 7, 2021 15:45
VDeltaGabriel pushed a commit to Project-P2009/p2009_sdk that referenced this pull request Apr 27, 2023
Sign up for freeto 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

@samisalreadytaken@Blixibon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

vscript additions and fixes 2 - #80

Merged
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23
Dec 27, 2020
Merged

vscript additions and fixes 2#80
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23

Conversation

@samisalreadytaken

@samisalreadytakensamisalreadytaken commented Dec 25, 2020

Copy link
Copy Markdown

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()){functionstart(){player.SetThink(function(){localpos= Entities.FindByClassname(null,"npc_rollermine").GetOrigin()
QueryScreenPos(pos)returninterval_per_tick},0)}function QueryScreenPos(pos){NetMsg.Start("EntityPos")
NetMsg.WriteVec3Coord(pos)
NetMsg.Send(player,true)}NetMsg.Recieve("ScreenPos",function(ply){localbFacing= NetMsg.ReadBool()
if ( bFacing ){localx=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(){localpos= NetMsg.ReadVec3Coord()localbFacing=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()){functionCallClientsideFunction(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

Blixibon commented Dec 26, 2020

Copy link
Copy Markdown
Member

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:developDec 27, 2020
@samisalreadytaken
samisalreadytaken deleted the _23 branch March 7, 2021 15:45
VDeltaGabriel pushed a commit to Project-P2009/p2009_sdk that referenced this pull request Apr 27, 2023
Sign up for freeto 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

@samisalreadytaken@Blixibon
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

vscript additions and fixes 2 - #80

Merged
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23
Dec 27, 2020
Merged

vscript additions and fixes 2#80
Blixibon merged 1 commit into
mapbase-source:developfrom
samisalreadytaken:_23

Conversation

@samisalreadytaken

@samisalreadytakensamisalreadytaken commented Dec 25, 2020

Copy link
Copy Markdown

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()){functionstart(){player.SetThink(function(){localpos= Entities.FindByClassname(null,"npc_rollermine").GetOrigin()
QueryScreenPos(pos)returninterval_per_tick},0)}function QueryScreenPos(pos){NetMsg.Start("EntityPos")
NetMsg.WriteVec3Coord(pos)
NetMsg.Send(player,true)}NetMsg.Recieve("ScreenPos",function(ply){localbFacing= NetMsg.ReadBool()
if ( bFacing ){localx=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(){localpos= NetMsg.ReadVec3Coord()localbFacing=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()){functionCallClientsideFunction(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

Blixibon commented Dec 26, 2020

Copy link
Copy Markdown
Member

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:developDec 27, 2020
@samisalreadytaken
samisalreadytaken deleted the _23 branch March 7, 2021 15:45
VDeltaGabriel pushed a commit to Project-P2009/p2009_sdk that referenced this pull request Apr 27, 2023
Sign up for freeto 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

@samisalreadytaken@Blixibon