Public Functions
ConsoleDocClass(RemoteCommandEvent , "@brief <a href="/coding/file/gizmo_8h/#gizmo_8h_1a10fcd3bee2ea25191e31795e36bdeba1a5df911aaca43421a25e32c3002befbc4">Object</a> used <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> remote procedure <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">calls.\n\n</a>" "Not intended <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> game development, <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> exposing ConsoleFunctions(such as commandToClient) <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" " @internal" )
ConsoleFunctionGroupBegin(Net , "Functions <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> use with the network; tagged strings and remote commands." )
ConsoleFunctionGroupEnd(Net )
DefineEngineFunction(addTaggedString , const char * , (const char *str) , ("") , "@brief Use the addTaggedString function <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> tag <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> string and add it <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">NetStringTable\n\n</a>" "@param str The string <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be tagged and placed in the NetStringTable. Tagging ignores case, " "so tagging the same string(excluding case differences) will be ignored as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> duplicated <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tag.\n\n</a>" " @return Returns <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> string(containing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> numeric <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a>) equivalent <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the string ID <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the newly tagged string" " @see \\ref syntaxDataTypes under Tagged %<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Strings\n</a>" " @see removeTaggedString()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @see getTaggedString()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Networking\n</a>" )
DefineEngineFunction(getTaggedString , const char * , (const char *tag) , ("") , "@brief Use the getTaggedString function <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/colladautils_8h/#colladautils_8h_1a24cd315eae41894b5bbf77c8c0b097d4">convert</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> tag <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">string.\n\n</a>" "This is not the same as detag() which can only be used within the context " "of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> function that receives <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> tag. This function can be used any time and " "anywhere <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/colladautils_8h/#colladautils_8h_1a24cd315eae41894b5bbf77c8c0b097d4">convert</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> tag <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">string.\n\n</a>" "@param tag A numeric tag <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ID.\n</a>" "@returns The string as found in the <a href="/coding/class/structnet/">Net</a> <a href="/coding/class/classstring/">String</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">table.\n</a>" "@see \\ref syntaxDataTypes under Tagged %<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Strings\n</a>" "@see addTaggedString()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see removeTaggedString()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Networking\n</a>" )
DefineEngineFunction(removeTaggedString , void , (S32 tag) , (-1) , "@brief Remove <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> tagged string from the <a href="/coding/class/structnet/">Net</a> <a href="/coding/class/classstring/">String</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Table\n\n</a>" "@param tag The tag associated with the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">string\n\n</a>" "@see \\ref syntaxDataTypes under Tagged %<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Strings\n</a>" "@see addTaggedString()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see getTaggedString()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Networking\n</a>" )
DefineEngineStringlyVariadicFunction(buildTaggedString , const char * , 2 , 11 , "(string format, ...)" "@brief Build <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> string using the specified tagged string <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">format.\n\n</a>" "This function takes an already tagged string (passed in as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> tagged string ID) and one " "or more additional strings. If the tagged string contains argument tags that range from " "%%1 through %% 9, then each additional string will be substituted into the tagged string. " "The final(non-tagged) combined string will be returned. The maximum length of the tagged " "string plus any inserted additional strings is 511 <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">characters.\n\n</a>" " @param format A tagged string ID that contains zero or more argument tags, in the form of " "%%1 through %%9.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @param ... A variable number of arguments that are insterted into the tagged string " "based on the argument tags within the format <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">string.\n</a>" " @returns An ordinary string that is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> combination of the original tagged string with any additional " "strings passed in inserted in place of each argument <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tag.\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//Create <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> tagged string with argument <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tags\n</a>" "% taggedStringID)
DefineEngineStringlyVariadicFunction(commandToClient , void , 3 , RemoteCommandEvent::MaxRemoteCommandArgs+ 2, "(NetConnection client, string func, ...)" "@brief Send <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> command from the server <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">client\n\n</a>" "@param client The numeric ID of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> client <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GameConnection\n</a>" "@param func Name of the client function being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">called\n</a>" "@param ... Various parameters being passed <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> client <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">command\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Set up the client command. Needs <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be executed on the client, such <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">as\n</a>" "//within scripts/client/client." TORQUE_SCRIPT_EXTENSION "\n" "//Update the Ammo Counter with current ammo, <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not any then hide the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">counter.\n</a>" "function clientCmdSetAmmoAmountHud(%amount)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a>(!%amount)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " AmmoAmount.setVisible(false);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">else\n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " AmmoAmount.setVisible(true);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " AmmoAmount.setText(\"Ammo: \"@%amount);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " }\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "// Call it from <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> server function. Needs <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be executed on the server, \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "//such as within scripts/server/game." TORQUE_SCRIPT_EXTENSION "\n" "function GameConnection::setAmmoAmountHud(%client, %amount)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " commandToClient(%client, 'SetAmmoAmountHud', %amount);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Networking\n</a>" )
DefineEngineStringlyVariadicFunction(commandToServer , void , 2 , RemoteCommandEvent::MaxRemoteCommandArgs+ 1, "(string func, ...)" "@brief Send <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> command <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">server.\n\n</a>" "@param func Name of the server command being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">called\n</a>" "@param ... Various parameters being passed <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> server <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">command\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Create <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> standard function. Needs <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be executed on the client, such \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "//as within scripts/client/default.bind." TORQUE_SCRIPT_EXTENSION "\n" "function toggleCamera(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "//If key was down, call <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> server command named 'ToggleCamera'\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a>(%val)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " commandToServer('ToggleCamera');\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "//Server command being called from above. Needs <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be executed on the \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "// server, such as within scripts/server/commands." TORQUE_SCRIPT_EXTENSION "\n" "function serverCmdToggleCamera(%client)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a>(%client.getControlObject()==%client.player)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " %client.camera.setVelocity(\"0 0 0\");\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " %<a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> = %client.camera;\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " }\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">else\n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " %client.player.setVelocity(\"0 0 0\");\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " %<a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> = %client.player;\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " }\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " %client.setControlObject(%<a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a>);\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " clientCmdSyncEditorGui();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "}\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@ingroup Networking" )
IMPLEMENT_CO_NETEVENT_V1(RemoteCommandEvent )
1
2//-----------------------------------------------------------------------------
3// Copyright (c) 2012 GarageGames, LLC
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to
7// deal in the Software without restriction, including without limitation the
8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9// sell copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21// IN THE SOFTWARE.
22//-----------------------------------------------------------------------------
23
24#include "platform/platform.h"
25#include "core/dnet.h"
26#include "core/idGenerator.h"
27#include "core/stream/bitStream.h"
28#include "console/simBase.h"
29#include "console/console.h"
30#include "console/consoleTypes.h"
31#include "sim/netConnection.h"
32#include "sim/netObject.h"
33#include "app/net/serverQuery.h"
34#include "console/engineAPI.h"
35#include <vector>
36#include "net.h"
37//----------------------------------------------------------------
38// remote procedure call console functions
39//----------------------------------------------------------------
40
41
42 RemoteCommandEvent::RemoteCommandEvent(S32 argc, const char **argv, NetConnection *conn)
43 {
44 mArgc = argc;
45 for(S32 i = 0; i < argc; i++)
46 {
47 if(argv[i][0] == StringTagPrefixByte)
48 {
49 char buffer[256];
50 mTagv[i+1] = NetStringHandle(dAtoi(argv[i]+1));
51 if(conn)
52 {
53 dSprintf(buffer + 1, sizeof(buffer) - 1, "%d", conn->getNetSendId(mTagv[i+1]));
54 buffer[0] = StringTagPrefixByte;
55 mArgv[i+1] = dStrdup(buffer);
56 }
57 }
58 else
59 mArgv[i+1] = dStrdup(argv[i]);
60 }
61 }
62
63#ifdef TORQUE_DEBUG_NET
64 const char *RemoteCommandEvent::getDebugName()
65 {
66 static char buffer[256];
67 dSprintf(buffer, sizeof(buffer), "%s [%s]", getClassName(), mTagv[1].isValidString() ? mTagv[1].getString() : "--unknown--" );
68 return buffer;
69 }
70#endif
71
72 RemoteCommandEvent::~RemoteCommandEvent()
73 {
74 for(S32 i = 0; i < mArgc; i++)
75 dFree(mArgv[i+1]);
76 }
77
78 void RemoteCommandEvent::pack(NetConnection* conn, BitStream *bstream)
79 {
80 bstream->writeInt(mArgc, CommandArgsBits);
81 // write it out reversed... why?
82 // automatic string substitution with later arguments -
83 // handled automatically by the system.
84
85 for(S32 i = 0; i < mArgc; i++)
86 conn->packString(bstream, mArgv[i+1]);
87 }
88
89 void RemoteCommandEvent::write(NetConnection* conn, BitStream *bstream)
90 {
91 pack(conn, bstream);
92 }
93
94 void RemoteCommandEvent::unpack(NetConnection* conn, BitStream *bstream)
95 {
96
97 mArgc = bstream->readInt(CommandArgsBits);
98 // read it out backwards
99 for(S32 i = 0; i < mArgc; i++)
100 {
101 conn->unpackString(bstream, mBuf);
102 mArgv[i+1] = dStrdup(mBuf);
103 }
104 }
105
106 void RemoteCommandEvent::process(NetConnection *conn)
107 {
108 static char idBuf[10];
109
110 // de-tag the command name
111
112 for(S32 i = mArgc - 1; i >= 0; i--)
113 {
114 char *arg = mArgv[i+1];
115 if(*arg == StringTagPrefixByte)
116 {
117 // it's a tag:
118 U32 localTag = dAtoi(arg + 1);
119 NetStringHandle tag = conn->translateRemoteStringId(localTag);
120 NetStringTable::expandString( tag,
121 mBuf,
122 sizeof(mBuf),
123 (mArgc - 1) - i,
124 (const char**)(mArgv + i + 2) );
125 dFree(mArgv[i+1]);
126 mArgv[i+1] = dStrdup(mBuf);
127 }
128 }
129 const char *rmtCommandName = dStrchr(mArgv[1], ' ') + 1;
130 if(conn->isConnectionToServer())
131 {
132 dStrcpy(mBuf, "clientCmd", 1024);
133 dStrcat(mBuf, rmtCommandName, 1024);
134
135 char *temp = mArgv[1];
136 mArgv[1] = mBuf;
137
138 Con::execute(mArgc, (const char **) mArgv+1);
139 mArgv[1] = temp;
140 }
141 else
142 {
143 dStrcpy(mBuf, "serverCmd", 1024);
144 dStrcat(mBuf, rmtCommandName, 1024);
145 char *temp = mArgv[1];
146
147 dSprintf(idBuf, sizeof(idBuf), "%d", conn->getId());
148 mArgv[0] = mBuf;
149 mArgv[1] = idBuf;
150
151 Con::execute(mArgc+1, (const char **) mArgv);
152 mArgv[1] = temp;
153 }
154 }
155
156 void RemoteCommandEvent::sendRemoteCommand(NetConnection *conn, S32 argc, const char **argv)
157 {
158 if(U8(argv[0][0]) != StringTagPrefixByte)
159 {
160 Con::errorf(ConsoleLogEntry::Script, "Remote Command Error - command must be a tag.");
161 return;
162 }
163 S32 i;
164 for(i = argc - 1; i >= 0; i--)
165 {
166 if(argv[i][0] != 0)
167 break;
168 argc = i;
169 }
170 for(i = 0; i < argc; i++)
171 conn->validateSendString(argv[i]);
172 RemoteCommandEvent *cevt = new RemoteCommandEvent(argc, argv, conn);
173 conn->postNetEvent(cevt);
174 }
175
176 const char* RemoteCommandEvent::getTaggedString(const char* tag)
177 {
178 const char *indexPtr = tag;
179 if (*indexPtr == StringTagPrefixByte)
180 indexPtr++;
181 return gNetStringTable->lookupString(dAtoi(indexPtr));
182 }
183
184 void RemoteCommandEvent::removeTaggedString(S32 tag)
185 {
186 if (tag)
187 gNetStringTable->removeString(tag, true);
188 }
189
190 const char* RemoteCommandEvent::addTaggedString(const char* str)
191 {
192 NetStringHandle s(str);
193 gNetStringTable->incStringRefScript(s.getIndex());
194
195 char *ret = Con::getReturnBuffer(10);
196 ret[0] = StringTagPrefixByte;
197 dSprintf(ret + 1, 9, "%d", s.getIndex());
198 return ret;
199 }
200
201
202char RemoteCommandEvent::mBuf[1024];
203
204IMPLEMENT_CO_NETEVENT_V1(RemoteCommandEvent);
205
206ConsoleDocClass( RemoteCommandEvent,
207 "@brief Object used for remote procedure calls.\n\n"
208 "Not intended for game development, for exposing ConsoleFunctions (such as commandToClient) only.\n\n"
209 "@internal");
210
211
212
213ConsoleFunctionGroupBegin( Net, "Functions for use with the network; tagged strings and remote commands.");
214
215
216DefineEngineStringlyVariadicFunction( commandToServer, void, 2, RemoteCommandEvent::MaxRemoteCommandArgs + 1, "(string func, ...)"
217 "@brief Send a command to the server.\n\n"
218
219 "@param func Name of the server command being called\n"
220 "@param ... Various parameters being passed to server command\n\n"
221
222 "@tsexample\n"
223 "// Create a standard function. Needs to be executed on the client, such \n"
224 "// as within scripts/client/default.bind." TORQUE_SCRIPT_EXTENSION "\n"
225 "function toggleCamera(%val)\n"
226 "{\n"
227 " // If key was down, call a server command named 'ToggleCamera'\n"
228 " if (%val)\n"
229 " commandToServer('ToggleCamera');\n"
230 "}\n\n"
231 "// Server command being called from above. Needs to be executed on the \n"
232 "// server, such as within scripts/server/commands." TORQUE_SCRIPT_EXTENSION "\n"
233 "function serverCmdToggleCamera(%client)\n"
234 "{\n"
235 " if (%client.getControlObject() == %client.player)\n"
236 " {\n"
237 " %client.camera.setVelocity(\"0 0 0\");\n"
238 " %control = %client.camera;\n"
239 " }\n"
240 " else\n"
241 " {\n"
242 " %client.player.setVelocity(\"0 0 0\");\n"
243 " %control = %client.player;\n"
244 " }\n"
245 " %client.setControlObject(%control);\n"
246 " clientCmdSyncEditorGui();\n"
247 "}\n"
248 "@endtsexample\n\n"
249
250 "@ingroup Networking")
251{
252 NetConnection *conn = NetConnection::getConnectionToServer();
253 if(!conn)
254 return;
255 StringStackWrapper args(argc - 1, argv + 1);
256 RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args);
257}
258
259DefineEngineStringlyVariadicFunction( commandToClient, void, 3, RemoteCommandEvent::MaxRemoteCommandArgs + 2, "(NetConnection client, string func, ...)"
260 "@brief Send a command from the server to the client\n\n"
261
262 "@param client The numeric ID of a client GameConnection\n"
263 "@param func Name of the client function being called\n"
264 "@param ... Various parameters being passed to client command\n\n"
265
266 "@tsexample\n"
267 "// Set up the client command. Needs to be executed on the client, such as\n"
268 "// within scripts/client/client." TORQUE_SCRIPT_EXTENSION "\n"
269 "// Update the Ammo Counter with current ammo, if not any then hide the counter.\n"
270 "function clientCmdSetAmmoAmountHud(%amount)\n"
271 "{\n"
272 " if (!%amount)\n"
273 " AmmoAmount.setVisible(false);\n"
274 " else\n"
275 " {\n"
276 " AmmoAmount.setVisible(true);\n"
277 " AmmoAmount.setText(\"Ammo: \"@%amount);\n"
278 " }\n"
279 "}\n\n"
280 "// Call it from a server function. Needs to be executed on the server, \n"
281 "//such as within scripts/server/game." TORQUE_SCRIPT_EXTENSION "\n"
282 "function GameConnection::setAmmoAmountHud(%client, %amount)\n"
283 "{\n"
284 " commandToClient(%client, 'SetAmmoAmountHud', %amount);\n"
285 "}\n"
286 "@endtsexample\n\n"
287
288 "@ingroup Networking\n")
289{
290 NetConnection *conn;
291 if(!Sim::findObject(argv[1], conn))
292 return;
293 StringStackWrapper args(argc - 2, argv + 2);
294 RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args);
295}
296
297
298
299
300
301DefineEngineFunction(removeTaggedString, void, (S32 tag), (-1),
302 "@brief Remove a tagged string from the Net String Table\n\n"
303
304 "@param tag The tag associated with the string\n\n"
305
306 "@see \\ref syntaxDataTypes under Tagged %Strings\n"
307 "@see addTaggedString()\n"
308 "@see getTaggedString()\n"
309 "@ingroup Networking\n")
310 {
311 RemoteCommandEvent::removeTaggedString(tag);
312 }
313
314
315DefineEngineFunction(addTaggedString, const char* , (const char* str), (""),
316 "@brief Use the addTaggedString function to tag a new string and add it to the NetStringTable\n\n"
317
318 "@param str The string to be tagged and placed in the NetStringTable. Tagging ignores case, "
319 "so tagging the same string (excluding case differences) will be ignored as a duplicated tag.\n\n"
320
321 "@return Returns a string( containing a numeric value) equivalent to the string ID for the newly tagged string"
322
323 "@see \\ref syntaxDataTypes under Tagged %Strings\n"
324 "@see removeTaggedString()\n"
325 "@see getTaggedString()\n"
326 "@ingroup Networking\n")
327 {
328 return RemoteCommandEvent::addTaggedString(str);
329 }
330
331
332DefineEngineFunction(getTaggedString, const char* , (const char *tag), (""),
333 "@brief Use the getTaggedString function to convert a tag to a string.\n\n"
334
335 "This is not the same as detag() which can only be used within the context "
336 "of a function that receives a tag. This function can be used any time and "
337 "anywhere to convert a tag to a string.\n\n"
338
339 "@param tag A numeric tag ID.\n"
340
341 "@returns The string as found in the Net String table.\n"
342
343 "@see \\ref syntaxDataTypes under Tagged %Strings\n"
344 "@see addTaggedString()\n"
345 "@see removeTaggedString()\n"
346 "@ingroup Networking\n")
347 {
348 return RemoteCommandEvent::getTaggedString(tag);
349 }
350
351
352
353DefineEngineStringlyVariadicFunction( buildTaggedString, const char*, 2, 11, "(string format, ...)"
354 "@brief Build a string using the specified tagged string format.\n\n"
355
356 "This function takes an already tagged string (passed in as a tagged string ID) and one "
357 "or more additional strings. If the tagged string contains argument tags that range from "
358 "%%1 through %%9, then each additional string will be substituted into the tagged string. "
359 "The final (non-tagged) combined string will be returned. The maximum length of the tagged "
360 "string plus any inserted additional strings is 511 characters.\n\n"
361
362 "@param format A tagged string ID that contains zero or more argument tags, in the form of "
363 "%%1 through %%9.\n"
364 "@param ... A variable number of arguments that are insterted into the tagged string "
365 "based on the argument tags within the format string.\n"
366
367 "@returns An ordinary string that is a combination of the original tagged string with any additional "
368 "strings passed in inserted in place of each argument tag.\n"
369
370 "@tsexample\n"
371 "// Create a tagged string with argument tags\n"
372 "%taggedStringID = addTaggedString(\"Welcome %1 to the game!\");\n\n"
373
374 "// Some point later, combine the tagged string with some other string\n"
375 "%string = buildTaggedString(%taggedStringID, %playerName);\n"
376 "echo(%string);\n"
377 "@endtsexample\n\n"
378
379 "@see \\ref syntaxDataTypes under Tagged %Strings\n"
380 "@see addTaggedString()\n"
381 "@see getTaggedString()\n"
382 "@ingroup Networking\n")
383{
384 const char *indexPtr = argv[1];
385 if (*indexPtr == StringTagPrefixByte)
386 indexPtr++;
387 const char *fmtString = gNetStringTable->lookupString(dAtoi(indexPtr));
388 static const U32 bufSize = 512;
389 char *strBuffer = Con::getReturnBuffer(bufSize);
390 const char *fmtStrPtr = fmtString;
391 char *strBufPtr = strBuffer;
392 S32 strMaxLength = bufSize - 1;
393 if (!fmtString)
394 goto done;
395
396 //build the string
397 while (*fmtStrPtr)
398 {
399 //look for an argument tag
400 if (*fmtStrPtr == '%')
401 {
402 if (fmtStrPtr[1] >= '1' && fmtStrPtr[1] <= '9')
403 {
404 S32 argIndex = S32(fmtStrPtr[1] - '0') + 1;
405 if (argIndex >= argc)
406 goto done;
407 const char *argStr = argv[argIndex];
408 if (!argStr)
409 goto done;
410 S32 strLength = dStrlen(argStr);
411 if (strLength > strMaxLength)
412 goto done;
413 dStrcpy(strBufPtr, argStr, strMaxLength);
414 strBufPtr += strLength;
415 strMaxLength -= strLength;
416 fmtStrPtr += 2;
417 continue;
418 }
419 }
420
421 //if we don't continue, just copy the character
422 if (strMaxLength <= 0)
423 goto done;
424 *strBufPtr++ = *fmtStrPtr++;
425 strMaxLength--;
426 }
427
428done:
429 *strBufPtr = '\0';
430 return strBuffer;
431}
432
433ConsoleFunctionGroupEnd( Net );
434