Skip to content

Commit

Permalink
Switch package to organization repository.
Browse files Browse the repository at this point in the history
Kodarru committed Oct 17, 2024
0 parents commit 10d70ab
Showing 19 changed files with 1,798 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* text eol=lf
*.png binary
Binary file added .github/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Publish
on:
push:
branches:
- main

jobs:
publish:
runs-on: ubuntu-latest

permissions:
contents: read
id-token: write

steps:
- uses: actions/checkout@v4

- name: Publish package
run: npx jsr publish
133 changes: 133 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

# VSCode
.vscode/*
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"tabWidth": 4,
"endOfLine": "lf",
"semi": true,
"printWidth": 120
}
105 changes: 105 additions & 0 deletions Example/Main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*!
* Callisto, a simple and powerful bot package for nin0-dev's chat server.
* Copyright (c) 2022 Kodarru and contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

// ******
// Import the necessary modules.
import { Client, type Callisto } from "../Source/Main.ts";

// ******

const client = new Client({
Bot: {
username: "YOUR_BOT_NAME",
key: "YOUR_BOT_KEY",
// Has no use implemented yet. Leave it as an empty array.
staleMessages: [],
},
Websocket: {
URI: "wss://guhws.nin0.dev",
Reconnect: true,
ReconnectMaxTrials: 5,
},
LogLevel: 2,
});

const Log = client.Logger;
let prefix = "!";

// This function will be called when the Websocket is opened.
client.On("open", () => {
Log.Info("Connection established!");
client.Send("Hello, world! My prefix is " + prefix + ". Type " + prefix + "help for a list of commands.");
});

// This function will be called when the Websocket receives a message.
client.On("message", (message: Callisto.Message) => {
// Will not respond to bots.
if (message.isBot()) return;
// Will not respond to itself.
if (message.isSelf()) return;

/*
* The message object has the following functions:
*
* isMod(): boolean; - Checks if the message was sent by a admin/mod.
* isBot(): boolean; - Checks if the message was sent by a bot.
* isDiscord(): boolean; - Checks if the message was sent from Discord.
* isUser(): boolean; - Checks if the message was sent by a user.
* isSelf(): boolean; - Checks if the message was sent by the bot.
* Send(content: string): void; - Sends a message to the chat.
* Reply(content: string): void; - Replies to the user who sent the message.
*/

// Check if the message starts with the prefix.
if (message.content?.startsWith(prefix)) {
// Split the message into an array of arguments.
// Example: !ping hello world
// Output: ["ping", "hello", "world"]
const args = message.content.slice(prefix.length).split(/ +/);
// Shift the first argument from the array.
// Example: ["ping", "hello", "world"]
// Output: "ping"
const command = args.shift()?.toLowerCase();

switch (command) {
case "ping":
// message.Reply will reply to the user who sent the message.
// Example: message.Reply("Pong!");
// Output: Replying to <username>: Pong!
message.Reply("Pong!");
break;
case "prefix":
prefix = args[0];
message.Reply("Prefix set to " + prefix);
break;
case "say":
// message.Send will send a message to the chat.
// Example: message.Send("Hello, world!");
// Output: Hello, world!
// Note: This will not reply to the user.
message.Send(args.join(" "));
break;
case "help":
message.Reply("Commands: help, ping, say, prefix");
break;
}
}
});

// Connects to the Websocket server.
client.Connect();
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

71 changes: 71 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<div align="center">
<h1>Callisto 🌙</h1>
<img src=".github/logo.png" width="200">
<br>
<b>This is what I think Callisto would look like. Made using <a href="https://deno.com">Deno's Dinosaur Creator.</a></b>
<hr>
<p>Check out <a href="https://github.com/nin0chat/Callisto/blob/main/Releases.md">Releases.md</a> for more information on <b>v0.1.1</b>!</p>
</div>

---

