Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Report illegal vehicle entry to administrators
- Loading branch information
1 parent
3cb3438
commit c5e8fe2
Showing
7 changed files
with
209 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// Copyright 2016 Las Venturas Playground. All rights reserved. | ||
// Use of this source code is governed by the MIT license, a copy of which can | ||
// be found in the LICENSE file. | ||
|
||
// The abuse monitor keeps an eye out for players who may abuse something on Las Venturas Playground | ||
// and informs administrators of the event when something has been detected. | ||
// | ||
// The abuse monitor is able to detect the following kinds of abuse: | ||
// 1) Illegal vehicle entry: entering a vehicle that is locked for the player. | ||
// | ||
class AbuseMonitor { | ||
constructor(announce, settings) { | ||
this.announce_ = announce; | ||
this.settings_ = settings; | ||
|
||
this.detected_ = new Map([ | ||
[ AbuseMonitor.TYPE_ILLEGAL_VEHICLE_ENTRY, new WeakMap() ] | ||
]); | ||
|
||
server.playerManager.addObserver(this); | ||
} | ||
|
||
// --------------------------------------------------------------------------------------------- | ||
|
||
// Returns the maximum number of times to report a particular warning about a particular player. | ||
getReportLimit() { return this.settings_().getValue('abuse/warning_report_limit'); } | ||
|
||
// --------------------------------------------------------------------------------------------- | ||
|
||
// Reports that the |player| has been detected for abusing |type|. Administrators will receive | ||
// a configurable amount of warnings for the |player, type| tuple as well. | ||
reportAbuse(player, type) { | ||
const incidents = (this.detected_.get(type).get(player) || 0) + 1; | ||
if (incidents <= this.getReportLimit()) { | ||
const incidentDescription = this.getTypeDescription(type); | ||
const incidentOrdinal = incidents.toOrdinalString(); | ||
|
||
this.announce_().announceToAdministrators( | ||
Message.ABUSE_ANNOUNCE_DETECTED, player.name, player.id, incidentDescription, | ||
incidentOrdinal); | ||
} | ||
|
||
// Do keep track of the new number of incidents for the |player|. | ||
this.detected_.get(type).set(player, incidents); | ||
} | ||
|
||
// Returns the number of times the |player| has been caught for the various kinds of abuse. | ||
getPlayerStatistics(player) { | ||
// Utility function that returns the number of times |player| has been caught for |type|. | ||
const createEntryForType = type => | ||
[ this.getTypeDescription(type), this.detected_.get(type).get(player) || 0 ]; | ||
|
||
return new Map([ | ||
createEntryForType(AbuseMonitor.TYPE_ILLEGAL_VEHICLE_ENTRY) | ||
]); | ||
} | ||
|
||
// Gets the textual description for the abuse |type|. | ||
getTypeDescription(type) { | ||
switch (type) { | ||
case AbuseMonitor.TYPE_ILLEGAL_VEHICLE_ENTRY: | ||
return 'illegal vehicle entry'; | ||
default: | ||
throw new Error('Unknown abuse type given: ' + type); | ||
} | ||
} | ||
|
||
// --------------------------------------------------------------------------------------------- | ||
|
||
// Called when the |player| enters the |vehicle|. Will report them for abuse when the vehicle | ||
// was locked for them, and entry therefore shouldn't have been possible. | ||
onPlayerEnterVehicle(player, vehicle) { | ||
if (vehicle.isLockedForPlayer(player)) | ||
this.reportAbuse(player, AbuseMonitor.TYPE_ILLEGAL_VEHICLE_ENTRY); | ||
} | ||
|
||
// --------------------------------------------------------------------------------------------- | ||
|
||
dispose() { | ||
server.playerManager.removeObserver(this); | ||
} | ||
} | ||
|
||
// The different sorts of abuse that can be detected by the monitor. | ||
AbuseMonitor.TYPE_ILLEGAL_VEHICLE_ENTRY = 0; | ||
|
||
exports = AbuseMonitor; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// Copyright 2016 Las Venturas Playground. All rights reserved. | ||
// Use of this source code is governed by the MIT license, a copy of which can | ||
// be found in the LICENSE file. | ||
|
||
const AbuseMonitor = require('features/abuse/abuse_monitor.js'); | ||
|
||
describe('AbuseMonitor', (it, beforeEach) => { | ||
let monitor = null; | ||
let settings = null; | ||
|
||
beforeEach(() => { | ||
monitor = server.featureManager.loadFeature('abuse').monitor_; | ||
settings = server.featureManager.loadFeature('settings'); | ||
}); | ||
|
||
it('should be able to detect and report illegal vehicle entry', assert => { | ||
const gunther = server.playerManager.getById(0 /* Gunther */); | ||
const russell = server.playerManager.getById(1 /* Russell */); | ||
|
||
russell.identify(); | ||
russell.level = Player.LEVEL_ADMINISTRATOR; | ||
|
||
const vehicle = server.vehicleManager.createVehicle({ | ||
modelId: 441, | ||
position: new Vector(200, 300, 50) | ||
}); | ||
|
||
vehicle.lockForPlayer(gunther); | ||
|
||
// (1) Make sure that the abuse can be detected. | ||
{ | ||
assert.isTrue(vehicle.isLockedForPlayer(gunther)); | ||
|
||
// Force |gunther| in the |vehicle|. This roughly matches how cheats enter vehicles. | ||
gunther.enterVehicle(vehicle); | ||
|
||
// Make sure that |russell| has received a warning about the incident. | ||
assert.equal(russell.messages.length, 1); | ||
assert.isTrue( | ||
russell.messages[0].includes( | ||
Message.format(Message.ABUSE_ANNOUNCE_DETECTED, gunther.name, gunther.id, | ||
'illegal vehicle entry', '1st'))); | ||
|
||
// Make sure that the incident has been reported in |gunther|'s statistics. | ||
const statistics = monitor.getPlayerStatistics(gunther); | ||
assert.equal(statistics.get('illegal vehicle entry'), 1); | ||
} | ||
|
||
// (2) Make sure that the warnings setting will be respected. | ||
{ | ||
settings.setValue('abuse/warning_report_limit', 10); | ||
assert.equal(monitor.getReportLimit(), 10); | ||
|
||
// Incidents should be reported up to the 10th time. | ||
for (let i = 2; i <= 10; ++i) { | ||
gunther.enterVehicle(vehicle); | ||
assert.equal(russell.messages.length, i); | ||
} | ||
|
||
// The next incidents should not be reported to administrators anymore. | ||
assert.equal(russell.messages.length, 10); | ||
|
||
gunther.enterVehicle(vehicle); | ||
gunther.enterVehicle(vehicle); | ||
gunther.enterVehicle(vehicle); | ||
gunther.enterVehicle(vehicle); | ||
|
||
assert.equal(russell.messages.length, 10); | ||
|
||
const statistics = monitor.getPlayerStatistics(gunther); | ||
assert.equal(statistics.get('illegal vehicle entry'), 14); | ||
} | ||
|
||
}); | ||
|
||
it('should gather and have names for all sorts of abuse', assert => { | ||
const gunther = server.playerManager.getById(0 /* Gunther */); | ||
const types = new Set(); | ||
|
||
for (const name of Object.getOwnPropertyNames(AbuseMonitor)) { | ||
if (name.startsWith('TYPE_')) | ||
types.add(AbuseMonitor[name]); | ||
} | ||
|
||
assert.isAbove(types.size, 0); | ||
|
||
// (1) Verify that all types have a description. | ||
{ | ||
for (const type of types) | ||
assert.equal(typeof monitor.getTypeDescription(type), 'string'); | ||
} | ||
|
||
// (2) Verify that all types are included in the statistics. | ||
{ | ||
const statistics = monitor.getPlayerStatistics(gunther); | ||
|
||
for (const type of types) | ||
assert.isTrue(statistics.has(monitor.getTypeDescription(type))); | ||
} | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters