Skip to content

Commit

Permalink
Cristalix boards 3.0 - Now even simpler
Browse files Browse the repository at this point in the history
  • Loading branch information
delfikpro committed Mar 12, 2021
0 parents commit 729763c
Show file tree
Hide file tree
Showing 20 changed files with 1,047 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Project exclude paths
/.gradle/
.idea
build
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Cristalix boards

## Установка

Проект cristalix-boards необходимо включать в один из своих плагинов.

```groovy
repositories {
maven {
url 'https://repo.implario.dev/public'
}
}
dependencies {
implementation 'ru.cristalix:boards-bukkit-api:3.0.0'
}
```

## Использование

Управление топами осуществляется через интерфейс `Board`

Сперва нужно создать, настроить и добавить таблицу в мир.

```java
// Создание топа
Board board = Boards.newBoard();

// Настройка имён колонок и их ширины
board.addColumn("#", 10);
board.addColumn("Игрок", 80);
board.addColumn("Побед", 30);
board.addColumn("Игр", 30);

// Заголовок топа
board.setTitle("Топ по победам");

// Местоположение (включая поворот)
board.setLocation(location);

// Добавление в мир после того, как всё настроено
Boards.addBoard(board);
```

Заметка: Если вы не создаёте топы до входа первых игроков, рекомендуется
вызвать метод `Boards.init()`

После того, как таблица создана, её можно наполнять контентом:

```java

// Перед добавлением нового контента, стоит очистить доску от существующего
board.clearContent();

board.addContent(UUID.randomUUID(), "§e1", "DelfikPro", "1000", "1500");
board.addContent(UUID.randomUUID(), "§e2", "kaso", "1000", "1500");
board.addContent(UUID.randomUUID(), "§e3", "CaptainLach", "1000", "1500");
board.addContent(UUID.randomUUID(), "§e4", "ilyafx", "1000", "1500");
board.addContent(UUID.randomUUID(), "§e5", "xxDark", "1000", "1500");
board.addContent(UUID.randomUUID(), "§e6", "HelloWorld", "1000", "1500");
board.addContent(UUID.randomUUID(), "§e7", "AppleJuice", "1000", "1500");

// Отправить обновление всем игрокам
board.updateContent();
```

Параметр UUID будет использоваться, чтобы перемещать ячейки с анимацией, а также для рендера скинов.
В данный момент он не используется.
49 changes: 49 additions & 0 deletions boards-bukkit-api/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
apply plugin: 'maven-publish'

repositories {

maven {
url 'https://repo.implario.dev/cristalix'
credentials {
username System.getenv('IMPLARIO_REPO_USER')
password System.getenv('IMPLARIO_REPO_PASSWORD')
}
}
}

dependencies {
compileOnly 'cristalix:bukkit-core:21.01.30'
compileOnly 'cristalix:dark-paper:21.02.03'
implementation project(':boards-data')
}

evaluationDependsOn(':boards-client-mod')

jar {
dependsOn project(':boards-client-mod').tasks.bundle
from (file(project(':boards-client-mod').buildDir.absolutePath + '/libs')) {
include '**-bundle.jar'
}
from configurations.runtimeClasspath.collect { it.directory ? it : zipTree(it) }
}