Callisto (getting it's name from Jupiter's second largest moon) is a simple, easy-to-use, and powerful Deno V2 library for creating and managing nin0chat bots. It only uses the `ws` library, everything else is built from scratch.

## Installation 📦

The installation is very simple, just run the following command in your terminal:

```bash
deno add jsr:@nin0chat/callisto
```

## Usage 📚

Here is a simple example of how to use Callisto:

```ts
import { Client, Callisto } from "@nin0chat/callisto";

const client = new Client({
Bot: {
username: "YOUR_BOT_NAME",
key: "YOUR_BOT_KEY",
staleMessages: [],
},
Websocket: {
URI: "wss://guhws.nin0.dev", // If you're using a different server, change this.
Reconnect: true,
ReconnectMaxTrials: 5,
},
LogLevel: 2,
});

const Log = client.Logger;

// This event is called when the bot connects to the server.
client.On("open", () => {
Log.Info("Connected to the server!");
client.Send("Hello, world!");
});

// This event is called when the bot receives a message.
client.On("message", (message: Callisto.Message) => {
// This is a simple example of how to check if the message is from a bot.
if (message.isBot()) return;

Log.Info("New message! " + message.content + " - " + message.username);
});

// Always put this at the end of your code (after you've registered all your events).
client.Connect();
```

Was this not enough? It's okay! We have a more in-depth example [here](https://github.com/nin0chat/Callisto/tree/main/Example).

## Documentation 📖

