Skip to content

Commit

Permalink
add: base
Browse files Browse the repository at this point in the history
This commit adds the base of CogLink v3.
  • Loading branch information
ThePedroo committed Apr 9, 2024
1 parent c3e9568 commit 01e0ce3
Show file tree
Hide file tree
Showing 43 changed files with 1,895 additions and 4,253 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
*

!guides
!guides/*
!include
!include/*
!lib
!lib/*
!external
!external/*
!.gitignore
!Doxyfile
!LICENSE
Expand Down
13 changes: 10 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
CC = clang
CC = gcc

PREFIX := /usr/local
LIBDIR := $(PREFIX)/lib
INCLUDEDIR := $(PREFIX)/include/coglink
DOCS_DIR = ../CoglinDocs

SRC_DIR = lib
SRC_DIR = lib external
OBJ_DIR = obj

CFLAGS := -Wall -Wextra -Wpedantic
LDFLAGS := -std=gnu99 -Iinclude -Iexternal
LDFLAGS := -std=c99 -D_POSIX_C_SOURCE=200112L -Iinclude -Iexternal
LFLAGS := -lcurl -ldiscord

SRCS = $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))
Expand All @@ -21,6 +21,9 @@ CogLink: $(OBJS)
$(OBJ_DIR)/%.o: lib/%.c | $(OBJ_DIR)
$(CC) -c -fPIC $< -o $@ $(LDFLAGS) $(CFLAGS)

$(OBJ_DIR)/%.o: external/%.c | $(OBJ_DIR)
$(CC) -c -fPIC $< -o $@ $(LDFLAGS) $(CFLAGS)

$(OBJ_DIR):
mkdir -p $@

Expand All @@ -37,6 +40,10 @@ install:
cp include/* $(INCLUDEDIR)
mv libcoglink.a $(LIBDIR)

uninstall:
rm -rf $(INCLUDEDIR)
rm -f $(LIBDIR)/libcoglink.a

gen_docs:
doxygen Doxyfile
rm -f $(DOCS_DIR)/* || true
Expand Down
161 changes: 44 additions & 117 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,154 +1,81 @@
# Coglink
# CogLink

[![Discord Server](https://img.shields.io/discord/1036045973039890522?color=5865F2&logo=discord&logoColor=white)](https://discord.gg/YcaK3puy49) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/acbabb99b4354f5ab182e511dd35aee4)](https://www.codacy.com/gh/ThePedroo/Coglink/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=ThePedroo/Coglink&amp;utm_campaign=Badge_Grade)
A Concord (C99) LavaLink/NodeLink client.

![Coglink logo](guides/images//CoglinkLogo.png "Coglink logo")
## Features

Coglink, the C Lavalink client, with the most performance above all Lavalink wrappers.
- C99 compatible
- Low memory usage (> 7MB of RAM a working bot)
- Portable

## About

Coglink is a C99 Lavalink client, which has full coverage of Lavalink API, allowing easy low-level control of LavaLink.

Made to be portable, Coglink is the least resource-consuming client, allowing you to run easily anywhere. (It can use less than 10MB of RAM)

## Why?

One of the main purposes of Coglink is to be the most performant LavaLink client, while still being light-weight and portable, especially with a low overhead.

In comparison with other NodeJs clients, even against FastLink, Coglink is way more portable, which makes it a good option for big bots, which needs to have the least resource consumption possible.

Coglink is from PerformanC, and our missions is to make our softwares stable enough that it could survive months without issues, and while this is hard for a big project, we are trying to make it possible, which for now, it's working.

Performance, stability and portability, that's what Coglink is about.

## Stability

Stability on this branch cannot be confirmed, LavaLink v4 is still in development with some pending features to be added.

While this branch is more stable than the main, LavaLink is not, so be aware when using this branch.

*If marked, considered stable, if not, bugs may be found.*

- [x] Search (Highly stable)
- [x] loadType/track/playlist/error parsing (loadType/track highly stable)
- [x] Play (Highly stable)
- [x] Join voice channel (Highly stable)
- [x] All cleanups (Highly stable)
- [x] DecodeTrack(s) & ParseTrack(s)
- [x] Parse track, pause track, stop track, seek track, set volume
- [x] Set filter
- [x] Get Players & parse get Players
- [x] Get/parse Info
- [ ] Get/parse RouterPlanner
- [x] Get/parse Lavalink Stats (Event included)
- [x] Get Lavalink Version
- [x] Connect/disconnect Node (Highly stable)
- [x] Set event (Highly stable)
- [x] Websocket (**Known bugs with close event**)
- [x] IO poller (Highly stable)
## Dependencies

## Compiling
- [`Concord`](https://github.com/Cogmasters/Concord) >= 2.2.0

Before starting, you will need to install the required libraries for Coglink, this can be done by the package manager of your OS, you will need to install the mentioned libraries below:
> [!NOTE]
> CogLink only relies on dependencies already included in Concord.
```text
make clang git
```
## Installation

**Warning**: Remember that their names can change depending on your OS.
### 1. Install Concord

After installing the libraries, you will need to [compile Concord](https://github.com/Cogmasters/concord).
The installation guide for Concord can be found [in their repository](https://github.com/Cogmasters/concord?tab=readme-ov-file#build-instructions).

After compiling Concord, you can proceed with the installation of Coglink, first, we will need to clone the repository:
### 2. Clone the repository

```console
$ git clone https://github.com/PerformanC/Coglink
```shell
$ git clone https://github.com/PerformanC/CogLink
```

When the repository is cloned, enter in the folder and run the `make` command, this will generate the header files, which will be used to compile Coglink, and after it, install into the system.
### 3. Compile

```console
# cd Coglink && make && make install
```shell
$ cd CogLink
$ make -j4
```

**Warning**: When compiling your bot, remember to use the `-lcoglink` flag.

## Using
> [!NOTE]
> The `-j4` flag is optional, but it will speed up the compilation process. The number after `-j` is the number of threads to use for compilation.
See below the purpose of Coglink header files:
### 4. Install

```c
#include <coglink/lavalink.h> // Websocket related Coglink functions
#include <coglink/definitions.h> // File with the definitions of macros, like COGLINK_SUCCESS
#include <coglink/information.h> // Functions which get information from Lavalink
#include <coglink/network.h> // Functions related to network, like the router planner
#include <coglink/player.h> // The functions related to the music player
#include <coglink/plugins.h> // For the use of plugins
#include <coglink/track.h> // Functions related to tracks, like decoding, searching, etc
```shell
$ sudo make install
```

As for the usage, you can see the `guides/example` folder, with a complete example of Coglink usage.
## Usage

## Documentation

You can see [here](https://performanc.github.io/CoglinDocs/) the documentation for Coglink, made with Doxygen.

In case you want to build the documentation yourself, you can use the `make gen_docs` command, but be sure that you have Doxygen installed.

## Coglink plugins

For most functions, Coglink allows plugins to interfere with it, allowing the community to add more features to Coglink, without the need to modify the source code, but for the protection of the users, Coglink has some security measures to avoid malicious plugins.

The security measures are:

- Plugins are not allowed to change the members of the struct `lavaInfo`/`client`
- Concord's client struct has hidden members (OPTIONAL)
- Plugins are not allowed to read neither the bot token nor the Concord websocket struct by default.
... TODO

### Setting up a plugin

Plugins can't straight ahead work in Coglink, you need to pass the functions to Coglink from the plugin, so it can execute when some function from Coglink is used, see the function below that allow this to happen:
## Documentation

```c
#include <coglink/plugins.h>
#include "somePlugin.h"
[CogLink documentation](https://performanc.github.io/CoglinDocs/) is made with Doxygen, hosted on GitHub Pages.

struct coglink_pluginEvents event = {
.onSearchRequest = &functionToBeExecuted
}
The documentation can be built with the following command:

coglink_setPluginEvents(&lavaInfo, &event);
```shell
$ make gen_docs
```

Done, now when the function coglink_searchSong is executed, this will be executed first before Coglink processes it.
**Warning**: The first plugins have the priority, so if you want to make a plugin that will be executed first, you will need to set it first.
## Plugin list
For now, there are no plugins for Coglink, but if you want to make one, you can see the [Setting up a plugin](#setting-up-a-plugin) section, and after it, you can add it to the list below.
> [!NOTE]
> Doxygen is required to build the documentation.
## Support

In case of any issue using it (except bugs, that should be reported on GitHub Issues), you are free to ask on PerformanC's [Discord server](https://discord.gg/uPveNfTuCJ).
Any question or issue related to CogLink or other PerformanC projects can be can be made in [PerformanC's Discord server](https://discord.gg/uPveNfTuCJ).

## Credits
For verified issues, please also create a GitHub issue for tracking the issue.

Although Coglink is made only by one person, many people contributed to it, thanks [Cogmaster](https://discord.gg/YcaK3puy49) members for this. And special thanks to `müller#1001`, without you, we wouldn't be here.
## Contributing

Some people that helped on Coglink related things:
CogLink follows the PerformanC's [contribution guidelines](https://github.com/PerformanC/contributing). It is necessary to follow the guidelines to contribute to CogLink and other PerformanC projects.

- müller
- HackerSmacker
- Goo
## Projects using CogLink

Thanks you all for the help! ^^
None known yet, but if you are using CogLink, please let us know in [PerformanC's Discord server](https://discord.gg/uPveNfTuCJ) and we will add your project here.

## Dependencies
## License

CogLink is licensed under PerformanC's License, which is a modified version of the MIT License, focusing on the protection of the source code and the rights of the PerformanC team over the source code.

- `libcurl` >= 7.56.1
- `Concord (master/dev)` 2.2.0
- `jsmn-find` latest (included on Concord 2.2.0)
- `jsmn` latest (included on Concord 2.2.0)
- `tablec` v2.2.3 (Open-addressing)
* This project uses the latest standards of The PerformanC Organization.
97 changes: 97 additions & 0 deletions external/tablec.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "tablec.h"

void tablec_init(struct tablec_ht *tablec, size_t max_capacity) {
tablec->length = 0;
tablec->capacity = max_capacity;
tablec->buckets = calloc(sizeof(struct tablec_bucket) * max_capacity, 1);
}

static size_t __tablec_hash(struct tablec_ht *tablec, char *key) {
size_t hash = 0, i = 0;

while (key[i] != '\0') hash = hash * 37 + (key[i++] & 255);

return hash % tablec->capacity;
}

void tablec_resize(struct tablec_ht *tablec, size_t new_max_capacity) {
struct tablec_ht newHashtable;
tablec_init(&newHashtable, new_max_capacity);

while (tablec->capacity--) {
if (!tablec->buckets[tablec->capacity].key) continue;

tablec_set(&newHashtable, tablec->buckets[tablec->capacity].key, tablec->buckets[tablec->capacity].value);
}

tablec_cleanup(tablec);
*tablec = newHashtable;
}

void tablec_set(struct tablec_ht *tablec, char *key, void *value) {
size_t hash;

if (tablec->length - 1 == tablec->capacity) tablec_resize(tablec, tablec->capacity * 2);

hash = __tablec_hash(tablec, key);

while (hash != tablec->capacity) {
if (!tablec->buckets[hash].key) {
tablec->buckets[hash].key = key;
tablec->buckets[hash].value = value;

tablec->length++;

return;
}

hash++;
}

tablec_resize(tablec, tablec->capacity * 2);
tablec_set(tablec, key, value);

return;
}

void tablec_del(struct tablec_ht *tablec, char *key) {
size_t hash = __tablec_hash(tablec, key);

while (hash != tablec->capacity) {
if (tablec->buckets[hash].key && strcmp(tablec->buckets[hash].key, key) == 0) {
tablec->buckets[hash].key = NULL;
tablec->buckets[hash].value = NULL;

tablec->length--;

return;
}

hash++;
}
}

struct tablec_bucket *tablec_get(struct tablec_ht *tablec, char *key) {
size_t hash = __tablec_hash(tablec, key);

while (hash != tablec->capacity) {
if (tablec->buckets[hash].key && strcmp(tablec->buckets[hash].key, key) == 0)
return &tablec->buckets[hash];

hash++;
}

return NULL;
}

int tablec_full(struct tablec_ht *tablec) {
return (int)(tablec->capacity == tablec->length) ? -1 : (int)(tablec->capacity - tablec->length);
}

void tablec_cleanup(struct tablec_ht *tablec) {
free(tablec->buckets);
}
29 changes: 29 additions & 0 deletions external/tablec.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef TABLEC_H
#define TABLEC_H

struct tablec_bucket {
char *key;
void *value;
};

struct tablec_ht {
size_t length;
size_t capacity;
struct tablec_bucket *buckets;
};

void tablec_init(struct tablec_ht *tablec, size_t max_capacity);

void tablec_resize(struct tablec_ht *tablec, size_t new_max_capacity);

void tablec_set(struct tablec_ht *tablec, char *key, void *value);

void tablec_del(struct tablec_ht *tablec, char *key);

struct tablec_bucket *tablec_get(struct tablec_ht *tablec, char *key);

int tablec_full(struct tablec_ht *tablec);

void tablec_cleanup(struct tablec_ht *tablec);

#endif
Loading

0 comments on commit 01e0ce3

Please sign in to comment.