Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Figura Server side (or FSB) #239

Draft
wants to merge 7 commits into
base: 1.20
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ architectury {
minecraft = rootProject.minecraft_version
}

subprojects {
rootProject.mod_projects.split(",").each { project(":$it") {
apply plugin: "dev.architectury.loom"
apply plugin: "io.github.juuxel.loom-vineflower"

Expand Down Expand Up @@ -39,7 +39,7 @@ subprojects {
modCompileOnly "maven.modrinth:immediatelyfast:$immediately_fast"
modCompileOnly "maven.modrinth:iris:$iris"
}
}
}}

allprojects {
apply plugin: "java"
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ java_version = 17
minecraft_version = 1.20.1
mappings = 1
enabled_platforms = fabric,forge
mod_projects = common,common:mojmap,fabric,forge

# Mod Properties
mod_version = 0.1.4
Expand Down
7 changes: 7 additions & 0 deletions server-common/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
repositories {

}

dependencies {
implementation 'com.google.code.gson:gson:2.11.0'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.figuramc.figura.server;

import org.figuramc.figura.server.events.Events;
import org.figuramc.figura.server.events.packets.DeferredPacketErrorEvent;
import org.figuramc.figura.server.packets.Packet;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

public class DeferredPacketsQueue {
private final FiguraServer parent;
private final HashMap<UUID, LinkedList<CompletableFuture<Packet>>> queues = new HashMap<>();

public DeferredPacketsQueue(FiguraServer parent) {
this.parent = parent;
}

public void sendPacket(UUID receiver, CompletableFuture<Packet> futurePacket) {
queues.computeIfAbsent(receiver, u -> new LinkedList<>()).add(futurePacket);
}

void tick() {

}

private boolean completedAndSent(UUID receiver, CompletableFuture<Packet> packet) {
if (packet.isDone()) {
try {
Packet p = packet.join();
parent.sendPacket(receiver, p);
} catch (Exception e) {
Events.call(new DeferredPacketErrorEvent(e));
}
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package org.figuramc.figura.server;

import org.figuramc.figura.server.avatars.FiguraServerAvatarManager;
import org.figuramc.figura.server.events.Events;
import org.figuramc.figura.server.events.HandshakeEvent;
import org.figuramc.figura.server.events.packets.OutcomingPacketEvent;
import org.figuramc.figura.server.packets.Packet;
import org.figuramc.figura.server.packets.handlers.c2s.C2SPacketHandler;
import org.figuramc.figura.server.packets.s2c.S2CBackendHandshakePacket;
import org.figuramc.figura.server.utils.Identifier;
import org.figuramc.figura.server.utils.Utils;

import java.nio.file.Path;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

public abstract class FiguraServer {
private static FiguraServer INSTANCE;
private final FiguraUserManager userManager = new FiguraUserManager(this);
private final FiguraServerAvatarManager avatarManager = new FiguraServerAvatarManager(this);
private FiguraServerConfig config;
private final DeferredPacketsQueue deferredPacketsQueue = new DeferredPacketsQueue(this);
protected FiguraServer() {
if (INSTANCE != null) throw new IllegalStateException("Can't create more than one instance of FiguraServer");
INSTANCE = this;
}

public static FiguraServer getInstance() {
return INSTANCE;
}

public abstract Path getFiguraFolder();

public abstract void registerHandler(Identifier packetId, C2SPacketHandler<?> handler);
public abstract void unregisterHandler(Identifier packetId);

public Path getUsersFolder() {
return getFiguraFolder().resolve("users");
}

public Path getAvatarsFolder() {
return getFiguraFolder().resolve("avatars");
}

public Path getAvatar(byte[] hash) {
return getAvatarsFolder().resolve("%s.nbt".formatted(Utils.hexFromBytes(hash)));
}

public Path getAvatarMetadata(byte[] hash) {
return getAvatarsFolder().resolve("%s.mtd".formatted(Utils.hexFromBytes(hash)));
}

public Path getUserdataFile(UUID user) {
return getUsersFolder().resolve("%s.pl".formatted(Utils.uuidToHex(user)));
}

public final void init() {

}

public final void close() {
INSTANCE = null;
}

protected final void tick() {
deferredPacketsQueue.tick();
avatarManager.tick();
}

public final void sendHandshake(UUID receiver) {
var event = Events.call(new HandshakeEvent(receiver));
if (!event.isCancelled()) {
userManager.expect(receiver);
sendPacket(receiver, new S2CBackendHandshakePacket(
config.pings(),
config.pingsRateLimit(),
config.pingsSizeLimit(),
config.avatars(),
config.avatarSizeLimit(),
config.avatarsCountLimit()
));
}
}

public FiguraServerConfig config() {
return config;
}

public FiguraUserManager userManager() {
return userManager;
}

public final void sendPacket(UUID receiver, Packet packet) {
OutcomingPacketEvent event = new OutcomingPacketEvent(receiver, packet);
Events.call(event);
if (!event.isCancelled()) {
sendPacketInternal(receiver, packet);
}
}

public final void sendDeferredPacket(UUID receiver, CompletableFuture<Packet> packet) {
deferredPacketsQueue.sendPacket(receiver, packet);
}

protected abstract void sendPacketInternal(UUID receiver, Packet packet);

public FiguraServerAvatarManager avatarManager() {
return avatarManager;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.figuramc.figura.server;

public final class FiguraServerConfig {
private boolean pings = true;
private boolean avatars = true;

private int pingsRateLimit = 20;
private int pingsSizeLimit = 10240;

private int avatarSizeLimit = 102400;
private int avatarsCountLimit = 1;

private int garbageCollectionTicks = 1200;
private int maxOutcomingChunkSize = 50000;

public boolean pings() {
return pings;
}

public boolean avatars() {
return avatars;
}

public int pingsRateLimit() {
return pingsRateLimit;
}

public int pingsSizeLimit() {
return pingsSizeLimit;
}

public int avatarSizeLimit() {
return avatarSizeLimit;
}

public int avatarsCountLimit() {
return avatarsCountLimit;
}

public int garbageCollectionTicks() {
return garbageCollectionTicks;
}

public int s2cChunkSize() {
return maxOutcomingChunkSize;
}
}
Loading
Loading