Scripter is an extension that introduces scripting support to PETEP.
Scripting is based on GraalVM Polyglot. One of the greatest advantages is that you can use Java libraries in the code, so you can also use PETEP utils etc.
Since GraalVM 22.2, JavaScript is no longer installed by default, so you have to install it using the following command:
gu install js
For more information, see GraalVM 22.2 Release Notes
If you edit a File script, you have to reload the script in the PETEP UI.
All scripts are persisted in Groups. You have to define these groups and bind them with specific Scripter interceptors to make them work.
Be aware that scripts are potentially dangerous and can break PETEP (like extensions). Scripts should never register any listeners, receivers etc. in PETEP, because scripts can be reloaded and this would break it.
Scripter currently has the following interface accessible through "scripter" variable:
Use PETEP's Java utils to work with the PDUs. This can be achieved using the Java.type function:
const PduUtils = Java.type('com.warxim.petep.util.PduUtils');
const BytesUtils = Java.type('com.warxim.petep.util.BytesUtils');
Take full advantage of Java interoperability, see GraalVM Java Interoperability
In order to specify, which PDUs should be processed using scripts, you can tag them using the following tags (all PDUs are processed by default):
The following examples are part of Example preset. There are three scripts - simple replacer, logging interceptor and colorizing interceptor.
This simple script uses JavaScript to process custom replacement. (Replaces bytes at specific index with given data.)
// Imports
const BytesUtils = Java.type('com.warxim.petep.util.BytesUtils');
// Config
const NEW_DATA = BytesUtils.hexStringToBytes('3A 29');
const TARGET_INDEX = 2;
const TARGET_LENGTH = NEW_DATA.length;
const TARGET_TAG = 'tag-1';
// Replacer
scripter.registerInterceptor({
intercept: function(pdu, helper) {
const buffer = pdu.getBuffer();
if (!pdu.hasTag(TARGET_TAG)) {
return true;
}
for (let i = 0; i < TARGET_LENGTH; ++i) {
buffer[TARGET_INDEX + i] = NEW_DATA[i];
}
return true;
}
});
This simple script uses logger and PduUtils to print information about PDUs to console.
var config = {};
config.messages = {
init: 'Script initialized!'
};
config.log = {
type: true,
size: true,
proxy: true,
connection: true,
interceptor: false,
destination: true,
tags: true,
buffer: false
};
// Import config script
scripter.require('log-config.js');
// Load PETEP utils
const PduUtils = Java.type('com.warxim.petep.util.PduUtils');
// Load Java utils
const StringJoiner = Java.type('java.util.StringJoiner');
const ArrayList = Java.type('java.util.ArrayList');
// Obtain logger
const log = scripter.getLogger();
log.info(config.messages.init);
// Register info interceptor
scripter.registerInterceptor({
intercept: function(pdu, helper) {
var information = '';
if (config.log.type) {
information += '
- type: ' + pdu.getClass().getSimpleName();
}
if (config.log.destination) {
information += '
- destination: ' + pdu.getDestination();
}
if (config.log.proxy) {
let proxy = pdu.getProxy();
information += '
- proxy: ' + proxy.getName() + ' (' + proxy.getCode() + ')';
}
if (config.log.connection) {
let connection = pdu.getConnection();
information += '
- connection: ' + connection.getCode();
}
if (config.log.interceptor) {
let interceptor = pdu.getLastInterceptor();
information += '
- last interceptor: ' + interceptor.getName() + ' (' + interceptor.getCode() + ')';
}
if (config.log.size) {
information += '
- size: ' + pdu.getSize();
}
if (config.log.tags) {
let tagJoiner = new StringJoiner(', ');
pdu.getTags().forEach(tagJoiner.add);
information += '
- tags: ' + tagJoiner.toString();
}
if (config.log.buffer) {
information += '
- buffer: ' + PduUtils.bufferToHexString(pdu);
}
if (information.length > 0) {
log.info('PDU information: ' + information);
}
return true;
}
});
This simple script uses PduUtils and BytesUtils to replace colors in the PDU data.
var config = {};
config.colors = {
'#383b53': '#533838',
'#b4b9e6': '#e6b4b4',
'#8e96d9': '#d98e8e',
'#33364b': '#4b3333',
'#1f2639': '#391f1f',
'#403e66': '#663e3e',
'#daddf3': '#f3dada',
'#edeff9': '#f9eded',
'#f9f9fd': '#fdf9f9',
'#f7f8fc': '#fcf7f7',
'rgba(142,150,217,0.25)': 'rgba(217,142,142,0.25)'
}
// Import config script
scripter.require('color-config.js');
// Load PETEP utils
const PduUtils = Java.type('com.warxim.petep.util.PduUtils');
const BytesUtils = Java.type('com.warxim.petep.util.BytesUtils');
// Register colorize interceptor
scripter.registerInterceptor({
intercept: function(pdu, helper) {
if (pdu.getProxy().getCode() !== 'petep') {
return;
}
for (let currentColor in config.colors) {
let newColor = config.colors[currentColor];
PduUtils.replace(
pdu,
BytesUtils.getBytes(currentColor),
BytesUtils.getBytes(newColor)
);
}
return true;
}
});