Commit MetaInfo

修订版96d83561db40423b79dde79c637b25a1ea5839a3 (tree)
时间2020-12-27 13:30:30
作者Adam Kaminski <kaminskiadam9@gmai...>
CommiterAdam Kaminski

Log Message

Added ACS functions: SendNetworkString and NamedSendNetworkString, allowing strings to be sent from the server to the client(s) and vice versa, which are passed as the first argument of script to also be executed. Note that sending strings from client to server works just like puking scripts and there's no guarantee they are sent to the server successfully.

更改概述

差异

diff -r 5b59765c5a2b -r 96d83561db40 docs/zandronum-history.txt
--- a/docs/zandronum-history.txt Sat Dec 26 12:36:10 2020 -0500
+++ b/docs/zandronum-history.txt Sat Dec 26 23:30:30 2020 -0500
@@ -30,6 +30,7 @@
3030 + - Added an ACS special to check whether the game is in demo or not [DoomJoshuaBoy/geNia]
3131 + - Added new SBARINFO commands: IfSpectator [not] [dead] and IfSpying [not] that execute a sub block if the local player is (not) a (dead) spectator, or (not) spying on another player respectively. [Kaminsky]
3232 + - Added ACS functions: ExecuteClientScript and NamedExecuteClientScript which let the server execute clientside scripts for only one client as opposed to everyone. This allows net traffic to be greatly optimized, such that the server only sends out commands to the client(s) that matter. [Kaminsky]
33++ - Added ACS functions: SendNetworkString and NamedSendNetworkString, allowing strings to be sent from the server to the client(s) and vice versa, which are passed as the first argument of script to also be executed. Note that sending strings from client to server works just like puking scripts and there's no guarantee they are sent to the server successfully. [Kaminsky]
3334 - - Fixed: Bots tries to jump to reach item when sv_nojump is true. [sleep]
3435 - - Fixed: ACS function SetSkyScrollSpeed didn't work online. [Edward-san]
3536 - - Fixed: color codes in callvote reasons weren't terminated properly. [Dusk]
diff -r 5b59765c5a2b -r 96d83561db40 protocolspec/spec.misc.txt
--- a/protocolspec/spec.misc.txt Sat Dec 26 12:36:10 2020 -0500
+++ b/protocolspec/spec.misc.txt Sat Dec 26 23:30:30 2020 -0500
@@ -11,6 +11,13 @@
1111 Bool always
1212 EndCommand
1313
14+Command ACSSendString
15+ ExtendedCommand
16+ Short netid
17+ Actor activator with NullAllowed
18+ String string
19+EndCommand
20+
1421 Struct JoinSlot
1522 Byte player
1623 Byte team
diff -r 5b59765c5a2b -r 96d83561db40 src/cl_commands.cpp
--- a/src/cl_commands.cpp Sat Dec 26 12:36:10 2020 -0500
+++ b/src/cl_commands.cpp Sat Dec 26 23:30:30 2020 -0500
@@ -672,6 +672,22 @@
672672
673673 //*****************************************************************************
674674 //
675+void CLIENTCOMMANDS_ACSSendString ( int scriptNum, const char *pszString )
676+{
677+ const int scriptNetID = NETWORK_ACSScriptToNetID( scriptNum );
678+
679+ CLIENT_GetLocalBuffer( )->ByteStream.WriteByte( CLC_ACSSENDSTRING );
680+ CLIENT_GetLocalBuffer( )->ByteStream.WriteLong( scriptNetID );
681+
682+ // [AK] If we don't have a netID on file for this script, we send the name as a string.
683+ if ( scriptNetID == NO_SCRIPT_NETID )
684+ CLIENT_GetLocalBuffer( )->ByteStream.WriteString( FName( ENamedName( -scriptNum )));
685+
686+ CLIENT_GetLocalBuffer( )->ByteStream.WriteString( pszString );
687+}
688+
689+//*****************************************************************************
690+//
675691 void CLIENTCOMMANDS_MorphCheat ( const char *pszMorphClass )
676692 {
677693 if ( pszMorphClass == NULL )
diff -r 5b59765c5a2b -r 96d83561db40 src/cl_commands.h
--- a/src/cl_commands.h Sat Dec 26 12:36:10 2020 -0500
+++ b/src/cl_commands.h Sat Dec 26 23:30:30 2020 -0500
@@ -107,6 +107,7 @@
107107 void CLIENTCOMMANDS_EnterConsole( void );
108108 void CLIENTCOMMANDS_ExitConsole( void );
109109 void CLIENTCOMMANDS_Puke ( int script, int args[4], bool always );
110+void CLIENTCOMMANDS_ACSSendString( int script, const char* pszString );
110111 void CLIENTCOMMANDS_MorphCheat ( const char *pszMorphClass );
111112 void CLIENTCOMMANDS_FullUpdateReceived ( void );
112113 void CLIENTCOMMANDS_InfoCheat( AActor* mobj, bool extended );
diff -r 5b59765c5a2b -r 96d83561db40 src/cl_main.cpp
--- a/src/cl_main.cpp Sat Dec 26 12:36:10 2020 -0500
+++ b/src/cl_main.cpp Sat Dec 26 23:30:30 2020 -0500
@@ -6706,6 +6706,19 @@
67066706
67076707 //*****************************************************************************
67086708 //
6709+void ServerCommands::ACSSendString::Execute()
6710+{
6711+ // [AK] Resolve the script netid into a script number
6712+ int scriptNum = NETWORK_ACSScriptFromNetID( netid );
6713+
6714+ // [AK] Add the string to the ACS string table.
6715+ int args[4] = { GlobalACSStrings.AddString( string ), 0, 0, 0 };
6716+
6717+ P_StartScript( activator, NULL, scriptNum, NULL, args, 4, ACS_ALWAYS );
6718+}
6719+
6720+//*****************************************************************************
6721+//
67096722 void ServerCommands::Sound::Execute()
67106723 {
67116724 if ( volume > 127 )
diff -r 5b59765c5a2b -r 96d83561db40 src/network_enums.h
--- a/src/network_enums.h Sat Dec 26 12:36:10 2020 -0500
+++ b/src/network_enums.h Sat Dec 26 23:30:30 2020 -0500
@@ -372,6 +372,7 @@
372372 ENUM_ELEMENT ( SVC2_SETLOCALPLAYERJUMPTICS ),
373373 ENUM_ELEMENT ( SVC2_SETPLAYERDEATHS ),
374374 ENUM_ELEMENT ( SVC2_STOPSOUND ),
375+ ENUM_ELEMENT ( SVC2_ACSSENDSTRING ),
375376 // [BB] Commands necessary for the account system.
376377 ENUM_ELEMENT ( SVC2_SRP_USER_START_AUTHENTICATION ),
377378 ENUM_ELEMENT ( SVC2_SRP_USER_PROCESS_CHALLENGE ),
@@ -435,6 +436,7 @@
435436 ENUM_ELEMENT( CLC_EXITCONSOLE ),
436437 ENUM_ELEMENT( CLC_IGNORE ),
437438 ENUM_ELEMENT( CLC_PUKE ),
439+ ENUM_ELEMENT( CLC_ACSSENDSTRING ),
438440 ENUM_ELEMENT( CLC_MORPHEX ),
439441 ENUM_ELEMENT( CLC_FULLUPDATE ),
440442 ENUM_ELEMENT( CLC_INFOCHEAT ),
diff -r 5b59765c5a2b -r 96d83561db40 src/p_acs.cpp
--- a/src/p_acs.cpp Sat Dec 26 12:36:10 2020 -0500
+++ b/src/p_acs.cpp Sat Dec 26 23:30:30 2020 -0500
@@ -1789,6 +1789,84 @@
17891789 return 0;
17901790 }
17911791
1792+// ================================================================================================
1793+//
1794+// [AK] SendNetworkString
1795+//
1796+// Sends a string across the network then executes a script with the string's id as an argument.
1797+//
1798+// ================================================================================================
1799+
1800+static int SendNetworkString ( FBehavior* module, AActor* activator, int script, int index, int client )
1801+{
1802+ const ScriptPtr* scriptdata = FBehavior::StaticFindScript( script, module );
1803+ FString rep = FBehavior::RepresentScript( script );
1804+
1805+ // [AK] Don't execute during demo playback.
1806+ if ( CLIENTDEMO_IsPlaying() )
1807+ return 1;
1808+
1809+ // [AK] If we're in singleplayer, execute the script like normal.
1810+ if (( NETWORK_GetState() == NETSTATE_SINGLE ) || ( NETWORK_GetState() == NETSTATE_SINGLE_MULTIPLAYER ))
1811+ {
1812+ int scriptArgs[4] = { index, 0, 0, 0 };
1813+
1814+ P_StartScript( activator, NULL, script, NULL, scriptArgs, 4, ACS_ALWAYS );
1815+ return 1;
1816+ }
1817+
1818+ // [AK] Don't execute any network commands if the script doesn't exist.
1819+ if ( ACS_ExistsScript( script ) == false )
1820+ {
1821+ Printf( "SendNetworkString: Script %s doesn't exist.\n", rep.GetChars() );
1822+ return 0;
1823+ }
1824+
1825+ const char *string = FBehavior::StaticLookupString( index );
1826+
1827+ // [AK] Don't send empty strings across the network.
1828+ if (( string == NULL ) || ( strlen( string ) < 1 ))
1829+ return 0;
1830+
1831+ if ( NETWORK_GetState() == NETSTATE_CLIENT )
1832+ {
1833+ // [AK] Don't have the client send the string if the script is non-pukable.
1834+ if (( scriptdata->Flags & SCRIPTF_Net ) == 0 )
1835+ {
1836+ Printf( "SendNetworkString: Script %s must be NET but isn't.\n", rep.GetChars() );
1837+ return 0;
1838+ }
1839+
1840+ CLIENTCOMMANDS_ACSSendString( script, string );
1841+ return 1;
1842+ }
1843+
1844+ if ( NETWORK_GetState() == NETSTATE_SERVER )
1845+ {
1846+ // [AK] Don't send the string to a client that doesn't exist.
1847+ if (( client >= 0 ) && ( PLAYER_IsValidPlayer( client ) == false ))
1848+ return 0;
1849+
1850+ // [AK] Don't send the string to the client(s) if the script isn't clientside.
1851+ if ( ACS_IsScriptClientSide( script ) == false )
1852+ {
1853+ Printf( "SendNetworkString: Script %s must be CLIENTSIDE but isn't.\n", rep.GetChars() );
1854+ return 0;
1855+ }
1856+
1857+ // [AK] We want to send the string to all the clients.
1858+ if ( client < 0 )
1859+ SERVERCOMMANDS_ACSSendString( script, activator, string );
1860+ // [AK] Otherwise, we're sending the string to only this client.
1861+ else
1862+ SERVERCOMMANDS_ACSSendString( script, activator, string, client, SVCF_ONLYTHISCLIENT );
1863+
1864+ return 1;
1865+ }
1866+
1867+ return 0;
1868+}
1869+
17921870 //---- Plane watchers ----//
17931871
17941872 class DPlaneWatcher : public DThinker
@@ -5271,6 +5349,8 @@
52715349 ACSF_InDemoMode,
52725350 ACSF_ExecuteClientScript,
52735351 ACSF_NamedExecuteClientScript,
5352+ ACSF_SendNetworkString,
5353+ ACSF_NamedSendNetworkString,
52745354
52755355 // ZDaemon
52765356 ACSF_GetTeamScore = 19620, // (int team)
@@ -7521,6 +7601,20 @@
75217601 return ExecuteClientScript( activator, -scriptName, args[1], &args[2], argCount - 2 );
75227602 }
75237603
7604+ case ACSF_SendNetworkString:
7605+ {
7606+ const int client = argCount > 2 ? args[2] : -1;
7607+ return SendNetworkString( activeBehavior, activator, args[0], args[1], client );
7608+ }
7609+
7610+ case ACSF_NamedSendNetworkString:
7611+ {
7612+ FName scriptName = FBehavior::StaticLookupString( args[0] );
7613+ const int client = argCount > 2 ? args[2] : -1;
7614+
7615+ return SendNetworkString( activeBehavior, activator, -scriptName, args[1], client );
7616+ }
7617+
75247618 case ACSF_GetActorFloorTexture:
75257619 {
75267620 auto a = SingleActorFromTID(args[0], activator);
diff -r 5b59765c5a2b -r 96d83561db40 src/sv_commands.cpp
--- a/src/sv_commands.cpp Sat Dec 26 12:36:10 2020 -0500
+++ b/src/sv_commands.cpp Sat Dec 26 23:30:30 2020 -0500
@@ -3093,6 +3093,30 @@
30933093 }
30943094
30953095 //*****************************************************************************
3096+//
3097+void SERVERCOMMANDS_ACSSendString( int ScriptNum, AActor *pActivator, const char *pszString, ULONG ulPlayerExtra, ServerCommandFlags flags )
3098+{
3099+ int netid = NETWORK_ACSScriptToNetID( ScriptNum );
3100+
3101+ if ( netid == NO_SCRIPT_NETID )
3102+ {
3103+ // [AK] This shouldn't happen.
3104+ if ( sv_showwarnings )
3105+ {
3106+ Printf( "SERVERCOMMANDS_ACSSendString: Failed to find a netid for script %s!\n",
3107+ FName( ENamedName( -ScriptNum )).GetChars() );
3108+ }
3109+ return;
3110+ }
3111+
3112+ ServerCommands::ACSSendString command;
3113+ command.SetNetid( netid );
3114+ command.SetActivator( pActivator );
3115+ command.SetString( pszString );
3116+ command.sendCommandToClients( ulPlayerExtra, flags );
3117+}
3118+
3119+//*****************************************************************************
30963120 //*****************************************************************************
30973121 //
30983122 void SERVERCOMMANDS_SetSideFlags( ULONG ulSide, ULONG ulPlayerExtra, ServerCommandFlags flags )
diff -r 5b59765c5a2b -r 96d83561db40 src/sv_commands.h
--- a/src/sv_commands.h Sat Dec 26 12:36:10 2020 -0500
+++ b/src/sv_commands.h Sat Dec 26 23:30:30 2020 -0500
@@ -305,6 +305,7 @@
305305
306306 // ACS commands. These have something to do with ACS scripts.
307307 void SERVERCOMMANDS_ACSScriptExecute( int ScriptNum, AActor *pActivator, LONG lLineIdx, int levelnum, bool bBackSide, const int *args, int argcount, bool bAlways, ULONG ulPlayerExtra = MAXPLAYERS, ServerCommandFlags flags = 0 );
308+void SERVERCOMMANDS_ACSSendString( int ScriptNum, AActor *pActivator, const char *pszString, ULONG ulPlayerExtra = MAXPLAYERS, ServerCommandFlags flags = 0 );
308309
309310 // Sound commands. These play a sound.
310311 void SERVERCOMMANDS_Sound( LONG lChannel, const char *pszSound, float fVolume, float fAttenuation, ULONG ulPlayerExtra = MAXPLAYERS, ServerCommandFlags flags = 0 );
diff -r 5b59765c5a2b -r 96d83561db40 src/sv_main.cpp
--- a/src/sv_main.cpp Sat Dec 26 12:36:10 2020 -0500
+++ b/src/sv_main.cpp Sat Dec 26 23:30:30 2020 -0500
@@ -170,6 +170,7 @@
170170 static bool server_InventoryUse( BYTESTREAM_s *pByteStream );
171171 static bool server_InventoryDrop( BYTESTREAM_s *pByteStream );
172172 static bool server_Puke( BYTESTREAM_s *pByteStream );
173+static bool server_ReceiveACSString( BYTESTREAM_s *pByteStream );
173174 static bool server_MorphCheat( BYTESTREAM_s *pByteStream );
174175 static bool server_CheckForClientCommandFlood( ULONG ulClient );
175176 static bool server_CheckForClientMinorCommandFlood( ULONG ulClient );
@@ -4638,6 +4639,10 @@
46384639
46394640 // [BB] Client wishes to puke a scipt.
46404641 return ( server_Puke( pByteStream ));
4642+ case CLC_ACSSENDSTRING:
4643+
4644+ // [AK] Client sent us a string through an ACS script.
4645+ return ( server_ReceiveACSString( pByteStream ));
46414646 case CLC_MORPHEX:
46424647
46434648 // [BB] Client wishes to morph to a certain class.
@@ -6593,6 +6598,36 @@
65936598
65946599 //*****************************************************************************
65956600 //
6601+static bool server_ReceiveACSString( BYTESTREAM_s *pByteStream )
6602+{
6603+ const int scriptNetID = pByteStream->ReadLong();
6604+
6605+ // [AK] Resolve the script netid into a script number.
6606+ const int scriptNum = ( scriptNetID != NO_SCRIPT_NETID )
6607+ ? NETWORK_ACSScriptFromNetID ( scriptNetID )
6608+ : -FName( pByteStream->ReadString() );
6609+
6610+ const char *string = pByteStream->ReadString();
6611+
6612+ // [AK] A normal client checks if the script is pukeable and only requests to puke pukeable scripts.
6613+ // Thus if the requested script is not pukeable, the client was tampered with.
6614+ if ( ACS_IsScriptPukeable ( scriptNum ) == false )
6615+ {
6616+ // [AK] Trying to puke a non-pukeable script is treated as possible command flooding.
6617+ if ( server_CheckForClientCommandFlood ( g_lCurrentClient ) == true )
6618+ return ( true );
6619+
6620+ return ( false );
6621+ }
6622+
6623+ int arg[4] = { GlobalACSStrings.AddString ( string ), 0, 0, 0 };
6624+ P_StartScript( players[g_lCurrentClient].mo, NULL, scriptNum, NULL, arg, 4, ACS_ALWAYS | ACS_NET );
6625+
6626+ return ( false );
6627+}
6628+
6629+//*****************************************************************************
6630+//
65966631 static bool server_MorphCheat( BYTESTREAM_s *pByteStream )
65976632 {
65986633 const char *pszMorphClass = pByteStream->ReadString();
Show on old repository browser