Plugins - Basic tutorial
Plugins are one of the core aspect Difys is built on, you could see it as an empty vessel without plugins. If you are uncertain of some specific cases or have trouble making your plugin, please don't be shy and ask people in the #dev-general channel of our discord.
You cannot make a plugin if you don't have the source code. That is why you need to be part of the dev team in order to follow this page.
Creating your core files
config
src/config/plugins/MyAwesomePlugin.json
Your plugin config file must be in the config folder of difys.
{
"disabled": false
}
package
~/plugin.json
It defines what our plugin is and what it needs.
{
"name": "MyAwesomePlugin",
"description": "",
"author": "Zirpoo",
"version": "0.0.1",
"requiredPlugins": [],
"dependencies": [],
"binaries": []
}
name
It should have the same as your folder name.
description
Just the big lines of what your plugin is going to achieve.
author
preferably the same as your discord name.
version
Since your plugin needs to be on gitlab or github, you need to show the version of your plugin.
requiredPlugins
If you use other plugins functions, you'll need to add the name of the plugin you need, just to be sure this plugin is initialized and not disabled.
dependencies
NodeJS dependencies your plugin will need.
binaries
Game data your plugin will need, here's the list:
AbuseReasons
AchievementCategories
AchievementObjectives
AchievementRewards
Achievements
ActionDescriptions
AlignmentBalance
AlignmentEffect
AlignmentGift
AlignmentOrder
AlignmentRank
AlignmentRankJntGift
AlignmentSides
AlignmentTitles
AlmanaxCalendars
Appearances
Areas
BidHouseCategories
Breeds
CensoredContents
CensoredWords
Challenge
ChatChannels
Documents
Dungeons
Effects
EmblemBackgrounds
EmblemSymbolCategories
EmblemSymbols
Emoticons
ExternalNotifications
Heads
HintCategory
Hints
Houses
Incarnation
IncarnationLevels
InfoMessages
Interactives
Items
ItemSets
ItemTypes
Jobs
LivingObjectSkinJntMood
MapCoordinates
MapPositions
MapReferences
MonsterMiniBoss
MonsterRaces
Monsters
MonsterSuperRaces
Months
MountBehaviors
MountBones
Mounts
Notifications
NpcActions
NpcMessages
Npcs
Ornaments
Pack
Pets
PresetIcons
QuestCategory
QuestObjectives
QuestObjectiveTypes
Quests
QuestStepRewards
QuestSteps
RankNames
Recipes
RideFood
ServerCommunities
ServerGameTypes
ServerPopulations
Servers
SkillNames
Skills
SkinMappings
Smileys
SoundBones
SoundUi
SoundUiHook
SpeakingItemsText
SpeakingItemsTriggers
SpellBombs
SpellLevels
Spells
SpellStates
SpellTypes
StealthBones
SubAreas
SubAreaIdPerCoordinate
SubAreasWorldMapData
SuperAreas
TaxCollectorFirstnames
TaxCollectorNames
Tips
TitleCategories
Titles
TypeActions
Url
WorldMaps
index
~/index.ts
import pluginPackage from "./plugin.json";
import logger from "../../lib/logger";
import Socket from "../../module/game/connection";
import Account from "../../type/account";
import { listenerFunction1 } from "./events";
export function mount() {
logger.info(`${pluginPackage.name} Plugin | Mounted`);
return true;
}
export function hook(account: Account) {
return true;
}
export function customFunction1(socket: Socket) {
// Do something with the socket
}
export const listeners = [listenerFunction1];
Everything you export will be available to be used. It's much like public/private functions.
mount() Boolean
This could be an async function and wait for data initialisation or any kind of requests. if it returns false, then this account is ignored and is not going to be connected.
hook(account) Boolean
This function is called when an account is added to the system. if it returns false, then this account is ignored and is not going to be connected.
listeners Function[]
List of events to listen on the socket.
events
~/events.ts
import mongoose from "mongoose";
import pluginPackage from "./plugin.json";
import Socket from "../../module/game/connection";
export function listenerFunction1(data: unknown, socket: Socket) {
const username = socket.account.username;
const model = mongoose.models.MyModelName;
model.findOneAndUpdate(
{
username,
"data._messageType": data._messageType
},
{ username, data },
{ upsert: true },
(error, document, result) => {
if (error) {
return logger.error(
`${pluginPackage.name} Plugin | Couldn't save data into the database`
);
}
}
);
}
Possibilities are endless and the concept of storing data in the database might frighten you, but I assure you it's a good idea. Since it makes possible for other plugins to read your data.
listenerFunction1 is just an example, keep in mind that you must name your function the same as the event name you want to listen to.
How to set my custom model into mongoose ?
You can create a file in ~/model/MyCustomModel.ts
and this file will be automatically detected by Difys.
Your model file must look like that:
import mongoose from "mongoose";
const Schema = mongoose.Schema;
mongoose.model(
"MyCustomModel",
new Schema({
// My data
})
);
If you don't know how to build your schema object, I can suggest to look at the mongoose documentation.