~~The documentation for Callisto can be found [here](https://github.com/nin0chat/Callisto/tree/main/Documentation).~~ There will be no documentation as of yet until the nin0chat rewrite is complete. Check out the [example](https://github.com/nin0chat/Callisto/tree/main/Example) or look at the JSDoc comments in the source code.

## License 📜

This project is licensed under the GNU General Public License v3.0. You can find the license [here](https://github.com/nin0chat/Callisto/blob/main/LICENSE).
39 changes: 39 additions & 0 deletions Releases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<div align="center">
<h1>Callisto 🌙</h1>
<img src=".github/logo.png" width="200">
<br>
<b>This is what I think Callisto would look like. Made using <a href="https://deno.com">Deno's Dinosaur Creator.</a></b>
</div>

---

## Version `0.1.1` 📝

- Added `<Client>.Once` method. This method is the same as `<Client>.On`, but it only runs once.
- Example:
```ts
client.Once("open", () => {
Log.Info("Connected to the server!");
});
```
- Added `<Client>.Off` method. This method is used to remove an event listener.
- Example:
```ts
const openEvent = () => {
Log.Info("Connected to the server!");
};
client.On("open", openEvent);
// This will remove the event listener.
client.Off("open", openEvent);
```
- Added more consistent documentation to the following files:
- `@/Main.ts`
- `@/Utilities/Types.ts`
- `@/Utilities/Logger.ts`

Update to this version by running the following command in your terminal:

```bash
deno upgrade jsr:@nin0chat/callisto@0.1.1
```
43 changes: 43 additions & 0 deletions Source/Handlers/Close.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*!
* Callisto, a simple and powerful bot package for nin0-dev's chat server.
* Copyright (c) 2022 Kodarru and contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

// ******

import type { Client } from "@/Main.ts";

// ******

export function On_Close(client: Client) {
return () => {
client.Emit("close", client);

if (client.DisconnectIntentional) return;

client.Logger.Warning("Connection closed unexpectedly. Attempting to reconnect...");

if (client.ReconnectAttempts >= client.WebsocketData.ReconnectMaxTrials) {
// prettier-ignore
client.Logger.Error("Unable to establish a connection with the server. Tried reconnecting " + client.ReconnectAttempts + " times.");
return;
}

client.ReconnectAttempts++;
client.Logger.Info("Starting reconnect attempt " + (client.ReconnectAttempts + 1) + "...");
client.Connect();
};
}
30 changes: 30 additions & 0 deletions Source/Handlers/Error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*!
* Callisto, a simple and powerful bot package for nin0-dev's chat server.
* Copyright (c) 2022 Kodarru and contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

// ******

import type { Client } from "@/Main.ts";

// ******

export function On_Error(error: string, client: Client) {
return () => {
client.Emit("error");
client.Logger.Error("An unexpected error occurred! " + error);
};
}
74 changes: 74 additions & 0 deletions Source/Handlers/Message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*!
* Callisto, a simple and powerful bot package for nin0-dev's chat server.
* Copyright (c) 2022 Kodarru and contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

// ******

import type { Client } from "@/Main.ts";
import type * as Callisto from "@/Utilities/Types.ts";
import * as Constants from "@/Utilities/Constants.ts";

// ******

export function On_Message(data: any, client: Client) {
client.Logger.Debug("Received new message");

const _data = JSON.parse(data.toString());

const patchedMessage = {
username: _data.username,
content: _data.content,
role: _data.role,
isMod: function () {
return _data.role === Constants.Roles.Admin;
},
isBot: function () {
return _data.role === Constants.Roles.Bot;
},
isDiscord: function () {
return _data.role === Constants.Roles.Discord;
},
isUser: function () {
return _data.role === Constants.Roles.User;
},
isSelf: function () {
return _data.username === client.ClientData.username;
},
Send: function (content: string) {
client.Send(content);
},
Reply: function (content: string) {
client.Send("Replying to " + _data.username + ": " + content);
},
};

/*
if (data.op === 10) {
client.Logger.Info("Found stale messages.");
data.messages?.forEach((message: Callisto.Message) => {
message.user = data.username;
message.stale = true;
client.StaleMessages.push(message);
});
return;
}
*/

client.Emit("message", patchedMessage);
}
29 changes: 29 additions & 0 deletions Source/Handlers/Open.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*!
* Callisto, a simple and powerful bot package for nin0-dev's chat server.
* Copyright (c) 2022 Kodarru and contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

// ******

import type { Client } from "@/Main.ts";

// ******

export function On_Open(client: Client) {
return () => {
client.Emit("open");
};
}
272 changes: 272 additions & 0 deletions Source/Main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
/*!
* Callisto, a simple and powerful bot package for nin0-dev"s chat server.
* Copyright (c) 2022 Kodarru and contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

// ******
// Import all the necessary modules.
import Websocket from "ws";
import { Logging } from "@/Utilities/Logging.ts";
import * as Callisto from "@/Utilities/Types.ts";

// Import the handlers.
import { On_Open } from "@/Handlers/Open.ts";
import { On_Close } from "@/Handlers/Close.ts";
import { On_Message } from "@/Handlers/Message.ts";

// *****
// Export types
export * as Callisto from "@/Utilities/Types.ts";

/**
* The main client class for Callisto.
*
* Example usage:
*
* ```typescript
* const client = new Client({
* Bot: {
* username: "Ko-Ko",
* key: "xxx",
* staleMessages: []
* },
* Websocket: {
* URI: "wss://guhws.nin0.dev",
* Reconnect: true,
* ReconnectMaxTrials: 5
* },
* LogLevel: 2
* });
* ```
*
* @param {Callisto.ClientData} Bot - The client data.
* ```json
* {
* username: "<Your bot's username>",
* key: "<Your bot's key>",
* staleMessages: []
* }
* ```
* @param {Callisto.WebsocketData} Websocket - The websocket data.
* ```json
* {
* URI: "<The URI of the websocket server>",
* Reconnect: true,
* ReconnectMaxTrials: 5
* }
* @param {1 | 2 | 3 | 4} [LogLevel=2] - The logging level. Defaults to 2.
* @returns {void}
*/

export class Client {
// Properties for the client class. (Required)
private WS: Websocket;
public Logger: Logging;
public ClientData: Callisto.ClientData;
public WebsocketData: Callisto.WebsocketData;

// Other properties.
public ReconnectAttempts: number = 0;
public DisconnectIntentional: boolean = false;

// Handlers are used for event handling. They are arrays of strings and functions.
// The strings are the event names, and the functions are the event handlers.
private Handlers: Array<(string | Function)[]>;

// OnceHandlers are used for one-time event handling. They are arrays of strings, functions, and booleans.
// The boolean is used to determine whether the event handler has been run.
private OnceHandlers: Array<(string | Function | boolean)[]>;

// Constructor for the Client class.
constructor({
Bot,
Websocket,
LogLevel = 2,
}: {
Bot: Callisto.ClientData;
Websocket: Callisto.WebsocketData;
LogLevel?: 1 | 2 | 3 | 4;
}) {
this.Logger = new Logging(LogLevel);
this.Logger.Debug("Starting client... may take a bit.");

// Set the client data and websocket data.
this.ClientData = Bot;
this.WebsocketData = Websocket;
this.Handlers = [];
this.OnceHandlers = [];
}

/**
* Connect to the websocket server.
* **This function should ONLY be called after you have registered all of your event handlers.**
* Not doing so may result in missed events.
* @returns {boolean} - Whether the connection was successful.
*/

public Connect(): boolean {
this.Logger.Info("Attempting to connect to the server...");

try {
this.Logger.Debug("Connecting to the server...");
this.WS = new Websocket(this.WebsocketData.URI);
this.RegisterHandlers();
this.Logger.Info("Connected to the server.");
} catch (error) {
this.Logger.Error(`An error occurred while connecting to the server: ${error}`);
return false;
}

return true;
}

// Register the package"s event handlers.
private RegisterHandlers(): void {
this.Logger.Debug("Registering event handlers...");
this.WS.on("open", On_Open(this));
this.WS.on("close", On_Close(this));
this.WS.on("message", (data: Callisto.Message) => On_Message(data, this));
}

/**
* Sends a message to the websocket connection.
*
* @param {string} message - The message to send.
* @param {boolean} [raw=false] - Whether to send the message as raw data. Defaults to false.
* @returns {void}
*/

public Send(message: string, raw: boolean = false): void {
if (raw) {
this.Logger.Debug(`Sending RAW message: ${message}`);
this.WS.send(message);
return;
}

this.Logger.Debug(`Sending message: ${message}`);

const data = JSON.stringify({
content: message,
username: this.ClientData.username,
key: this.ClientData.key,
});

this.WS.send(data);
}

/**
* Get stale messages cached by the client.
* @returns {Array<Callisto.Message>} - An array of stale messages
*/

public get StaleMessages(): Callisto.Message[] {
this.Logger.Debug("Retrieving stale messages...");
return this.ClientData.staleMessages;
}

/**
* Listen for an event and run a function when it is emitted.
* @param event The event to listen for.
* @param handler The function to run when the event is emitted.
* @returns {void}
*/
public On(event: string, handler: Function): void {
this.Logger.Debug(`New event handler registered for event ${event}.`);
this.Handlers.push([event, handler]);
}

/**
* Listen for an event and run a function when it is emitted. The function will only run once.
* @param event The event to listen for.
* @param handler The function to run when the event is emitted.
* @returns {void}
*/
public Once(event: string, handler: Function): void {
this.Logger.Debug(`New one-time event handler registered for event ${event}.`);
this.OnceHandlers.push([event, handler, false]);
}

/**
* Remove an event handler.
*
* @param event The event to remove the handler from.
* @param handler The handler to remove.
* @returns {void}
*/

public Off(event: string, handler: Function): void {
this.Logger.Debug(`Removing event handler for event ${event}.`);

this.Handlers = this.Handlers.filter((h) => {
return h[0] !== event || h[1] !== handler;
});

this.OnceHandlers = this.OnceHandlers.filter((h) => {
return h[0] !== event || h[1] !== handler;
});
}

/**
* Emit an event.
* @param event The event to emit.
* @param args The arguments to pass to the event handler.
* @returns {void}
*/

public Emit(event: string, ...args: any[]): void {
this.Logger.Debug(`Emitting event ${event}.`);

this.Handlers.forEach((handler) => {
if (handler[0] === event && typeof handler[1] === "function") {
handler[1](...args);
}
});

this.OnceHandlers.forEach((handler) => {
if (handler[0] === event && typeof handler[1] === "function" && !handler[2]) {
handler[1](...args);
handler[2] = true;
}
});
}

/**
* Discards all event handlers.
* @returns {void}
*/

public ClearHandlers(): void {
this.Logger.Debug("Clearing all event handlers...");
this.Handlers = [];
}

/**
* Disconnect from the websocket server.
* @returns {void}
*/
public Disconnect(): void {
this.Logger.Info("Attempting to disconnect from the server...");
this.ClearHandlers();

if (this.WS.readyState === Websocket.OPEN) {
this.WS.close();
this.DisconnectIntentional = true;
this.Logger.Info("Disconnected from the server.");
} else {
this.Logger.Warning("Could not disconnect from the server. Is the websocket connected?");
}
}
}
36 changes: 36 additions & 0 deletions Source/Utilities/Constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*!
* Callisto, a simple and powerful bot package for nin0-dev's chat server.
* Copyright (c) 2022 Kodarru and contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

// ******

export const NewC_Roles = {
Guest: 1 << 6,
User: 1 << 7,
Bot: 1 << 8,
System: 1 << 10,
Mod: 1 << 11,
Admin: 1 << 12,
};

//! When nin0 rewrites the chat server, the roles will be updated to match the NewC_Roles object.
export const Roles = {
User: 0,
Admin: 2,
Discord: 3,
Bot: 12,
};
130 changes: 130 additions & 0 deletions Source/Utilities/Logging.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*!
* Callisto, a simple and powerful bot package for nin0-dev's chat server.
* Copyright (c) 2022 Kodarru and contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

// ******

/**
* Logging class for logging messages to the console with user-defined log levels.
*
* ```typescript
* const Log = new Logging(1);
* Log.Log("This is a debug message.", "Debug");
* Log.Log("This is an info message.", "Info");
* Log.Log("This is a warning message.", "Warning");
* Log.Log("This is an error message.", "Error");
* ```
*
* All of the above log messages will be logged to the console. The log level is set to 1 (Debug), so all messages will be logged.
* If the log level was set to 2 (Info), only the info, warning, and error messages would be logged.
*
* @class Logging
* @constructor Defines the log level. Defaults to 2 (Info).
* @method Log Logs a message to the console with the specified log level. Will only log messages with a log level equal to or higher than the current log level.
* @method Debug Logs a debug message to the console.
* @method Info Logs an info message to the console.
* @method Warning Logs a warning message to the console.
* @method Error Logs an error message to the console.
* @property LogLevel The log level. Defaults to 2 (Info).
*/

export class Logging {
/**
* The log level.
*
* @type {1 | 2 | 3 | 4}
* @default 2
*/

public LogLevel: 1 | 2 | 3 | 4;

private Colors = {
Reset: "\x1b[0m",
Dim: "\x1b[2m",
FgRed: "\x1b[31m",
FgYellow: "\x1b[33m",
FgBlue: "\x1b[34m",
};

private LogLevels: {
[key in "Debug" | "Info" | "Warning" | "Error"]: {
Level: number;
Color: string;
};
} = {
Debug: {
Level: 1,
Color: this.Colors.Dim,
},
Info: {
Level: 2,
Color: this.Colors.FgBlue,
},
Warning: {
Level: 3,
Color: this.Colors.FgYellow,
},
Error: {
Level: 4,
Color: this.Colors.FgRed,
},
};

/**
* Constructor for the Logging class.
*
* @param {1 | 2 | 3 | 4} [logLevel=2] The log level. Defaults to 2.
* @returns {void}
*/

constructor(logLevel?: 1 | 2 | 3 | 4) {
this.LogLevel = logLevel || 2;
}

/**
* Logs a message to the console with the specified log level.
*
* @param {string} message The message to log.
* @param {"Debug" | "Info" | "Warning" | "Error"} level The log level.
* @returns {void}
*/

public Log(message: string, level: "Debug" | "Info" | "Warning" | "Error") {
if (this.LogLevels[level].Level >= this.LogLevel) {
const logLevel = this.LogLevels[level];
const timestamp = new Date().toISOString();

console.log(`${logLevel.Color}[${level.toUpperCase()}]${this.Colors.Reset} (${timestamp}): ${message}`);
}
}

public Debug(message: string) {
this.Log(message, "Debug");
}

public Info(message: string) {
this.Log(message, "Info");
}

public Warning(message: string) {
this.Log(message, "Warning");
}

public Error(message: string) {
this.Log(message, "Error");
}
}
95 changes: 95 additions & 0 deletions Source/Utilities/Types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*!
* Callisto, a simple and powerful bot package for nin0-dev's chat server.
* Copyright (c) 2022 Kodarru and contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

// ******

/**
*
* The message object that is received from the chat server.
*
* @interface Message
* @property {string} content - The content of the message.
* @property {string} username - The username of the sender.
* @property {number} role - The role of the sender.
* @property {number} op (may not exist) - The op status of the sender.
* @property {Message[]} messages (may not exist) - The list of messages that were sent before the bot was started.
* @property {string} user (may not exist) - The user that sent the message.
* @property {boolean} stale (may not exist) - When a message is declared as stale, it means it is not a new message and was sent before the bot was started.
* @property {function} isMod - Checks if the message was sent by a admin/mod.
* @property {function} isBot - Checks if the message was sent by a bot.
* @property {function} isDiscord - Checks if the message was sent by Discord.
* @property {function} isUser - Checks if the message was sent by a user.
* @property {function} isSelf - Checks if the message was sent by the bot itself.
* @property {function} Send - Sends a message to the chat server.
* @property {function} Reply - Replies to the message.
*/

export interface Message {
content: string;
username: string;
role: number;
op?: number;

//? The list of messages that were sent before the bot was started.
messages?: Message[];

//! Will be deprecated with the new chat server. Only needed for previous messages.
user?: string;

//? When a message is declared as stale, it means it is not a new message and was sent before the bot was started.
stale?: boolean;

//? When a message is received, it will be patched with the following functions.
isMod(): boolean;
isBot(): boolean;
isDiscord(): boolean;
isUser(): boolean;
isSelf(): boolean;
Send(content: string): void;
Reply(content: string): void;
}

/**
* The client data object.
*
* @interface ClientData
* @property {string} username - The username of the bot.
* @property {string} key - The key of the bot.
* @property {Message[]} staleMessages - The list of messages that were sent before the bot was started.
*/

export interface ClientData {
username: string;
key: string;
staleMessages: Message[];
}

/**
* The websocket data object.
*
* @interface WebsocketData
* @property {string} URI - The URI of the websocket server.
* @property {boolean} Reconnect - Whether to reconnect to the server.
* @property {number} ReconnectMaxTrials - The maximum number of trials to reconnect to the server. Set to 0 if you already set reconnect to false.
*/

export interface WebsocketData {
URI: string;
Reconnect: boolean;
ReconnectMaxTrials: number;
}
10 changes: 10 additions & 0 deletions deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "@nin0chat/callisto",
"version": "0.1.1",
"exports": "./Source/Main.ts",
"imports": {
"@std/assert": "jsr:@std/assert@1",
"ws": "npm:ws@^8.18.0",
"@/": "./Source/"
}
}
30 changes: 30 additions & 0 deletions deno.lock

0 comments on commit 10d70ab

Please sign in to comment.