publishing {
repositories {
maven {
name 'implario'
url 'https://repo.implario.dev/public'
credentials {
username System.getenv('IMPLARIO_REPO_USER')
password System.getenv('IMPLARIO_REPO_PASSWORD')
}
}
}
publications {
create('bukkitApi', MavenPublication) {
it.groupId 'ru.cristalix'
it.artifactId 'boards-bukkit-api'
it.version '3.0.0'
it.artifact jar
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ru.cristalix.boards.bukkitapi;

import org.bukkit.Location;
import org.bukkit.entity.Player;

import java.util.Collection;
import java.util.UUID;

public interface Board {

UUID getUuid();

void setTitle(String title);

String getTitle();

void addColumn(String header, double width);

void setLocation(Location location);

Location getLocation();

void clearContent();

void addContent(UUID contentId, String... cellValues);

void updateContent();

void updateContent(Player player);

void updateStructure();

void updateStructure(Player player);

Collection<Player> getWatchers();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package ru.cristalix.boards.bukkitapi;

import com.destroystokyo.paper.event.entity.EntityAddToWorldEvent;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_12_R1.PacketDataSerializer;
import net.minecraft.server.v1_12_R1.PacketPlayOutCustomPayload;
import org.apache.commons.io.IOUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import ru.cristalix.core.display.DisplayChannels;
import ru.cristalix.core.display.messages.Mod;

import java.io.InputStream;
import java.util.*;

public class Boards implements Listener {

public static final List<Board> boards = new ArrayList<>();
public static final Set<CraftPlayer> active = new HashSet<>();
private static Plugin plugin;

public static Board newBoard() {
init();
return new SimpleBoard();
}

public static void init() {
if (plugin != null) return;
plugin = JavaPlugin.getProvidingPlugin(Boards.class);
Bukkit.getPluginManager().registerEvents(new Boards(), plugin);
Bukkit.getMessenger().registerIncomingPluginChannel(plugin, "boards:loaded", (channel, player, data) -> {
active.add((CraftPlayer) player);
for (Board board : boards) {
if (board.getLocation().getWorld() == player.getWorld()) {
board.updateStructure(player);
board.updateContent(player);
}
}
});
}

@EventHandler
public void onJoin(PlayerJoinEvent e) throws Exception {
InputStream resource = plugin.getResource("boards-client-mod-bundle.jar");
byte[] serialize = Mod.serialize(new Mod(IOUtils.readFully(resource, resource.available())));
ByteBuf buf = Unpooled.buffer();
buf.writeBytes(serialize);
PacketDataSerializer ds = new PacketDataSerializer(buf);
PacketPlayOutCustomPayload packet = new PacketPlayOutCustomPayload(DisplayChannels.MOD_CHANNEL, ds);
((CraftPlayer) e.getPlayer()).getHandle().playerConnection.sendPacket(packet);
}

@EventHandler
public void onAddToWorld(EntityAddToWorldEvent event) {
System.out.println(event.entity);
if (!(event.getEntity() instanceof CraftPlayer)) return;
CraftPlayer player = (CraftPlayer) event.getEntity();
if (!active.contains(player)) return;
for (Board board : boards) {
board.updateStructure(player);
board.updateContent(player);
}
}

public static void addBoard(Board board) {
boards.add(board);
board.updateStructure();
board.updateContent();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package ru.cristalix.boards.bukkitapi;

import dev.xdark.feder.NetUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Getter;
import lombok.ToString;
import lombok.val;
import net.minecraft.server.v1_12_R1.PacketDataSerializer;
import net.minecraft.server.v1_12_R1.PacketPlayOutCustomPayload;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import ru.cristalix.boards.data.BoardColumn;
import ru.cristalix.boards.data.BoardContent;
import ru.cristalix.boards.data.BoardStructure;
import ru.cristalix.core.GlobalSerializers;

import java.util.*;
import java.util.stream.Collectors;

@Getter
@ToString
public class SimpleBoard implements Board {

private final UUID uuid;
private final BoardStructure info;
private Location location;
private BoardContent content;

protected SimpleBoard() {
this(UUID.randomUUID());
}

protected SimpleBoard(UUID uuid) {
this.uuid = uuid;
this.info = new BoardStructure(uuid);
this.content = new BoardContent(uuid, new ArrayList<>());
}

@Override
public Collection<Player> getWatchers() {
if (this.location == null) return Collections.emptyList();
return Boards.active.stream().filter(b -> b.getWorld() == location.getWorld()).collect(Collectors.toList());
}

public void setTitle(String title) {
this.info.setName(title);
this.updateStructure();
}

public String getTitle() {
return this.info.getName();
}

public void addColumn(String header, double width) {
this.info.getColumns().add(new BoardColumn(header, width));
this.updateStructure();
}

@Override
public void clearContent() {
this.content.clear();
}

@Override
public void addContent(UUID contentId, String... cellValues) {
this.content.addLine(contentId, cellValues);
}

public void setLocation(Location location) {
this.info.setX(location.getX());
this.info.setY(location.getY());
this.info.setZ(location.getZ());
this.info.setYaw(location.getYaw());
// this.info.setPitch(location.getPitch());
this.location = location;
this.updateStructure();
}

@Override
public void updateStructure() {
send("boards:new", encode(info), getWatchers());
}

@Override
public void updateStructure(Player player) {
send("boards:new", encode(info), Collections.singleton(player));
}

public void updateContent() {
send("boards:content", encode(content), getWatchers());
}

@Override

This comment has been minimized.

Copy link
@GooDYT777

GooDYT777 Jan 27, 2023

Class

public void updateContent(Player player) {
send("boards:content", encode(content), Collections.singleton(player));
}

public static void send(String channel, ByteBuf buffer, Iterable<Player> players) {
for (Player player : players) {
val packet = new PacketPlayOutCustomPayload(channel, new PacketDataSerializer(buffer.retainedSlice()));
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
}
}

public static ByteBuf encode(Object object) {
val buffer = Unpooled.buffer();
val bytes = GlobalSerializers.toJson(object);
NetUtil.writeUtf8(bytes, buffer);
return buffer;
}

}
4 changes: 4 additions & 0 deletions boards-bukkit-api/src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
main: ru.cristalix.boards.bukkitapi.Boards
version: 1
name: boards
depend: [CoreAPI, HeartwarmingPlace]
Loading

0 comments on commit 729763c

Please sign in to comment.