Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
disgamekit
Advanced tools
A small package that will help making ts/js discord bot mini games way easier!
A small package that will help making ts/js discord bot mini games way easier! (placeholder for game example)
npm i disgamekit
id
: The unique identifier for the game.const { Game } = require('disgamekit');
const game = new Game('gameId');
start
Starts the game and emit's the "start" event.
game.start();
isGameOn
Returns game's current state
console.log(game.isGameOn()); // false
game.start();
console.log(game.isGameOn()); // true
end
Ends the game and emit's the "end" event.
interaction
:(optional) Interaction associated with the gamecustom
:(optional) Pass a custom string to be sent to the event listener.plane
:(optional) Pass the plane to be reset.game.start();
console.log(game.isGameOn()); // true
game.end(interaction); // so that when the end event is emitted you can edit an embed or do something to a message.
console.log(game.isGameOn()); // false
Fired when the game starts
const { Game } = require('disgamekit');
let game = new Game('game');
game.on('start', () => {
console.log('Game sucessfully started!');
});
Fired when the game ends
const { Game } = require('disgamekit');
let game = new Game('game');
game.on('end', () => {
console.log('Game ended!');
});
game.end();
// If you have a component to end the game, you can edit the reply one last time.
game.on('end', (i) => {
i.update('Game has ended.');
});
game.end(interaction);
// And lastly if you used a custom message
game.on('end', (i, c) => {
i.update(c);
});
game.end(interaction, 'Game has ended.');
Fired when an error occurs.
const { Game } = require('disgamekit');
let game = new Game('game');
game.on('error', (error) => {
console.log('Error occured!' + error);
});
const gameId = 'game`';
const game = new Game(gameId);
game.on('start', () => {
console.log('Game started!');
});
game.on('end', () => {
console.log('Game ended!');
});
game.on('error', (error) => {
console.error('An error occurred with the game!:', error);
});
game.start();
In the example above, a new Game
instance is created with a game client and a unique ID. Event listeners are added for the start
, end
, and error
events. Lastly the game is started using game.start()
.
The Plane
class represents a grid-based 2d plane and provides methods to manage and manipulate objects on the plane. All objects refrenced can be found here
game
: The game instance associated with the plane.rows
: The number of rows in the plane.columns
: The number of columns in the plane.blank
:(optional) The default value for empty cells in the plane. Defaults to null
const { Game, Plane } = require('disgamekit');
const game = new Game('gameId');
const plane = new Plane(game, 5, 5, 'blank');
lookupObj
Looks up an object's coordinates based on its ID.
inputValue
:(optional) The ID of the object to be looked up on the plane.// If an object with the ID: qwert was at x:2 y: 6
plane.lookupObj('qwert'); // { x: 2, y: 6 }
lookupCoords
Looks up the value at the specified x and y coordinates on the plane
x
:(optional) The x-coordinate.y
:(optional) The y-coordinateplane.lookupCoords(2, 6); // "qwert"
clear
Clears the entire plane, removing all objects while preserving their coordinates.
plane.clear();
update
Adds/Updates/Removes Objects on the plane. If provided : It will update/add to the plane If not provided : It will clear the plane of any objects.
...arr
:(optional) Numerous objects to be updated on the plane.plane.update(object1, object2, object3, object4);
return
Reutrns a string representation of the plane, with optional row and column separators.
row
:(optional) The separator for rows. Defaults to an empty string.column
:(optional) The separator for columns. Defaults to a line break// For example, the plane has 5 rows and 5 columns
plane.return('', '\n');
/*
blank blank blank blank blank
blank blank blank blank blank
blank blank blank blank blank
blank blank blank blank blank
blank blank blank blank blank
*/
Represents an object to be placed on the plane.
plane
: Plane instance.x
: The object's origin on the x-axisy
: The object's origin on the y-axisid
: A unique identifier for the object.value
:(optional) The emoji or value to display on the plane for said object. Defaults to the object's ID.detectCollision
:(optional) Whether to detect collisions with other objects. Defaults to true
const { Plane, PlaneObject } = require('disgamekit');
let plane = new Plane(...)
let hat = new PlaneObject(plane, 0, 0, 'hat', '🧢');
Fired when foo
collides with a wall or another PlaneObject
instance
const { Game, PlaneObject, Plane } = require('disgamekit');
let game = new Game('game');
let plane = new Plane(game, 4, 4);
let object = new PlaneObject(plane, 2, 0, 'object');
object.on('colllision', (i) => {
console.log(`Object collided with ${i.id}!`);
});
const { Plane, PlaneObject } = require('disgamekit');
// Create a game instance
const game = new Game('gameId');
// Create a plane with 5 rows and 5 columns
const plane = new Plane(game, 5, 5);
// Create plane objects
const object1 = new PlaneObject(plane, 2, 2, 'obj1', 'A');
const object2 = new PlaneObject(plane, 3, 3, 'obj2', 'B');
// Update the plane with the objects
plane.update(object1, object2);
// Check for collision (This is called when collided with a wall, even if detectCollison = false.)
object1.on('collision', (i) => {
console.log(`${i} collided with object1!`);
});
// Lookup object coordinates
const coordinates1 = plane.lookupObj('obj1');
console.log('Object 1 coordinates:', coordinates1); // Output: Object 1 coordinates: { x: 2, y: 2 }
// Lookup value at coordinates
const value = plane.lookupCoords(3, 3);
console.log('Value at coordinates (3, 3):', value); // Output: Value at coordinates (3, 3): B
// Clear the plane
plane.clear();
// Update the plane with a single object
const object3 = new PlaneObject(plane, 1, 1, 'obj3', 'C');
plane.update(object3);
// Return the plane as a string
const planeString = plane.return(' ', '\n');
console.log(planeString);
/* Output:
null null null null null
null null null null null
null null C null null
null null null null null
null null null null null
*/
In the example above, we create a game instance and then create a Plane
instance with 5 rows and 5 columns. We create PlaneObject
instances (object1
and object2
) with origin coordinates and values. The plane is then updated with these objects using the update()
method.
We perform lookups on the plane using the lookupObj()
method to retrieve the coordinates of object1
, and the lookupCoords()
method to retrieve the value at coordinates (3, 3)
.
The plane is cleared using the clear()
method and then updated with a new object (object3
). Finally, we return the plane as a string representation using the return()
method and print it to the console.
// This works the same with interactions. But so that the code is not 6k lines long, I've used messages.
// Discord.js and disgamekit imports
const {
Client,
IntentsBitField,
EmbedBuilder,
ButtonBuilder,
ButtonStyle,
ActionRowBuilder,
} = require('discord.js');
const { Game, Plane, PlaneObject } = require('disgamekit');
const client = new Client({
intents: [
IntentsBitField.Flags.Guilds,
IntentsBitField.Flags.GuildMessages,
IntentsBitField.Flags.MessageContent,
],
});
client.on('ready', () => {
console.log(`${client.user.tag} is online`);
});
// var setup
const game = new Game(client, 'game');
game.var.score = 0;
const plane = new Plane(game, 10, 10, ':green_square:');
const moveable = new PlaneObject(
plane,
3,
3,
'moveable',
':blue_square:',
true
);
const nonmove = new PlaneObject(plane, 2, 2, 'nonmove', ':apple:');
// game controls
const row = new ActionRowBuilder().addComponents(
new ButtonBuilder()
.setCustomId('up')
.setLabel('up')
.setStyle(ButtonStyle.Secondary),
new ButtonBuilder()
.setCustomId('down')
.setLabel('down')
.setStyle(ButtonStyle.Secondary),
new ButtonBuilder()
.setCustomId('left')
.setLabel('left')
.setStyle(ButtonStyle.Secondary),
new ButtonBuilder()
.setCustomId('right')
.setLabel('right')
.setStyle(ButtonStyle.Secondary),
new ButtonBuilder()
.setCustomId('end')
.setLabel('end')
.setStyle(ButtonStyle.Danger)
);
client.on('messageCreate', async (m) => {
if (m.author.bot) return;
const message = m.content;
if (!message.includes('mjb?')) return;
let cmd = message.split('?');
switch (cmd[1]) {
case 'help':
m.reply('No.');
break;
case 'button':
game.start();
plane.update(moveable, nonmove); // show the initial state by updating the object to the grid before hand
await m.reply({
embeds: [
new EmbedBuilder()
.setTitle('g a m e')
.setDescription(plane.return()),
],
components: [row],
});
break;
}
});
// game events
game.on('start', () => {
console.log('Game started!');
});
game.on('end', async (i) => {
await i.update({
content: `game has ended! Your final score = ${game.var.score}`,
components: [],
embeds: [],
}); // clear buttons so no errors occur.
console.log('Game ended!');
});
moveable.on('collision', (obj) => {
// when the moveable collides with nonemoveable update the score, if wall, log it to the console.
if (obj.id == nonmove.id) {
game.var.score++;
} else if (obj.id == 'wall') {
// You can just use an if since it's 2 objects but i used an else if for documentation sake
console.log('Collision with wall!');
}
});
// game controls
client.on(`interactionCreate`, async (i) => {
switch (i.customId) {
case 'up':
moveable.y++;
await update(i, plane, moveable, nonmove);
break;
case 'down':
moveable.y--;
await update(i, plane, moveable, nonmove);
break;
case 'left':
moveable.x--;
await update(i, plane, moveable, nonmove);
break;
case 'right':
moveable.x++;
await update(i, plane, moveable, nonmove);
break;
case 'end':
game.end(i);
}
});
// helper function to make this 50 less lines.
async function update(i, plane, ...item) {
/*
you don't need to make a function like this
but due to my controls doing the same thing
over and, over again, I made it a function.
*/
await plane.update(...item);
await i.update({
embeds: [
new EmbedBuilder()
.setTitle(`g a m e`)
.setDescription(plane.return())
.setFooter({ text: `Score = ${game.var.score}` }),
],
components: [row],
});
}
// Login the Discord client with your token
client.login('your-token-here-bro');
This code sets up a Discord bot using the Discord.js library and integrates it with a game using the disgamekit library. Here's a breakdown of the major components:
The code initializes a game with a client, a plane, and plane objects. It also sets up game controls as buttons using an ActionRowBuilder
.
When a user sends a message with the command "mjb?button", the game starts, the plane is updated with the objects, and the game state is sent as a reply with the buttons.
The game responds to interactions with the buttons, updating the position of the moveable object and updating the game state accordingly.
The game emits events for "start", "end", and "collision", which can be handled to perform actions when these events occur. (Currently) the moveable
listens for the "collision" event and checks whether it collided with an object or the wall. If it's the wall it logs to the console. If it's the nonmove
object, it updates the game variables stored in game.var
.
The update
function is a helper function that updates the game state and updates the message with the new state and buttons.
NOTE - The code above is set up in a way that every user plays the same game . To avoid this either initialize the variables in the message create or use a map.
FAQs
A small package that will help making ts/js discord bot mini games way easier!
We found that disgamekit demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.