Skip to content

Commit

Permalink
Update all commands up to H
Browse files Browse the repository at this point in the history
  • Loading branch information
RussellLVP committed Jul 31, 2020
1 parent a71d3ac commit a4c1e83
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 435 deletions.
7 changes: 5 additions & 2 deletions javascript/components/commands/default_permission_delegate.js
Expand Up @@ -16,10 +16,13 @@ export class DefaultPermissionDelegate extends CommandPermissionDelegate {

let access = null;

if (typeof command.restrictLevel === 'function')
if (typeof command.restrictLevel === 'function') {
access = command.restrictLevel(context);
else
} else {
access = command.restrictLevel <= contextDelegate.getLevel(context);
if (access && command.restrictTemporary && context.levelIsTemporary)
access = false;
}

if (!access && verbose) {
const requiredLevel = this.textualRepresentationForLevel(command.restrictLevel);
Expand Down
15 changes: 8 additions & 7 deletions javascript/features/death_match/death_match_commands.js
Expand Up @@ -2,22 +2,23 @@
// Use of this source code is governed by the MIT license, a copy of which can
// be found in the LICENSE file.

import { CommandBuilder } from 'components/command_manager/command_builder.js';
import { CommandBuilder } from 'components/commands/command_builder.js';
import { DeathMatchLocation } from 'features/death_match/death_match_location.js';
import { Menu } from 'components/menu/menu.js';

// Contains the /dm command for players to allow to teleport to a DM zone with specific weapons.
export class DeathMatchCommands {

constructor(limits, manager) {
server.deprecatedCommandManager.buildCommand('deathmatch')
.parameters([{ name: 'zone', type: CommandBuilder.NUMBER_PARAMETER, optional: true }])
server.commandManager.buildCommand('deathmatch')
.description('Enter one of the deathmatch zones.')
.sub('leave')
.description(`Leave the deathmatch zone you're in.`)
.build(DeathMatchCommands.prototype.onLeaveCommand.bind(this))
.sub('stats')
.description('See fighting statistics of your time in the zone.')
.build(DeathMatchCommands.prototype.onStatsCommand.bind(this))

.build(DeathMatchCommands.prototype.onDmCommand.bind(this));
.parameters([{ name: 'zone', type: CommandBuilder.kTypeNumber, optional: true }])
.build(DeathMatchCommands.prototype.onDmCommand.bind(this));

this.limits_ = limits;
this.manager_ = manager;
Expand Down Expand Up @@ -71,6 +72,6 @@ export class DeathMatchCommands {

// Cleans up the state created by this class, i.e. removes the command.
dispose() {
server.deprecatedCommandManager.removeCommand('deathmatch');
server.commandManager.removeCommand('deathmatch');
}
}
280 changes: 62 additions & 218 deletions javascript/features/debug/debug.js
Expand Up @@ -2,242 +2,86 @@
// Use of this source code is governed by the MIT license, a copy of which can
// be found in the LICENSE file.

import { CommandBuilder } from 'components/command_manager/command_builder.js';
import { CommandBuilder } from 'components/commands/command_builder.js';
import { Feature } from 'components/feature_manager/feature.js';

import InteriorList from 'features/debug/interiors.js';

// Utility function to return |value| in |len| digits, left-padded with zeros when necessary.
function leftPad(value, len = 2) {
return ('0' + value).slice(-2);
}

// The debug feature offers useful tools for administrators to debug the server or the Las Venturas
// Playground gamemode itself. It's driven by a number of in-game comments.
class Debug extends Feature {
constructor() {
super();

// /serverfps
server.deprecatedCommandManager.buildCommand('serverfps')
.restrict(Player.LEVEL_ADMINISTRATOR)
.build(this.__proto__.serverFrameCounter.bind(this));

// /trace [seconds]
server.deprecatedCommandManager.buildCommand('trace')
.restrict(Player.LEVEL_MANAGEMENT)
.parameters([{ name: 'seconds', type: CommandBuilder.NUMBER_PARAMETER }])
.build(this.__proto__.captureTrace.bind(this));

// /sound [id]
server.deprecatedCommandManager.buildCommand('sound')
.restrict(Player.LEVEL_MANAGEMENT)
.parameters([{ name: 'sound', type: CommandBuilder.NUMBER_PARAMETER }])
.build(this.__proto__.playSound.bind(this));

// /int [id]
server.deprecatedCommandManager.buildCommand('int')
.restrict(Player.LEVEL_ADMINISTRATOR)
.parameters([ { name: 'id', type: CommandBuilder.NUMBER_PARAMETER } ])
.build(this.__proto__.int.bind(this));

// /cam
server.deprecatedCommandManager.buildCommand('cam')
.restrict(Player.LEVEL_ADMINISTRATOR)
.build(this.__proto__.cam.bind(this));

// /eval
server.deprecatedCommandManager.buildCommand('eval')
.restrict(Player.LEVEL_MANAGEMENT)
.parameters([ { name: 'command', type: CommandBuilder.SENTENCE_PARAMETER } ])
.build(this.__proto__.eval.bind(this));

// /idlers
server.deprecatedCommandManager.buildCommand('idlers')
.restrict(Player.LEVEL_ADMINISTRATOR)
.build(this.__proto__.idlers.bind(this));

// /pattach
server.deprecatedCommandManager.buildCommand('pattach')
.restrict(Player.LEVEL_MANAGEMENT)
.parameters([ { name: 'player', type: CommandBuilder.PLAYER_PARAMETER },
{ name: 'model', type: CommandBuilder.NUMBER_PARAMETER },
{ name: 'x', type: CommandBuilder.NUMBER_PARAMETER },
{ name: 'y', type: CommandBuilder.NUMBER_PARAMETER },
{ name: 'z', type: CommandBuilder.NUMBER_PARAMETER } ])
.build(this.__proto__.attach.bind(this));

// /pdetach
server.deprecatedCommandManager.buildCommand('pdetach')
.restrict(Player.LEVEL_MANAGEMENT)
.parameters([ { name: 'player', type: CommandBuilder.PLAYER_PARAMETER } ])
.build(this.__proto__.detach.bind(this));

this.attachedObjects_ = new Map();

server.playerManager.addObserver(this);
}

// Displays the number of FPS the server was able to handle since the last call to this command.
serverFrameCounter(player) {
let stats = global.frameCounter(),
message = Message.format(Message.DEBUG_FRAME_COUNTER, stats.fps, stats.duration / 1000);

player.sendMessage(message)
}

// Captures a trace for |seconds| (which must be in range of [0, 300]) and stores it to the
// trace.log.[DMYHIS] file in the server's root directory.
captureTrace(player, seconds) {
if (typeof seconds !== 'number' || seconds < 0 || seconds > 300) {
player.sendMessage(Message.DEBUG_TRACE_INVALID_TIME);
return;
export default class Debug extends Feature {
constructor() {
super();

// /serverfps
server.commandManager.buildCommand('serverfps')
.description(`Displays the current performance of the server.`)
.restrict(Player.LEVEL_ADMINISTRATOR)
.build(Debug.prototype.onServerFrameCounterCommand.bind(this));

// /eval
server.commandManager.buildCommand('eval')
.description(`Evaluates JavaScript code on the server.`)
.restrict(Player.LEVEL_MANAGEMENT)
.parameters([ { name: 'command', type: CommandBuilder.kTypeText } ])
.build(Debug.prototype.onEvaluateCommand.bind(this));

// /idlers
server.commandManager.buildCommand('idlers')
.description('Displays a list of players who are currently idle.')
.restrict(Player.LEVEL_ADMINISTRATOR)
.build(Debug.prototype.idlers.bind(this));
}

let date = new Date(),
filename = 'trace.log.';

filename += date.getUTCFullYear() + leftPad(date.getUTCMonth() + 1) + leftPad(date.getUTCDate());
filename += leftPad(date.getUTCHours()) + leftPad(date.getUTCMinutes()) +
leftPad(date.getUTCSeconds());

global.startTrace();
wait(seconds * 1000).then(() => {
global.stopTrace(filename);

if (player.isConnected())
player.sendMessage(Message.DEBUG_TRACE_FINISHED);
});

player.sendMessage(Message.DEBUG_TRACE_STARTED);
}
// Displays the number of FPS the server was able to handle since the last call to this command.
onServerFrameCounterCommand(player) {
const statistics = global.frameCounter();

// Plays |soundId| for all in-game players.
playSound(player, soundId) {
server.playerManager.forEach(p => p.playSound(soundId));
}

// Teleports the player to the interior identified by |id|. Only available to administrators.
int(player, id) {
if (id < 0 || id >= InteriorList.length) {
player.sendMessage(Message.COMMAND_USAGE, '/int [0-' + (InteriorList.length - 1) + ']');
return;
player.sendMessage(Message.DEBUG_FRAME_COUNTER, statistics.fps, statistics.duration / 1000);
}

const interiorInfo = InteriorList[id];

player.position = interiorInfo.position;
player.rotation = interiorInfo.rotation;
player.interiorId = interiorInfo.interior;

player.sendMessage(Message.COMMAND_SUCCESS, 'You have been teleported to ' + interiorInfo.name);
}

// Has the player spectate their current position.
cam(player) {
player.setSpectating(true);

const position = player.position;
const camera = new Vector(position.x, position.y, position.z + 10);

player.setCamera(camera, position);

wait(5000).then(() => player.setSpectating(false));
}
// Evaluates the |command| on behalf of |player|.
onEvaluateCommand(player, command) {
console.log('[JavaScript] Evaluating: ' + command);

// Evaluates the |command| on behalf of |player|.
eval(player, command) {
console.log('[JavaScript] Evaluating: ' + command);
// Utility functions that are often used with the `/eval` command.
const cm = server.commandManager;
const fm = server.featureManager;
const p = playerId => server.playerManager.getById(playerId);
const vid = playerId => pawnInvoke('GetPlayerVehicleID', 'i', playerId);
const v = playerId => server.playerManager.getById(playerId).vehicle;

// Utility functions that are often used with the `/eval` command.
const cm = server.deprecatedCommandManager;
const fm = server.featureManager;
const p = playerId => server.playerManager.getById(playerId);
const vid = playerId => pawnInvoke('GetPlayerVehicleID', 'i', playerId);
const v = playerId => server.playerManager.getById(playerId).vehicle;
try {
const output = '' + JSON.stringify(eval(command), null, ' ');
const lines = output.split('\n');

try {
const output = '' + JSON.stringify(eval(command), null, ' ');
const lines = output.split('\n');
for (let i = 0; i < Math.min(8, lines.length); ++i)
player.sendMessage('>> ' + lines[i]);

for (let i = 0; i < Math.min(8, lines.length); ++i) {
player.sendMessage('>> ' + lines[i]);
}
if (lines.length > 8)
player.sendMessage('>> Omitted ' + (lines.length - 8) + ' lines.');

if (lines.length > 8)
player.sendMessage('>> Omitted ' + (lines.length - 8) + ' lines.');
} catch (error) {
player.sendMessage('>> ' + error.name + ': ' + error.message);
} catch (error) {
player.sendMessage('>> ' + error.name + ': ' + error.message);
}
}
}

// Lists the players who currently have minimized their game.
idlers(player) {
const idlers = [];
// Lists the players who currently have minimized their game.
idlers(player) {
const idlers = [];

for (const player of server.playerManager) {
if (player.isMinimized())
idlers.push(player.name);
}

if (!idlers.length)
player.sendMessage('Nobody minimized their game.');
else
player.sendMessage('Minimized: ' + idlers.sort().join(', '));
}

// Called when the |player| disconnects from the server.
onPlayerDisconnect(player) {
if (!this.attachedObjects_.has(player))
return;

for (const objectId of this.attachedObjects_.get(player))
pawnInvoke('DestroyObject', 'i', objectId);

this.attachedObjects_.delete(player);
}

// Attaches the object with |modelId| to the |subject| at the given offset.
attach(player, subject, modelId, x, y, z) {
if (!this.attachedObjects_.has(subject))
this.attachedObjects_.set(subject, new Set());

const objectId = pawnInvoke('CreateObject', 'ifffffff', modelId, 0, 0, 0, 0, 0, 0, 0);
this.attachedObjects_.get(subject).add(objectId);
for (const player of server.playerManager) {
if (player.isMinimized())
idlers.push(player.name);
}

pawnInvoke('AttachObjectToPlayer', 'iiffffff', objectId, subject.id, x, y, z, 0, 0, 0);

player.sendMessage('Done!');
}

// Removes all attached objects from the |subject|.
detach(player, subject) {
this.onPlayerDisconnect(subject);

player.sendMessage('Done!');
}

dispose() {
server.playerManager.removeObserver(this);

for (const [player, objects] of this.attachedObjects_) {
for (const objectId of objects)
pawnInvoke('DestroyObject', 'i', objectId);
if (!idlers.length)
player.sendMessage('Nobody minimized their game.');
else
player.sendMessage('Minimized: ' + idlers.sort().join(', '));
}

this.attachedObjects_.clear();
this.attachedObjects_ = null;

server.deprecatedCommandManager.removeCommand('serverfps')
server.deprecatedCommandManager.removeCommand('trace')
server.deprecatedCommandManager.removeCommand('sound')
server.deprecatedCommandManager.removeCommand('int')
server.deprecatedCommandManager.removeCommand('cam')
server.deprecatedCommandManager.removeCommand('eval')
server.deprecatedCommandManager.removeCommand('idlers')
server.deprecatedCommandManager.removeCommand('pattach')
server.deprecatedCommandManager.removeCommand('pdetach')
}
dispose() {
server.commandManager.removeCommand('serverfps');
server.commandManager.removeCommand('eval');
server.commandManager.removeCommand('idlers');
}
}

export default Debug;

0 comments on commit a4c1e83

Please sign in to comment.