refactor some game interface plugin approach
This commit is contained in:
parent
acf66da4ca
commit
9f4d06c265
@ -276,6 +276,8 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
{
|
{
|
||||||
_logger.LogDebug("OnLoad executing for {Name}", Name);
|
_logger.LogDebug("OnLoad executing for {Name}", Name);
|
||||||
_scriptEngine.SetValue("_manager", manager);
|
_scriptEngine.SetValue("_manager", manager);
|
||||||
|
_scriptEngine.SetValue("getDvar", GetDvarAsync);
|
||||||
|
_scriptEngine.SetValue("setDvar", SetDvarAsync);
|
||||||
_scriptEngine.Evaluate("plugin.onLoadAsync(_manager)");
|
_scriptEngine.Evaluate("plugin.onLoadAsync(_manager)");
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@ -451,6 +453,85 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
|
|
||||||
return commandList;
|
return commandList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GetDvarAsync(Server server, string dvarName, Delegate onCompleted)
|
||||||
|
{
|
||||||
|
Task.Run<Task>(async () =>
|
||||||
|
{
|
||||||
|
var tokenSource = new CancellationTokenSource();
|
||||||
|
tokenSource.CancelAfter(TimeSpan.FromSeconds(5));
|
||||||
|
string result = null;
|
||||||
|
var success = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = (await server.GetDvarAsync<string>(dvarName, token: tokenSource.Token)).Value;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _onProcessing.WaitAsync();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
onCompleted.DynamicInvoke(JsValue.Undefined,
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
JsValue.FromObject(_scriptEngine, server),
|
||||||
|
JsValue.FromObject(_scriptEngine, dvarName),
|
||||||
|
JsValue.FromObject(_scriptEngine, result),
|
||||||
|
JsValue.FromObject(_scriptEngine, success),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (_onProcessing.CurrentCount == 0)
|
||||||
|
{
|
||||||
|
_onProcessing.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private void SetDvarAsync(Server server, string dvarName, string dvarValue, Delegate onCompleted)
|
||||||
|
{
|
||||||
|
Task.Run<Task>(async () =>
|
||||||
|
{
|
||||||
|
var tokenSource = new CancellationTokenSource();
|
||||||
|
tokenSource.CancelAfter(TimeSpan.FromSeconds(5));
|
||||||
|
var success = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await server.SetDvarAsync(dvarName, dvarValue, tokenSource.Token);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
await _onProcessing.WaitAsync();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
onCompleted.DynamicInvoke(JsValue.Undefined,
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
JsValue.FromObject(_scriptEngine, server),
|
||||||
|
JsValue.FromObject(_scriptEngine, dvarName),
|
||||||
|
JsValue.FromObject(_scriptEngine, dvarValue),
|
||||||
|
JsValue.FromObject(_scriptEngine, success)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (_onProcessing.CurrentCount == 0)
|
||||||
|
{
|
||||||
|
_onProcessing.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PermissionLevelToStringConverter : IObjectConverter
|
public class PermissionLevelToStringConverter : IObjectConverter
|
||||||
|
@ -603,6 +603,7 @@ HideImpl()
|
|||||||
if ( !IsDefined( self.savedHealth ) || self.health < 1000 )
|
if ( !IsDefined( self.savedHealth ) || self.health < 1000 )
|
||||||
{
|
{
|
||||||
self.savedHealth = self.health;
|
self.savedHealth = self.health;
|
||||||
|
self.savedMaxHealth = self.maxhealth;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.maxhealth = 99999;
|
self.maxhealth = 99999;
|
||||||
@ -621,12 +622,19 @@ UnhideImpl()
|
|||||||
self IPrintLnBold( "You are not alive" );
|
self IPrintLnBold( "You are not alive" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( IsDefined( self.isHidden ) && !self.isHidden )
|
||||||
|
{
|
||||||
|
self IPrintLnBold( "You are not hidden" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self SetClientDvar( "sv_cheats", 1 );
|
self SetClientDvar( "sv_cheats", 1 );
|
||||||
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.health = self.savedHealth;
|
||||||
|
self.maxhealth = self.savedMaxHealth;
|
||||||
self.isHidden = false;
|
self.isHidden = false;
|
||||||
|
|
||||||
self Show();
|
self Show();
|
||||||
|
@ -1,19 +1,14 @@
|
|||||||
const eventTypes = {
|
const servers = {};
|
||||||
1: 'start', // a server started being monitored
|
|
||||||
6: 'disconnect', // a client detected a leaving the game
|
|
||||||
9: 'preconnect', // client detected as joining via log or status
|
|
||||||
101: 'warn' // client was warned
|
|
||||||
};
|
|
||||||
|
|
||||||
const servers = {};
|
|
||||||
const inDvar = 'sv_iw4madmin_in';
|
const inDvar = 'sv_iw4madmin_in';
|
||||||
const outDvar = 'sv_iw4madmin_out';
|
const outDvar = 'sv_iw4madmin_out';
|
||||||
const pollRate = 750;
|
const pollRate = 900;
|
||||||
|
const enableCheckTimeout = 10000;
|
||||||
let logger = {};
|
let logger = {};
|
||||||
|
const maxQueuedMessages = 25;
|
||||||
|
|
||||||
let plugin = {
|
let plugin = {
|
||||||
author: 'RaidMax',
|
author: 'RaidMax',
|
||||||
version: 1.0,
|
version: 1.1,
|
||||||
name: 'Game Interface',
|
name: 'Game Interface',
|
||||||
|
|
||||||
onEventAsync: (gameEvent, server) => {
|
onEventAsync: (gameEvent, server) => {
|
||||||
@ -21,7 +16,7 @@ let plugin = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventType = eventTypes[gameEvent.Type];
|
const eventType = String(gameEvent.TypeName).toLowerCase();
|
||||||
|
|
||||||
if (eventType === undefined) {
|
if (eventType === undefined) {
|
||||||
return;
|
return;
|
||||||
@ -86,10 +81,10 @@ let commands = [{
|
|||||||
name: 'player',
|
name: 'player',
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'weapon name',
|
name: 'weapon name',
|
||||||
required: true
|
required: true
|
||||||
}],
|
}],
|
||||||
supportedGames: ['IW4'],
|
supportedGames: ['IW4'],
|
||||||
execute: (gameEvent) => {
|
execute: (gameEvent) => {
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
@ -98,198 +93,198 @@ let commands = [{
|
|||||||
sendScriptCommand(gameEvent.Owner, 'GiveWeapon', gameEvent.Origin, gameEvent.Target, {weaponName: gameEvent.Data});
|
sendScriptCommand(gameEvent.Owner, 'GiveWeapon', gameEvent.Origin, gameEvent.Target, {weaponName: gameEvent.Data});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'takeweapons',
|
name: 'takeweapons',
|
||||||
description: 'take all weapons from specified player',
|
description: 'take all weapons from specified player',
|
||||||
alias: 'tw',
|
alias: 'tw',
|
||||||
permission: 'SeniorAdmin',
|
permission: 'SeniorAdmin',
|
||||||
targetRequired: true,
|
targetRequired: true,
|
||||||
arguments: [{
|
arguments: [{
|
||||||
name: 'player',
|
name: 'player',
|
||||||
required: true
|
|
||||||
}],
|
|
||||||
supportedGames: ['IW4'],
|
|
||||||
execute: (gameEvent) => {
|
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sendScriptCommand(gameEvent.Owner, 'TakeWeapons', gameEvent.Origin, gameEvent.Target, undefined);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'switchteam',
|
|
||||||
description: 'switches specified player to the opposite team',
|
|
||||||
alias: 'st',
|
|
||||||
permission: 'Administrator',
|
|
||||||
targetRequired: true,
|
|
||||||
arguments: [{
|
|
||||||
name: 'player',
|
|
||||||
required: true
|
|
||||||
}],
|
|
||||||
supportedGames: ['IW4'],
|
|
||||||
execute: (gameEvent) => {
|
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sendScriptCommand(gameEvent.Owner, 'SwitchTeams', gameEvent.Origin, gameEvent.Target, undefined);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'hide',
|
|
||||||
description: 'hide yourself ingame',
|
|
||||||
alias: 'hi',
|
|
||||||
permission: 'SeniorAdmin',
|
|
||||||
targetRequired: false,
|
|
||||||
arguments: [],
|
|
||||||
supportedGames: ['IW4'],
|
|
||||||
execute: (gameEvent) => {
|
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sendScriptCommand(gameEvent.Owner, 'Hide', gameEvent.Origin, gameEvent.Origin, undefined);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'unhide',
|
|
||||||
description: 'unhide yourself ingame',
|
|
||||||
alias: 'unh',
|
|
||||||
permission: 'SeniorAdmin',
|
|
||||||
targetRequired: false,
|
|
||||||
arguments: [],
|
|
||||||
supportedGames: ['IW4'],
|
|
||||||
execute: (gameEvent) => {
|
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sendScriptCommand(gameEvent.Owner, 'Unhide', gameEvent.Origin, gameEvent.Origin, undefined);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'alert',
|
|
||||||
description: 'alert a player',
|
|
||||||
alias: 'alr',
|
|
||||||
permission: 'SeniorAdmin',
|
|
||||||
targetRequired: true,
|
|
||||||
arguments: [{
|
|
||||||
name: 'player',
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'message',
|
|
||||||
required: true
|
required: true
|
||||||
}],
|
}],
|
||||||
supportedGames: ['IW4'],
|
supportedGames: ['IW4'],
|
||||||
execute: (gameEvent) => {
|
execute: (gameEvent) => {
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
sendScriptCommand(gameEvent.Owner, 'TakeWeapons', gameEvent.Origin, gameEvent.Target, undefined);
|
||||||
}
|
}
|
||||||
sendScriptCommand(gameEvent.Owner, 'Alert', gameEvent.Origin, gameEvent.Target, {
|
|
||||||
alertType: 'Alert',
|
|
||||||
message: gameEvent.Data
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'gotoplayer',
|
|
||||||
description: 'teleport to a player',
|
|
||||||
alias: 'g2p',
|
|
||||||
permission: 'SeniorAdmin',
|
|
||||||
targetRequired: true,
|
|
||||||
arguments: [{
|
|
||||||
name: 'player',
|
|
||||||
required: true
|
|
||||||
}],
|
|
||||||
supportedGames: ['IW4'],
|
|
||||||
execute: (gameEvent) => {
|
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sendScriptCommand(gameEvent.Owner, 'Goto', gameEvent.Origin, gameEvent.Target, undefined);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'goto',
|
|
||||||
description: 'teleport to a position',
|
|
||||||
alias: 'g2',
|
|
||||||
permission: 'SeniorAdmin',
|
|
||||||
targetRequired: false,
|
|
||||||
arguments: [{
|
|
||||||
name: 'x',
|
|
||||||
required: true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'y',
|
name: 'switchteam',
|
||||||
required: true
|
description: 'switches specified player to the opposite team',
|
||||||
|
alias: 'st',
|
||||||
|
permission: 'Administrator',
|
||||||
|
targetRequired: true,
|
||||||
|
arguments: [{
|
||||||
|
name: 'player',
|
||||||
|
required: true
|
||||||
|
}],
|
||||||
|
supportedGames: ['IW4'],
|
||||||
|
execute: (gameEvent) => {
|
||||||
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendScriptCommand(gameEvent.Owner, 'SwitchTeams', gameEvent.Origin, gameEvent.Target, undefined);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'z',
|
name: 'hide',
|
||||||
required: true
|
description: 'hide yourself ingame',
|
||||||
}],
|
alias: 'hi',
|
||||||
supportedGames: ['IW4'],
|
permission: 'SeniorAdmin',
|
||||||
execute: (gameEvent) => {
|
targetRequired: false,
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
arguments: [],
|
||||||
return;
|
supportedGames: ['IW4'],
|
||||||
|
execute: (gameEvent) => {
|
||||||
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendScriptCommand(gameEvent.Owner, 'Hide', gameEvent.Origin, gameEvent.Origin, undefined);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
const args = String(gameEvent.Data).split(' ');
|
{
|
||||||
sendScriptCommand(gameEvent.Owner, 'Goto', gameEvent.Origin, gameEvent.Target, {
|
name: 'unhide',
|
||||||
x: args[0],
|
description: 'unhide yourself ingame',
|
||||||
y: args[1],
|
alias: 'unh',
|
||||||
z: args[2]
|
permission: 'SeniorAdmin',
|
||||||
});
|
targetRequired: false,
|
||||||
}
|
arguments: [],
|
||||||
},
|
supportedGames: ['IW4'],
|
||||||
{
|
execute: (gameEvent) => {
|
||||||
name: 'kill',
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
description: 'kill a player',
|
return;
|
||||||
alias: 'kpl',
|
}
|
||||||
permission: 'SeniorAdmin',
|
sendScriptCommand(gameEvent.Owner, 'Unhide', gameEvent.Origin, gameEvent.Origin, undefined);
|
||||||
targetRequired: true,
|
|
||||||
arguments: [{
|
|
||||||
name: 'player',
|
|
||||||
required: true
|
|
||||||
}],
|
|
||||||
supportedGames: ['IW4'],
|
|
||||||
execute: (gameEvent) => {
|
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
sendScriptCommand(gameEvent.Owner, 'Kill', gameEvent.Origin, gameEvent.Target, undefined);
|
},
|
||||||
}
|
{
|
||||||
},
|
name: 'alert',
|
||||||
{
|
description: 'alert a player',
|
||||||
name: 'nightmode',
|
alias: 'alr',
|
||||||
description: 'sets server into nightmode',
|
permission: 'SeniorAdmin',
|
||||||
alias: 'nitem',
|
targetRequired: true,
|
||||||
permission: 'SeniorAdmin',
|
arguments: [{
|
||||||
targetRequired: false,
|
name: 'player',
|
||||||
arguments: [],
|
required: true
|
||||||
supportedGames: ['IW4'],
|
},
|
||||||
execute: (gameEvent) => {
|
{
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
name: 'message',
|
||||||
return;
|
required: true
|
||||||
|
}],
|
||||||
|
supportedGames: ['IW4'],
|
||||||
|
execute: (gameEvent) => {
|
||||||
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendScriptCommand(gameEvent.Owner, 'Alert', gameEvent.Origin, gameEvent.Target, {
|
||||||
|
alertType: 'Alert',
|
||||||
|
message: gameEvent.Data
|
||||||
|
});
|
||||||
}
|
}
|
||||||
sendScriptCommand(gameEvent.Owner, 'NightMode', gameEvent.Origin, undefined, undefined);
|
},
|
||||||
}
|
{
|
||||||
},
|
name: 'gotoplayer',
|
||||||
{
|
description: 'teleport to a player',
|
||||||
name: 'setspectator',
|
alias: 'g2p',
|
||||||
description: 'sets a player as spectator',
|
permission: 'SeniorAdmin',
|
||||||
alias: 'spec',
|
targetRequired: true,
|
||||||
permission: 'Administrator',
|
arguments: [{
|
||||||
targetRequired: true,
|
name: 'player',
|
||||||
arguments: [{
|
required: true
|
||||||
name: 'player',
|
}],
|
||||||
required: true
|
supportedGames: ['IW4'],
|
||||||
}],
|
execute: (gameEvent) => {
|
||||||
supportedGames: ['IW4'],
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
execute: (gameEvent) => {
|
return;
|
||||||
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
}
|
||||||
return;
|
sendScriptCommand(gameEvent.Owner, 'Goto', gameEvent.Origin, gameEvent.Target, undefined);
|
||||||
}
|
}
|
||||||
sendScriptCommand(gameEvent.Owner, 'SetSpectator', gameEvent.Origin, gameEvent.Target, undefined);
|
},
|
||||||
}
|
{
|
||||||
}];
|
name: 'goto',
|
||||||
|
description: 'teleport to a position',
|
||||||
|
alias: 'g2',
|
||||||
|
permission: 'SeniorAdmin',
|
||||||
|
targetRequired: false,
|
||||||
|
arguments: [{
|
||||||
|
name: 'x',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'y',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'z',
|
||||||
|
required: true
|
||||||
|
}],
|
||||||
|
supportedGames: ['IW4'],
|
||||||
|
execute: (gameEvent) => {
|
||||||
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const args = String(gameEvent.Data).split(' ');
|
||||||
|
sendScriptCommand(gameEvent.Owner, 'Goto', gameEvent.Origin, gameEvent.Target, {
|
||||||
|
x: args[0],
|
||||||
|
y: args[1],
|
||||||
|
z: args[2]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'kill',
|
||||||
|
description: 'kill a player',
|
||||||
|
alias: 'kpl',
|
||||||
|
permission: 'SeniorAdmin',
|
||||||
|
targetRequired: true,
|
||||||
|
arguments: [{
|
||||||
|
name: 'player',
|
||||||
|
required: true
|
||||||
|
}],
|
||||||
|
supportedGames: ['IW4'],
|
||||||
|
execute: (gameEvent) => {
|
||||||
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendScriptCommand(gameEvent.Owner, 'Kill', gameEvent.Origin, gameEvent.Target, undefined);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'nightmode',
|
||||||
|
description: 'sets server into nightmode',
|
||||||
|
alias: 'nitem',
|
||||||
|
permission: 'SeniorAdmin',
|
||||||
|
targetRequired: false,
|
||||||
|
arguments: [],
|
||||||
|
supportedGames: ['IW4'],
|
||||||
|
execute: (gameEvent) => {
|
||||||
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendScriptCommand(gameEvent.Owner, 'NightMode', gameEvent.Origin, undefined, undefined);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'setspectator',
|
||||||
|
description: 'sets a player as spectator',
|
||||||
|
alias: 'spec',
|
||||||
|
permission: 'Administrator',
|
||||||
|
targetRequired: true,
|
||||||
|
arguments: [{
|
||||||
|
name: 'player',
|
||||||
|
required: true
|
||||||
|
}],
|
||||||
|
supportedGames: ['IW4'],
|
||||||
|
execute: (gameEvent) => {
|
||||||
|
if (!validateEnabled(gameEvent.Owner, gameEvent.Origin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendScriptCommand(gameEvent.Owner, 'SetSpectator', gameEvent.Origin, gameEvent.Target, undefined);
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
const sendScriptCommand = (server, command, origin, target, data) => {
|
const sendScriptCommand = (server, command, origin, target, data) => {
|
||||||
const state = servers[server.EndPoint];
|
const state = servers[server.EndPoint];
|
||||||
@ -301,34 +296,11 @@ const sendScriptCommand = (server, command, origin, target, data) => {
|
|||||||
|
|
||||||
const sendEvent = (server, responseExpected, event, subtype, origin, target, data) => {
|
const sendEvent = (server, responseExpected, event, subtype, origin, target, data) => {
|
||||||
const logger = _serviceResolver.ResolveService('ILogger');
|
const logger = _serviceResolver.ResolveService('ILogger');
|
||||||
|
const state = servers[server.EndPoint];
|
||||||
|
|
||||||
let pendingOut = true;
|
if (state.queuedMessages.length >= maxQueuedMessages) {
|
||||||
let pendingCheckCount = 0;
|
logger.WriteWarning('Too many queued messages so we are skipping');
|
||||||
const start = new Date();
|
return;
|
||||||
|
|
||||||
while (pendingOut && pendingCheckCount <= 10) {
|
|
||||||
if (server.Throttled) {
|
|
||||||
logger.WriteWarning('Server is throttled, so we are not attempting to send data');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const out = server.GetServerDvar(outDvar);
|
|
||||||
pendingOut = !(out == null || out === '' || out === 'null');
|
|
||||||
} catch (error) {
|
|
||||||
logger.WriteError(`Could not check server output dvar for IO status ${error}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pendingOut) {
|
|
||||||
logger.WriteDebug('Waiting for event bus to be cleared');
|
|
||||||
System.Threading.Tasks.Task.Delay(1000).Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
pendingCheckCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pendingOut) {
|
|
||||||
logger.WriteWarning(`Reached maximum attempts waiting for output to be available for ${server.EndPoint}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let targetClientNumber = -1;
|
let targetClientNumber = -1;
|
||||||
@ -337,31 +309,11 @@ const sendEvent = (server, responseExpected, event, subtype, origin, target, dat
|
|||||||
}
|
}
|
||||||
|
|
||||||
const output = `${responseExpected ? '1' : '0'};${event};${subtype};${origin.ClientNumber};${targetClientNumber};${buildDataString(data)}`;
|
const output = `${responseExpected ? '1' : '0'};${event};${subtype};${origin.ClientNumber};${targetClientNumber};${buildDataString(data)}`;
|
||||||
logger.WriteDebug(`Sending output to server ${output}`);
|
logger.WriteDebug(`Queuing output for server ${output}`);
|
||||||
|
|
||||||
try {
|
state.queuedMessages.push(output);
|
||||||
server.SetServerDvar(outDvar, output);
|
|
||||||
logger.WriteDebug(`SendEvent took ${(new Date() - start) / 1000}ms`);
|
|
||||||
} catch (error) {
|
|
||||||
logger.WriteError(`Could not set server output dvar ${error}`);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseEvent = (input) => {
|
|
||||||
if (input === undefined) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const eventInfo = input.split(';');
|
|
||||||
|
|
||||||
return {
|
|
||||||
eventType: eventInfo[1],
|
|
||||||
subType: eventInfo[2],
|
|
||||||
clientNumber: eventInfo[3],
|
|
||||||
data: eventInfo.length > 4 ? parseDataString(eventInfo[4]) : undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const initialize = (server) => {
|
const initialize = (server) => {
|
||||||
const logger = _serviceResolver.ResolveService('ILogger');
|
const logger = _serviceResolver.ResolveService('ILogger');
|
||||||
|
|
||||||
@ -371,7 +323,7 @@ const initialize = (server) => {
|
|||||||
|
|
||||||
let enabled = false;
|
let enabled = false;
|
||||||
try {
|
try {
|
||||||
enabled = server.GetServerDvar('sv_iw4madmin_integration_enabled') === '1';
|
enabled = server.GetServerDvar('sv_iw4madmin_integration_enabled', enableCheckTimeout) === '1';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.WriteError(`Could not get integration status of ${server.EndPoint} - ${error}`);
|
logger.WriteError(`Could not get integration status of ${server.EndPoint} - ${error}`);
|
||||||
}
|
}
|
||||||
@ -391,33 +343,36 @@ const initialize = (server) => {
|
|||||||
|
|
||||||
servers[server.EndPoint].timer = timer;
|
servers[server.EndPoint].timer = timer;
|
||||||
servers[server.EndPoint].enabled = true;
|
servers[server.EndPoint].enabled = true;
|
||||||
|
servers[server.EndPoint].waitingOnInput = false;
|
||||||
|
servers[server.EndPoint].waitingOnOutput = false;
|
||||||
|
servers[server.EndPoint].queuedMessages = [];
|
||||||
|
|
||||||
try {
|
setDvar(server, inDvar, '', onSetDvar);
|
||||||
server.SetServerDvar(inDvar, '');
|
setDvar(server, outDvar, '', onSetDvar);
|
||||||
server.SetServerDvar(outDvar, '');
|
|
||||||
} catch (error) {
|
|
||||||
logger.WriteError(`Could set default values bus dvars for ${server.EndPoint} - ${error}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
}
|
||||||
|
|
||||||
const pollForEvents = server => {
|
function onReceivedDvar(server, dvarName, dvarValue, success) {
|
||||||
if (server.Throttled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const logger = _serviceResolver.ResolveService('ILogger');
|
const logger = _serviceResolver.ResolveService('ILogger');
|
||||||
|
logger.WriteDebug(`Received ${dvarName}=${dvarValue} success=${success}`);
|
||||||
|
|
||||||
let input;
|
let input = dvarValue;
|
||||||
try {
|
const state = servers[server.EndPoint];
|
||||||
input = server.GetServerDvar(inDvar);
|
|
||||||
} catch (error) {
|
if (state.waitingOnOutput && dvarName === outDvar && isEmpty(dvarValue)) {
|
||||||
logger.WriteError(`Could not get input bus value for ${server.EndPoint} - ${error}`);
|
logger.WriteDebug('Setting out bus to read to send');
|
||||||
return;
|
// reset our flag letting use the out bus is open
|
||||||
|
state.waitingOnOutput = !success;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input === undefined || input === null || input === 'null') {
|
if (state.waitingOnInput && dvarName === inDvar) {
|
||||||
|
logger.WriteDebug('Setting in bus to ready to receive');
|
||||||
|
// we've received the data so now we can mark it as ready for more
|
||||||
|
state.waitingOnInput = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEmpty(input)) {
|
||||||
input = '';
|
input = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,24 +436,80 @@ const pollForEvents = server => {
|
|||||||
} else {
|
} else {
|
||||||
metaService.SetPersistentMeta(event.data['key'], event.data['value'], clientId).GetAwaiter().GetResult();
|
metaService.SetPersistentMeta(event.data['key'], event.data['value'], clientId).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
sendEvent(server, false, 'SetClientDataCompleted', 'Meta', {ClientNumber: event.clientNumber}, undefined,{status: 'Complete'});
|
sendEvent(server, false, 'SetClientDataCompleted', 'Meta', {ClientNumber: event.clientNumber}, undefined, {status: 'Complete'});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
sendEvent(server, false, 'SetClientDataCompleted', 'Meta', {ClientNumber: event.clientNumber}, undefined,{status: 'Fail'});
|
sendEvent(server, false, 'SetClientDataCompleted', 'Meta', {ClientNumber: event.clientNumber}, undefined, {status: 'Fail'});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
setDvar(server, inDvar, '', onSetDvar);
|
||||||
server.SetServerDvar(inDvar, '');
|
|
||||||
} catch (error) {
|
|
||||||
logger.WriteError(`Could not reset in bus value for ${server.EndPoint} - ${error}`);
|
|
||||||
}
|
|
||||||
} else if (server.ClientNum === 0) {
|
} else if (server.ClientNum === 0) {
|
||||||
servers[server.EndPoint].timer.Stop();
|
servers[server.EndPoint].timer.Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onSetDvar(server, dvarName, dvarValue, success) {
|
||||||
|
const logger = _serviceResolver.ResolveService('ILogger');
|
||||||
|
logger.WriteDebug(`Completed set of dvar ${dvarName}=${dvarValue}, success=${success}`);
|
||||||
|
|
||||||
|
const state = servers[server.EndPoint];
|
||||||
|
|
||||||
|
if (dvarName === inDvar && success && isEmpty(dvarValue)) {
|
||||||
|
logger.WriteDebug('In bus is ready for new data');
|
||||||
|
// reset our flag letting use the in bus is ready for more data
|
||||||
|
state.waitingOnInput = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const pollForEvents = server => {
|
||||||
|
const state = servers[server.EndPoint];
|
||||||
|
|
||||||
|
if (state === null || !state.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server.Throttled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state.waitingOnInput) {
|
||||||
|
state.waitingOnInput = true;
|
||||||
|
getDvar(server, inDvar, onReceivedDvar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state.waitingOnOutput) {
|
||||||
|
if (state.queuedMessages.length === 0) {
|
||||||
|
logger.WriteDebug('No messages in queue');
|
||||||
|
return;``
|
||||||
|
}
|
||||||
|
|
||||||
|
state.waitingOnOutput = true;
|
||||||
|
const nextMessage = state.queuedMessages.splice(0, 1);
|
||||||
|
setDvar(server, outDvar, nextMessage, onSetDvar);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.waitingOnOutput) {
|
||||||
|
getDvar(server, outDvar, onReceivedDvar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseEvent = (input) => {
|
||||||
|
if (input === undefined) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventInfo = input.split(';');
|
||||||
|
|
||||||
|
return {
|
||||||
|
eventType: eventInfo[1],
|
||||||
|
subType: eventInfo[2],
|
||||||
|
clientNumber: eventInfo[3],
|
||||||
|
data: eventInfo.length > 4 ? parseDataString(eventInfo[4]) : undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const buildDataString = data => {
|
const buildDataString = data => {
|
||||||
if (data === undefined) {
|
if (data === undefined) {
|
||||||
return '';
|
return '';
|
||||||
@ -534,7 +545,11 @@ const parseDataString = data => {
|
|||||||
const validateEnabled = (server, origin) => {
|
const validateEnabled = (server, origin) => {
|
||||||
const enabled = servers[server.EndPoint] != null && servers[server.EndPoint].enabled;
|
const enabled = servers[server.EndPoint] != null && servers[server.EndPoint].enabled;
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
origin.Tell("Game interface is not enabled on this server");
|
origin.Tell('Game interface is not enabled on this server');
|
||||||
}
|
}
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isEmpty(value) {
|
||||||
|
return value == null || false || value === '' || value === 'null';
|
||||||
|
}
|
||||||
|
@ -257,6 +257,7 @@ namespace SharedLibraryCore
|
|||||||
public EFClient Target;
|
public EFClient Target;
|
||||||
|
|
||||||
public EventType Type;
|
public EventType Type;
|
||||||
|
public string TypeName => Type.ToString();
|
||||||
|
|
||||||
public GameEvent()
|
public GameEvent()
|
||||||
{
|
{
|
||||||
|
@ -388,10 +388,10 @@ namespace SharedLibraryCore
|
|||||||
|
|
||||||
public abstract Task<long> GetIdForServer(Server server = null);
|
public abstract Task<long> GetIdForServer(Server server = null);
|
||||||
|
|
||||||
public string[] ExecuteServerCommand(string command)
|
public string[] ExecuteServerCommand(string command, int timeoutMs = 1000)
|
||||||
{
|
{
|
||||||
var tokenSource = new CancellationTokenSource();
|
var tokenSource = new CancellationTokenSource();
|
||||||
tokenSource.CancelAfter(TimeSpan.FromSeconds(0.5));
|
tokenSource.CancelAfter(TimeSpan.FromSeconds(timeoutMs));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -403,10 +403,10 @@ namespace SharedLibraryCore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetServerDvar(string dvarName)
|
public string GetServerDvar(string dvarName, int timeoutMs = 1000)
|
||||||
{
|
{
|
||||||
var tokenSource = new CancellationTokenSource();
|
var tokenSource = new CancellationTokenSource();
|
||||||
tokenSource.CancelAfter(TimeSpan.FromSeconds(0.5));
|
tokenSource.CancelAfter(TimeSpan.FromSeconds(timeoutMs));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return this.GetDvarAsync<string>(dvarName, token: tokenSource.Token).GetAwaiter().GetResult().Value;
|
return this.GetDvarAsync<string>(dvarName, token: tokenSource.Token).GetAwaiter().GetResult().Value;
|
||||||
@ -417,10 +417,10 @@ namespace SharedLibraryCore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetServerDvar(string dvarName, string dvarValue)
|
public bool SetServerDvar(string dvarName, string dvarValue, int timeoutMs = 1000)
|
||||||
{
|
{
|
||||||
var tokenSource = new CancellationTokenSource();
|
var tokenSource = new CancellationTokenSource();
|
||||||
tokenSource.CancelAfter(TimeSpan.FromSeconds(0.5));
|
tokenSource.CancelAfter(TimeSpan.FromSeconds(timeoutMs));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.SetDvarAsync(dvarName, dvarValue, tokenSource.Token).GetAwaiter().GetResult();
|
this.SetDvarAsync(dvarName, dvarValue, tokenSource.Token).GetAwaiter().GetResult();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user