PlutoIW5 support for the Game Interface and improvements to the GSC part of it. (#242)
* Improvements to the GSC part of the Game Interface * Adds compatibility with PlutoIW5 with minimal changes. * Fixes issues when commands are called from the web interface when the used profile is not on the server. * New Debug output when the target or origin of a command is sent by IW4MAdmin but not found in-game. * Commands that can be run on the context of the target are now run in it. * Simplifies the command registration and execution. * Got rid of the huge switch block. * Introduced AddClientCommand to register new commands for example * `AddClientCommand("SwitchTeams", true, ::TeamSwitchImpl);` * `AddClientCommand("Hide", false, ::HideImpl);` * Callbacks are called with the full event object and the parsed data as parameters to allow maximum flexibility. * Introduced level.eventBus.gamename to know which game we are to add minor changes. * Changes - noclip/lockcontrols/playertome Additional changes to support other games' functions Co-Authored-By: Amos <4959320+MrAmos123@users.noreply.github.com>
This commit is contained in:
parent
fab97ccad4
commit
1700b7da91
16
GameFiles/README.MD
Normal file
16
GameFiles/README.MD
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Game Interface
|
||||||
|
|
||||||
|
Allows integration of IW4M-Admin to GSC, mainly used for special commands that need to use GSC in order to work.
|
||||||
|
But can also be used to read / write metadata from / to a profile and to get the player permission level.
|
||||||
|
|
||||||
|
|
||||||
|
## Installation Plutonium IW5
|
||||||
|
|
||||||
|
|
||||||
|
Move `_integration.gsc` to `%localappdata%\Plutonium\storage\iw5\scripts\`
|
||||||
|
|
||||||
|
|
||||||
|
## Installation IW4x
|
||||||
|
|
||||||
|
|
||||||
|
Move `_integration.gsc` to `IW4x/userraw/scripts`, `IW4x` being the root folder of your game server.
|
@ -1,7 +1,6 @@
|
|||||||
#include common_scripts\utility;
|
#include common_scripts\utility;
|
||||||
#include maps\mp\_utility;
|
#include maps\mp\_utility;
|
||||||
#include maps\mp\gametypes\_hud_util;
|
#include maps\mp\gametypes\_hud_util;
|
||||||
#include maps\mp\gametypes\_playerlogic;
|
|
||||||
|
|
||||||
init()
|
init()
|
||||||
{
|
{
|
||||||
@ -12,6 +11,7 @@ init()
|
|||||||
level.eventBus.failKey = "fail";
|
level.eventBus.failKey = "fail";
|
||||||
level.eventBus.timeoutKey = "timeout";
|
level.eventBus.timeoutKey = "timeout";
|
||||||
level.eventBus.timeout = 30;
|
level.eventBus.timeout = 30;
|
||||||
|
level.eventBus.gamename = getDvar( "gamename" ); // We want to do a few small detail different on IW5 compared to IW4, nothing where 2 files would make sense.
|
||||||
|
|
||||||
level.clientDataKey = "clientData";
|
level.clientDataKey = "clientData";
|
||||||
|
|
||||||
@ -35,18 +35,26 @@ init()
|
|||||||
level.eventCallbacks[level.eventTypes.clientDataReceived] = ::OnClientDataReceived;
|
level.eventCallbacks[level.eventTypes.clientDataReceived] = ::OnClientDataReceived;
|
||||||
level.eventCallbacks[level.eventTypes.executeCommandRequested] = ::OnExecuteCommand;
|
level.eventCallbacks[level.eventTypes.executeCommandRequested] = ::OnExecuteCommand;
|
||||||
level.eventCallbacks[level.eventTypes.setClientDataCompleted] = ::OnSetClientDataCompleted;
|
level.eventCallbacks[level.eventTypes.setClientDataCompleted] = ::OnSetClientDataCompleted;
|
||||||
|
|
||||||
|
level.clientCommandCallbacks = [];
|
||||||
|
level.clientCommandRusAsTarget = [];
|
||||||
|
|
||||||
if ( GetDvarInt( "sv_iw4madmin_integration_enabled" ) != 1 )
|
if ( GetDvarInt( "sv_iw4madmin_integration_enabled" ) != 1 )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InitializeGameMethods();
|
||||||
|
RegisterClientCommands();
|
||||||
|
|
||||||
// start long running tasks
|
// start long running tasks
|
||||||
level thread MonitorClientEvents();
|
level thread MonitorClientEvents();
|
||||||
level thread MonitorBus();
|
level thread MonitorBus();
|
||||||
level thread OnPlayerConnect();
|
level thread OnPlayerConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
// Client Methods
|
// Client Methods
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
@ -61,7 +69,7 @@ OnPlayerConnect()
|
|||||||
|
|
||||||
level.iw4adminIntegrationDebug = GetDvarInt( "sv_iw4madmin_integration_debug" );
|
level.iw4adminIntegrationDebug = GetDvarInt( "sv_iw4madmin_integration_debug" );
|
||||||
|
|
||||||
if ( player.pers["isBot"] )
|
if ( isDefined(player.pers["isBot"]) && player.pers["isBot"] )
|
||||||
{
|
{
|
||||||
// we don't want to track bots
|
// we don't want to track bots
|
||||||
continue;
|
continue;
|
||||||
@ -109,26 +117,26 @@ OnPlayerDisconnect()
|
|||||||
|
|
||||||
OnPlayerJoinedTeam()
|
OnPlayerJoinedTeam()
|
||||||
{
|
{
|
||||||
self endon( "disconnect" );
|
self endon( "disconnect" );
|
||||||
|
|
||||||
for( ;; )
|
for( ;; )
|
||||||
{
|
{
|
||||||
self waittill( "joined_team" );
|
self waittill( "joined_team" );
|
||||||
// join spec and join team occur at the same moment - out of order logging would be problematic
|
// join spec and join team occur at the same moment - out of order logging would be problematic
|
||||||
wait( 0.25 );
|
wait( 0.25 );
|
||||||
LogPrint( GenerateJoinTeamString( false ) );
|
LogPrint( GenerateJoinTeamString( false ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OnPlayerJoinedSpectators()
|
OnPlayerJoinedSpectators()
|
||||||
{
|
{
|
||||||
self endon( "disconnect" );
|
self endon( "disconnect" );
|
||||||
|
|
||||||
for( ;; )
|
for( ;; )
|
||||||
{
|
{
|
||||||
self waittill( "joined_spectators" );
|
self waittill( "joined_spectators" );
|
||||||
LogPrint( GenerateJoinTeamString( true ) );
|
LogPrint( GenerateJoinTeamString( true ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OnGameEnded()
|
OnGameEnded()
|
||||||
@ -209,7 +217,7 @@ MonitorClientEvents()
|
|||||||
|
|
||||||
if ( level.iw4adminIntegrationDebug == 1 )
|
if ( level.iw4adminIntegrationDebug == 1 )
|
||||||
{
|
{
|
||||||
self IPrintLn( "Processing Event " + client.event.type + "-" + client.event.subtype );
|
IPrintLn( "Processing Event " + client.event.type + "-" + client.event.subtype );
|
||||||
}
|
}
|
||||||
|
|
||||||
eventHandler = level.eventCallbacks[client.event.type];
|
eventHandler = level.eventCallbacks[client.event.type];
|
||||||
@ -227,6 +235,53 @@ MonitorClientEvents()
|
|||||||
// Helper Methods
|
// Helper Methods
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
|
|
||||||
|
RegisterClientCommands()
|
||||||
|
{
|
||||||
|
AddClientCommand( "GiveWeapon", true, ::GiveWeaponImpl );
|
||||||
|
AddClientCommand( "TakeWeapons", true, ::TakeWeaponsImpl );
|
||||||
|
AddClientCommand( "SwitchTeams", true, ::TeamSwitchImpl );
|
||||||
|
AddClientCommand( "Hide", false, ::HideImpl );
|
||||||
|
AddClientCommand( "Unhide", false, ::UnhideImpl );
|
||||||
|
AddClientCommand( "Alert", true, ::AlertImpl );
|
||||||
|
AddClientCommand( "Goto", false, ::GotoImpl );
|
||||||
|
AddClientCommand( "Kill", true, ::KillImpl );
|
||||||
|
AddClientCommand( "SetSpectator", true, ::SetSpectatorImpl );
|
||||||
|
AddClientCommand( "NightMode", false, ::NightModeImpl ); //This really should be a level command
|
||||||
|
AddClientCommand( "LockControls", true, ::LockControlsImpl );
|
||||||
|
AddClientCommand( "UnlockControls", true, ::UnlockControlsImpl );
|
||||||
|
AddClientCommand( "PlayerToMe", true, ::PlayerToMeImpl );
|
||||||
|
AddClientCommand( "NoClip", false, ::NoClipImpl );
|
||||||
|
AddClientCommand( "NoClipOff", false, ::NoClipOffImpl );
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeGameMethods()
|
||||||
|
{
|
||||||
|
level.overrideMethods = [];
|
||||||
|
level.overrideMethods["god"] = ::_god;
|
||||||
|
level.overrideMethods["noclip"] = ::UnsupportedFunc;
|
||||||
|
|
||||||
|
if ( isDefined( ::God ) )
|
||||||
|
{
|
||||||
|
level.overrideMethods["god"] = ::God;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isDefined( ::NoClip ) )
|
||||||
|
{
|
||||||
|
level.overrideMethods["noclip"] = ::NoClip;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( level.eventBus.gamename == "IW5" )
|
||||||
|
{ //PlutoIW5 only allows Godmode and NoClip if cheats are on..
|
||||||
|
level.overrideMethods["god"] = ::IW5_God;
|
||||||
|
level.overrideMethods["noclip"] = ::IW5_NoClip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UnsupportedFunc()
|
||||||
|
{
|
||||||
|
self IPrintLnBold( "Function is not supported!" );
|
||||||
|
}
|
||||||
|
|
||||||
RequestClientMeta( metaKey )
|
RequestClientMeta( metaKey )
|
||||||
{
|
{
|
||||||
getClientMetaEvent = BuildEventRequest( true, level.eventTypes.clientDataRequested, "Meta", self, metaKey );
|
getClientMetaEvent = BuildEventRequest( true, level.eventTypes.clientDataRequested, "Meta", self, metaKey );
|
||||||
@ -490,14 +545,65 @@ NotifyClientEvent( eventInfo )
|
|||||||
if ( level.iw4adminIntegrationDebug == 1 )
|
if ( level.iw4adminIntegrationDebug == 1 )
|
||||||
{
|
{
|
||||||
IPrintLn( "NotifyClientEvent->" + event.data );
|
IPrintLn( "NotifyClientEvent->" + event.data );
|
||||||
|
if( int( eventInfo[3] ) != -1 && !isDefined( origin ) )
|
||||||
|
{
|
||||||
|
IPrintLn( "origin is null but the slot id is " + int( eventInfo[3] ) );
|
||||||
|
}
|
||||||
|
if( int( eventInfo[4] ) != -1 && !isDefined( target ) )
|
||||||
|
{
|
||||||
|
IPrintLn( "target is null but the slot id is " + int( eventInfo[4] ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client = event.origin;
|
if( isDefined( target ) )
|
||||||
|
{
|
||||||
|
client = event.target;
|
||||||
|
}
|
||||||
|
else if( isDefined( origin ) )
|
||||||
|
{
|
||||||
|
client = event.origin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( level.iw4adminIntegrationDebug == 1 )
|
||||||
|
{
|
||||||
|
IPrintLn( "Neither origin or target are set but we are a Client Event, aborting" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
client.event = event;
|
client.event = event;
|
||||||
|
|
||||||
level notify( level.eventTypes.localClientEvent, client );
|
level notify( level.eventTypes.localClientEvent, client );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetPlayerFromClientNum( clientNum )
|
||||||
|
{
|
||||||
|
if ( clientNum < 0 )
|
||||||
|
return undefined;
|
||||||
|
|
||||||
|
for ( i = 0; i < level.players.size; i++ )
|
||||||
|
{
|
||||||
|
if ( level.players[i] getEntityNumber() == clientNum )
|
||||||
|
{
|
||||||
|
return level.players[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddClientCommand( commandName, shouldRunAsTarget, callback, shouldOverwrite )
|
||||||
|
{
|
||||||
|
if ( isDefined( level.clientCommandCallbacks[commandName] ) && isDefined( shouldOverwrite ) && !shouldOverwrite ) {
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
level.clientCommandCallbacks[commandName] = callback;
|
||||||
|
level.clientCommandRusAsTarget[commandName] = shouldRunAsTarget == true; //might speed up things later in case someone gives us a string or number instead of a boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
// Event Handlers
|
// Event Handlers
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
@ -544,45 +650,18 @@ OnExecuteCommand( event )
|
|||||||
data = ParseDataString( event.data );
|
data = ParseDataString( event.data );
|
||||||
response = "";
|
response = "";
|
||||||
|
|
||||||
switch ( event.subtype )
|
command = level.clientCommandCallbacks[event.subtype];
|
||||||
|
runAsTarget = level.clientCommandRusAsTarget[event.subtype];
|
||||||
|
executionContextEntity = event.origin;
|
||||||
|
if ( runAsTarget ) {
|
||||||
|
executionContextEntity = event.target;
|
||||||
|
}
|
||||||
|
if ( isDefined( command ) ) {
|
||||||
|
response = executionContextEntity [[command]]( event, data );
|
||||||
|
}
|
||||||
|
else if ( level.iw4adminIntegrationDebug == 1 )
|
||||||
{
|
{
|
||||||
case "GiveWeapon":
|
IPrintLn( "Unkown Client command->" + event.subtype);
|
||||||
response = event.target GiveWeaponImpl( data );
|
|
||||||
break;
|
|
||||||
case "TakeWeapons":
|
|
||||||
response = event.target TakeWeaponsImpl();
|
|
||||||
break;
|
|
||||||
case "SwitchTeams":
|
|
||||||
response = event.target TeamSwitchImpl();
|
|
||||||
break;
|
|
||||||
case "Hide":
|
|
||||||
response = self HideImpl();
|
|
||||||
break;
|
|
||||||
case "Unhide":
|
|
||||||
response = self UnhideImpl();
|
|
||||||
break;
|
|
||||||
case "Alert":
|
|
||||||
response = event.target AlertImpl( data );
|
|
||||||
break;
|
|
||||||
case "Goto":
|
|
||||||
if ( IsDefined( event.target ) )
|
|
||||||
{
|
|
||||||
response = self GotoPlayerImpl( event.target );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
response = self GotoImpl( data );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "Kill":
|
|
||||||
response = event.target KillImpl();
|
|
||||||
break;
|
|
||||||
case "NightMode":
|
|
||||||
NightModeImpl();
|
|
||||||
break;
|
|
||||||
case "SetSpectator":
|
|
||||||
response = event.target SetSpectatorImpl();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// send back the response to the origin, but only if they're not the target
|
// send back the response to the origin, but only if they're not the target
|
||||||
@ -605,7 +684,7 @@ OnSetClientDataCompleted( event )
|
|||||||
// Command Implementations
|
// Command Implementations
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
GiveWeaponImpl( data )
|
GiveWeaponImpl( event, data )
|
||||||
{
|
{
|
||||||
if ( !IsAlive( self ) )
|
if ( !IsAlive( self ) )
|
||||||
{
|
{
|
||||||
@ -636,7 +715,7 @@ TeamSwitchImpl()
|
|||||||
{
|
{
|
||||||
if ( !IsAlive( self ) )
|
if ( !IsAlive( self ) )
|
||||||
{
|
{
|
||||||
return self.name + "^7 is not alive";
|
return self + "^7 is not alive";
|
||||||
}
|
}
|
||||||
|
|
||||||
team = level.allies;
|
team = level.allies;
|
||||||
@ -653,6 +732,79 @@ TeamSwitchImpl()
|
|||||||
return self.name + "^7 switched to " + self.team;
|
return self.name + "^7 switched to " + self.team;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LockControlsImpl()
|
||||||
|
{
|
||||||
|
if ( !IsAlive( self ) )
|
||||||
|
{
|
||||||
|
return self.name + "^7 is not alive";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
self freezeControls( true );
|
||||||
|
self call [[level.overrideMethods["god"]]]( true );
|
||||||
|
self Hide();
|
||||||
|
|
||||||
|
info = [];
|
||||||
|
info[ "alertType" ] = "Alert!";
|
||||||
|
info[ "message" ] = "You have been frozen!";
|
||||||
|
|
||||||
|
self AlertImpl( undefined, info );
|
||||||
|
|
||||||
|
return self.name + "\'s controls are locked";
|
||||||
|
}
|
||||||
|
|
||||||
|
UnlockControlsImpl()
|
||||||
|
{
|
||||||
|
if ( !IsAlive( self ) )
|
||||||
|
{
|
||||||
|
return self.name + "^7 is not alive";
|
||||||
|
}
|
||||||
|
|
||||||
|
self freezeControls( false );
|
||||||
|
self call [[level.overrideMethods["god"]]]( false );
|
||||||
|
self Show();
|
||||||
|
|
||||||
|
return self.name + "\'s controls are unlocked";
|
||||||
|
}
|
||||||
|
|
||||||
|
NoClipImpl()
|
||||||
|
{
|
||||||
|
if ( !IsAlive( self ) )
|
||||||
|
{
|
||||||
|
self IPrintLnBold( "You are not alive" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self SetClientDvar( "sv_cheats", 1 );
|
||||||
|
self SetClientDvar( "cg_thirdperson", 1 );
|
||||||
|
self SetClientDvar( "sv_cheats", 0 );
|
||||||
|
|
||||||
|
self call [[level.overrideMethods["god"]]]( true );
|
||||||
|
self call [[level.overrideMethods["noclip"]]]( true );
|
||||||
|
self Hide();
|
||||||
|
|
||||||
|
self IPrintLnBold( "NoClip enabled" );
|
||||||
|
}
|
||||||
|
|
||||||
|
NoClipOffImpl()
|
||||||
|
{
|
||||||
|
if ( !IsAlive( self ) )
|
||||||
|
{
|
||||||
|
self IPrintLnBold( "You are not alive" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self SetClientDvar( "sv_cheats", 1 );
|
||||||
|
self SetClientDvar( "cg_thirdperson", 0 );
|
||||||
|
self SetClientDvar( "sv_cheats", 0 );
|
||||||
|
|
||||||
|
self call [[level.overrideMethods["god"]]]( false );
|
||||||
|
self call [[level.overrideMethods["noclip"]]]( false );
|
||||||
|
self Show();
|
||||||
|
|
||||||
|
self IPrintLnBold( "NoClip disabled" );
|
||||||
|
}
|
||||||
|
|
||||||
HideImpl()
|
HideImpl()
|
||||||
{
|
{
|
||||||
if ( !IsAlive( self ) )
|
if ( !IsAlive( self ) )
|
||||||
@ -671,10 +823,7 @@ HideImpl()
|
|||||||
self.savedMaxHealth = self.maxhealth;
|
self.savedMaxHealth = self.maxhealth;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.maxhealth = 99999;
|
self call [[level.overrideMethods["god"]]]( true );
|
||||||
self.health = 99999;
|
|
||||||
self.isHidden = true;
|
|
||||||
|
|
||||||
self Hide();
|
self Hide();
|
||||||
|
|
||||||
self IPrintLnBold( "You are now ^5hidden ^7from other players" );
|
self IPrintLnBold( "You are now ^5hidden ^7from other players" );
|
||||||
@ -698,21 +847,36 @@ UnhideImpl()
|
|||||||
self SetClientDvar( "cg_thirdperson", 0 );
|
self SetClientDvar( "cg_thirdperson", 0 );
|
||||||
self SetClientDvar( "sv_cheats", 0 );
|
self SetClientDvar( "sv_cheats", 0 );
|
||||||
|
|
||||||
self.health = self.savedHealth;
|
self call [[level.overrideMethods["god"]]]( false );
|
||||||
self.maxhealth = self.savedMaxHealth;
|
|
||||||
self.isHidden = false;
|
|
||||||
|
|
||||||
self Show();
|
self Show();
|
||||||
|
|
||||||
self IPrintLnBold( "You are now ^5visible ^7to other players" );
|
self IPrintLnBold( "You are now ^5visible ^7to other players" );
|
||||||
}
|
}
|
||||||
|
|
||||||
AlertImpl( data )
|
AlertImpl( event, data )
|
||||||
{
|
{
|
||||||
self thread maps\mp\gametypes\_hud_message::oldNotifyMessage( data["alertType"], data["message"], "compass_waypoint_target", ( 1, 0, 0 ), "ui_mp_nukebomb_timer", 7.5 );
|
if ( level.eventBus.gamename == "IW4" ) {
|
||||||
|
self thread maps\mp\gametypes\_hud_message::oldNotifyMessage( data["alertType"], data["message"], "compass_waypoint_target", ( 1, 0, 0 ), "ui_mp_nukebomb_timer", 7.5 );
|
||||||
|
}
|
||||||
|
if ( level.eventBus.gamename == "IW5" ) { //IW5's notification are a bit different...
|
||||||
|
self thread maps\mp\gametypes\_hud_message::oldNotifyMessage( data["alertType"], data["message"], undefined, ( 1, 0, 0 ), "ui_mp_nukebomb_timer", 7.5 );
|
||||||
|
}
|
||||||
return "Sent alert to " + self.name;
|
return "Sent alert to " + self.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
GotoImpl( data )
|
GotoImpl( event, data )
|
||||||
|
{
|
||||||
|
if ( IsDefined( event.target ) )
|
||||||
|
{
|
||||||
|
return self GotoPlayerImpl( event.target );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return self GotoCoordImpl( data );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GotoCoordImpl( data )
|
||||||
{
|
{
|
||||||
if ( !IsAlive( self ) )
|
if ( !IsAlive( self ) )
|
||||||
{
|
{
|
||||||
@ -737,6 +901,18 @@ GotoPlayerImpl( target )
|
|||||||
self IPrintLnBold( "Moved to " + target.name );
|
self IPrintLnBold( "Moved to " + target.name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlayerToMeImpl( event )
|
||||||
|
{
|
||||||
|
if ( !IsAlive( self ) )
|
||||||
|
{
|
||||||
|
return self.name + " is not alive";
|
||||||
|
}
|
||||||
|
|
||||||
|
self SetOrigin( event.origin GetOrigin() );
|
||||||
|
return "Moved here " + self.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
KillImpl()
|
KillImpl()
|
||||||
{
|
{
|
||||||
if ( !IsAlive( self ) )
|
if ( !IsAlive( self ) )
|
||||||
@ -805,3 +981,48 @@ SetSpectatorImpl()
|
|||||||
|
|
||||||
return self.name + " has been moved to spectator";
|
return self.name + " has been moved to spectator";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// Function Overrides
|
||||||
|
//////////////////////////////////
|
||||||
|
|
||||||
|
_god( isEnabled )
|
||||||
|
{
|
||||||
|
if ( isEnabled == true )
|
||||||
|
{
|
||||||
|
if ( !IsDefined( self.savedHealth ) || self.health < 1000 )
|
||||||
|
{
|
||||||
|
self.savedHealth = self.health;
|
||||||
|
self.savedMaxHealth = self.maxhealth;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.maxhealth = 99999;
|
||||||
|
self.health = 99999;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( !IsDefined( self.savedHealth ) || !IsDefined( self.savedMaxHealth ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.health = self.savedHealth;
|
||||||
|
self.maxhealth = self.savedMaxHealth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IW5_God()
|
||||||
|
{
|
||||||
|
SetDvar( "sv_cheats", 1 );
|
||||||
|
self God();
|
||||||
|
SetDvar( "sv_cheats", 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
IW5_NoClip()
|
||||||
|
{
|
||||||
|
SetDvar( "sv_cheats", 1 );
|
||||||
|
self NoClip();
|
||||||
|
SetDvar( "sv_cheats", 0 );
|
||||||
|
}
|
@ -13,7 +13,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
version.txt = version.txt
|
version.txt = version.txt
|
||||||
DeploymentFiles\UpdateIW4MAdmin.ps1 = DeploymentFiles\UpdateIW4MAdmin.ps1
|
DeploymentFiles\UpdateIW4MAdmin.ps1 = DeploymentFiles\UpdateIW4MAdmin.ps1
|
||||||
DeploymentFiles\UpdateIW4MAdmin.sh = DeploymentFiles\UpdateIW4MAdmin.sh
|
DeploymentFiles\UpdateIW4MAdmin.sh = DeploymentFiles\UpdateIW4MAdmin.sh
|
||||||
GameFiles\IW4x\userraw\scripts\_integration.gsc = GameFiles\IW4x\userraw\scripts\_integration.gsc
|
GameFiles\_integration.gsc = GameFiles\_integration.gsc
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharedLibraryCore", "SharedLibraryCore\SharedLibraryCore.csproj", "{AA0541A2-8D51-4AD9-B0AC-3D1F5B162481}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharedLibraryCore", "SharedLibraryCore\SharedLibraryCore.csproj", "{AA0541A2-8D51-4AD9-B0AC-3D1F5B162481}"
|
||||||
|
@ -85,7 +85,7 @@ let commands = [{
|
|||||||
name: 'weapon name',
|
name: 'weapon name',
|
||||||
required: true
|
required: true
|
||||||
}],
|
}],
|
||||||
supportedGames: ['IW4'],
|
supportedGames: ['IW4', 'IW5'],
|
||||||
execute: (gameEvent) => {
|
execute: (gameEvent) => {
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
return;
|
return;
|
||||||
@ -103,7 +103,7 @@ let commands = [{
|
|||||||
name: 'player',
|
name: 'player',
|
||||||
required: true
|
required: true
|
||||||
}],
|
}],
|
||||||
supportedGames: ['IW4'],
|
supportedGames: ['IW4', 'IW5'],
|
||||||
execute: (gameEvent) => {
|
execute: (gameEvent) => {
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
return;
|
return;
|
||||||
@ -121,7 +121,7 @@ let commands = [{
|
|||||||
name: 'player',
|
name: 'player',
|
||||||
required: true
|
required: true
|
||||||
}],
|
}],
|
||||||
supportedGames: ['IW4'],
|
supportedGames: ['IW4', 'IW5'],
|
||||||
execute: (gameEvent) => {
|
execute: (gameEvent) => {
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
return;
|
return;
|
||||||
@ -129,6 +129,72 @@ let commands = [{
|
|||||||
sendScriptCommand(gameEvent.Owner, 'SwitchTeams', gameEvent.Origin, gameEvent.Target, undefined);
|
sendScriptCommand(gameEvent.Owner, 'SwitchTeams', gameEvent.Origin, gameEvent.Target, undefined);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'lockcontrols',
|
||||||
|
description: 'locks target player\'s controls',
|
||||||
|
alias: 'lc',
|
||||||
|
permission: 'Administrator',
|
||||||
|
targetRequired: true,
|
||||||
|
arguments: [{
|
||||||
|
name: 'player',
|
||||||
|
required: true
|
||||||
|
}],
|
||||||
|
supportedGames: ['IW4', 'IW5'],
|
||||||
|
execute: (gameEvent) => {
|
||||||
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendScriptCommand(gameEvent.Owner, 'LockControls', gameEvent.Origin, gameEvent.Target, undefined);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'unlockcontrols',
|
||||||
|
description: 'unlocks target player\'s controls',
|
||||||
|
alias: 'ulc',
|
||||||
|
permission: 'Administrator',
|
||||||
|
targetRequired: true,
|
||||||
|
arguments: [{
|
||||||
|
name: 'player',
|
||||||
|
required: true
|
||||||
|
}],
|
||||||
|
supportedGames: ['IW4', 'IW5'],
|
||||||
|
execute: (gameEvent) => {
|
||||||
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendScriptCommand(gameEvent.Owner, 'UnlockControls', gameEvent.Origin, gameEvent.Target, undefined);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'noclip',
|
||||||
|
description: 'enable noclip on yourself ingame',
|
||||||
|
alias: 'nc',
|
||||||
|
permission: 'SeniorAdmin',
|
||||||
|
targetRequired: false,
|
||||||
|
arguments: [],
|
||||||
|
supportedGames: ['IW4', 'IW5'],
|
||||||
|
execute: (gameEvent) => {
|
||||||
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendScriptCommand(gameEvent.Owner, 'NoClip', gameEvent.Origin, gameEvent.Origin, undefined);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'noclipoff',
|
||||||
|
description: 'disable noclip on yourself ingame',
|
||||||
|
alias: 'nco',
|
||||||
|
permission: 'SeniorAdmin',
|
||||||
|
targetRequired: false,
|
||||||
|
arguments: [],
|
||||||
|
supportedGames: ['IW4', 'IW5'],
|
||||||
|
execute: (gameEvent) => {
|
||||||
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendScriptCommand(gameEvent.Owner, 'NoClipOff', gameEvent.Origin, gameEvent.Origin, undefined);
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'hide',
|
name: 'hide',
|
||||||
description: 'hide yourself ingame',
|
description: 'hide yourself ingame',
|
||||||
@ -136,7 +202,7 @@ let commands = [{
|
|||||||
permission: 'SeniorAdmin',
|
permission: 'SeniorAdmin',
|
||||||
targetRequired: false,
|
targetRequired: false,
|
||||||
arguments: [],
|
arguments: [],
|
||||||
supportedGames: ['IW4'],
|
supportedGames: ['IW4', 'IW5'],
|
||||||
execute: (gameEvent) => {
|
execute: (gameEvent) => {
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
return;
|
return;
|
||||||
@ -151,7 +217,7 @@ let commands = [{
|
|||||||
permission: 'SeniorAdmin',
|
permission: 'SeniorAdmin',
|
||||||
targetRequired: false,
|
targetRequired: false,
|
||||||
arguments: [],
|
arguments: [],
|
||||||
supportedGames: ['IW4'],
|
supportedGames: ['IW4', 'IW5'],
|
||||||
execute: (gameEvent) => {
|
execute: (gameEvent) => {
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
return;
|
return;
|
||||||
@ -173,7 +239,7 @@ let commands = [{
|
|||||||
name: 'message',
|
name: 'message',
|
||||||
required: true
|
required: true
|
||||||
}],
|
}],
|
||||||
supportedGames: ['IW4'],
|
supportedGames: ['IW4', 'IW5'],
|
||||||
execute: (gameEvent) => {
|
execute: (gameEvent) => {
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
return;
|
return;
|
||||||
@ -194,7 +260,7 @@ let commands = [{
|
|||||||
name: 'player',
|
name: 'player',
|
||||||
required: true
|
required: true
|
||||||
}],
|
}],
|
||||||
supportedGames: ['IW4'],
|
supportedGames: ['IW4', 'IW5'],
|
||||||
execute: (gameEvent) => {
|
execute: (gameEvent) => {
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
return;
|
return;
|
||||||
@ -202,6 +268,24 @@ let commands = [{
|
|||||||
sendScriptCommand(gameEvent.Owner, 'Goto', gameEvent.Origin, gameEvent.Target, undefined);
|
sendScriptCommand(gameEvent.Owner, 'Goto', gameEvent.Origin, gameEvent.Target, undefined);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'playertome',
|
||||||
|
description: 'teleport a player to you',
|
||||||
|
alias: 'p2m',
|
||||||
|
permission: 'SeniorAdmin',
|
||||||
|
targetRequired: true,
|
||||||
|
arguments: [{
|
||||||
|
name: 'player',
|
||||||
|
required: true
|
||||||
|
}],
|
||||||
|
supportedGames: ['IW4', 'IW5'],
|
||||||
|
execute: (gameEvent) => {
|
||||||
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendScriptCommand(gameEvent.Owner, 'PlayerToMe', gameEvent.Origin, gameEvent.Target, undefined);
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'goto',
|
name: 'goto',
|
||||||
description: 'teleport to a position',
|
description: 'teleport to a position',
|
||||||
@ -220,7 +304,7 @@ let commands = [{
|
|||||||
name: 'z',
|
name: 'z',
|
||||||
required: true
|
required: true
|
||||||
}],
|
}],
|
||||||
supportedGames: ['IW4'],
|
supportedGames: ['IW4', 'IW5'],
|
||||||
execute: (gameEvent) => {
|
execute: (gameEvent) => {
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
return;
|
return;
|
||||||
@ -244,7 +328,7 @@ let commands = [{
|
|||||||
name: 'player',
|
name: 'player',
|
||||||
required: true
|
required: true
|
||||||
}],
|
}],
|
||||||
supportedGames: ['IW4'],
|
supportedGames: ['IW4', 'IW5'],
|
||||||
execute: (gameEvent) => {
|
execute: (gameEvent) => {
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
return;
|
return;
|
||||||
@ -259,7 +343,7 @@ let commands = [{
|
|||||||
permission: 'SeniorAdmin',
|
permission: 'SeniorAdmin',
|
||||||
targetRequired: false,
|
targetRequired: false,
|
||||||
arguments: [],
|
arguments: [],
|
||||||
supportedGames: ['IW4'],
|
supportedGames: ['IW4', 'IW5'],
|
||||||
execute: (gameEvent) => {
|
execute: (gameEvent) => {
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
return;
|
return;
|
||||||
@ -277,7 +361,7 @@ let commands = [{
|
|||||||
name: 'player',
|
name: 'player',
|
||||||
required: true
|
required: true
|
||||||
}],
|
}],
|
||||||
supportedGames: ['IW4'],
|
supportedGames: ['IW4', 'IW5'],
|
||||||
execute: (gameEvent) => {
|
execute: (gameEvent) => {
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
return;
|
return;
|
||||||
@ -489,7 +573,7 @@ const pollForEvents = server => {
|
|||||||
const nextMessage = state.queuedMessages.splice(0, 1);
|
const nextMessage = state.queuedMessages.splice(0, 1);
|
||||||
setDvar(server, outDvar, nextMessage, onSetDvar);
|
setDvar(server, outDvar, nextMessage, onSetDvar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.waitingOnOutput) {
|
if (state.waitingOnOutput) {
|
||||||
getDvar(server, outDvar, onReceivedDvar);
|
getDvar(server, outDvar, onReceivedDvar);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user